Bug 664123 - Backout bugs 659053 and 659539 (changesets 9c49f69d8bab-1b11c64ffcdf)
authorMs2ger <ms2ger@gmail.com>
Tue, 14 Jun 2011 16:25:51 +0200
changeset 71564 8ca16e3ff5e0f3290a87ef26d98ef198d5b71b8b
parent 71555 1b11c64ffcdf0c072943a5a686aab73deb395ad0
child 71565 e00f1b19444002f10832cac1439204e259b95895
push id159
push usereakhgari@mozilla.com
push dateTue, 16 Aug 2011 17:53:11 +0000
treeherdermozilla-beta@8786e3e49240 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs664123, 659053, 659539
milestone7.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 664123 - Backout bugs 659053 and 659539 (changesets 9c49f69d8bab-1b11c64ffcdf)
accessible/src/base/nsCoreUtils.cpp
content/base/public/nsContentUtils.h
content/base/public/nsIContent.h
content/base/public/nsINode.h
content/base/public/nsINodeInfo.h
content/base/src/nsCommentNode.cpp
content/base/src/nsContentList.cpp
content/base/src/nsContentUtils.cpp
content/base/src/nsDOMAttribute.cpp
content/base/src/nsDOMAttribute.h
content/base/src/nsDOMAttributeMap.cpp
content/base/src/nsDOMDocumentType.cpp
content/base/src/nsDOMDocumentType.h
content/base/src/nsDocument.cpp
content/base/src/nsDocument.h
content/base/src/nsDocumentEncoder.cpp
content/base/src/nsDocumentFragment.cpp
content/base/src/nsGenericDOMDataNode.cpp
content/base/src/nsGenericDOMDataNode.h
content/base/src/nsGenericElement.cpp
content/base/src/nsGenericElement.h
content/base/src/nsGkAtomList.h
content/base/src/nsNodeInfo.cpp
content/base/src/nsNodeInfo.h
content/base/src/nsNodeInfoManager.cpp
content/base/src/nsNodeInfoManager.h
content/base/src/nsNodeUtils.cpp
content/base/src/nsTextNode.cpp
content/base/src/nsTextNode.h
content/base/src/nsTraversal.cpp
content/base/test/test_bug352728.html
content/base/test/test_bug352728.xhtml
content/html/content/src/nsHTMLAudioElement.cpp
content/html/content/src/nsHTMLImageElement.cpp
content/html/content/src/nsHTMLOptionElement.cpp
content/html/content/src/nsTextEditorState.cpp
content/html/content/test/test_bug389797.html
content/html/document/src/ImageDocument.cpp
content/html/document/src/MediaDocument.cpp
content/html/document/src/PluginDocument.cpp
content/html/document/src/VideoDocument.cpp
content/html/document/src/nsHTMLContentSink.cpp
content/html/document/src/nsHTMLFragmentContentSink.cpp
content/svg/content/src/nsSVGElement.cpp
content/svg/content/src/nsSVGUseElement.cpp
content/test/unit/head_content.js
content/test/unit/test_isequalnode.js
content/test/unit/test_range.js
content/xbl/src/nsXBLContentSink.cpp
content/xbl/src/nsXBLService.cpp
content/xml/content/src/nsXMLCDATASection.cpp
content/xml/content/src/nsXMLProcessingInstruction.cpp
content/xml/content/src/nsXMLProcessingInstruction.h
content/xml/content/src/nsXMLStylesheetPI.cpp
content/xml/document/src/nsXMLContentSink.cpp
content/xml/document/src/nsXMLFragmentContentSink.cpp
content/xslt/src/xpath/nsXPathExpression.cpp
content/xslt/src/xpath/nsXPathNSResolver.cpp
content/xslt/src/xpath/nsXPathNSResolver.h
content/xslt/src/xpath/txMozillaXPathTreeWalker.cpp
content/xslt/src/xslt/txMozillaTextOutput.cpp
content/xslt/src/xslt/txMozillaXMLOutput.cpp
content/xtf/src/nsXTFElementWrapper.cpp
content/xul/content/src/nsXULElement.cpp
content/xul/document/src/nsXULContentSink.cpp
content/xul/document/src/nsXULDocument.cpp
content/xul/document/src/nsXULPrototypeDocument.cpp
content/xul/templates/src/nsXULContentBuilder.cpp
dom/base/nsDOMClassInfo.cpp
dom/base/nsFocusManager.cpp
dom/interfaces/base/Makefile.in
dom/interfaces/base/nsIDOMNSFeatureFactory.idl
dom/interfaces/core/Makefile.in
dom/interfaces/core/nsIDOM3Node.idl
dom/interfaces/core/nsIDOMNode.idl
editor/libeditor/html/nsHTMLEditRules.cpp
editor/txtsvc/src/nsTextServicesDocument.cpp
embedding/browser/activex/src/common/IEHtmlElement.cpp
embedding/browser/webBrowser/nsDocShellTreeOwner.cpp
embedding/components/webbrowserpersist/src/nsWebBrowserPersist.cpp
js/src/tests/js1_5/extensions/regress-375344.js
js/src/xpconnect/src/dom_quickstubs.qsconf
layout/base/nsCSSFrameConstructor.cpp
layout/base/nsPresShell.cpp
layout/build/nsContentDLF.cpp
layout/forms/nsComboboxControlFrame.cpp
layout/forms/nsFileControlFrame.cpp
layout/forms/nsIsIndexFrame.cpp
layout/forms/nsProgressFrame.cpp
layout/generic/nsGfxScrollFrame.cpp
layout/generic/nsVideoFrame.cpp
layout/inspector/src/inCSSValueSearch.cpp
layout/style/Loader.cpp
layout/xul/base/src/nsDocElementBoxFrame.cpp
netwerk/test/httpserver/test/test_default_index_handler.js
parser/html/nsHtml5TreeOperation.cpp
widget/src/xpwidgets/GfxInfoBase.cpp
--- a/accessible/src/base/nsCoreUtils.cpp
+++ b/accessible/src/base/nsCoreUtils.cpp
@@ -38,16 +38,17 @@
 
 #include "nsCoreUtils.h"
 
 #include "nsIAccessibleTypes.h"
 
 #include "nsAccessNode.h"
 
 #include "nsIDocument.h"
+#include "nsIDOM3Node.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOMHTMLDocument.h"
 #include "nsIDOMHTMLElement.h"
 #include "nsIDOMNodeList.h"
 #include "nsIDOMRange.h"
 #include "nsIDOMWindowInternal.h"
 #include "nsIDOMXULElement.h"
 #include "nsIDocShell.h"
--- a/content/base/public/nsContentUtils.h
+++ b/content/base/public/nsContentUtils.h
@@ -64,16 +64,17 @@ static fp_except_t oldmask = fpsetmask(~
 
 #include "nsAString.h"
 #include "nsIStatefulFrame.h"
 #include "nsINodeInfo.h"
 #include "nsNodeInfoManager.h"
 #include "nsContentList.h"
 #include "nsDOMClassInfoID.h"
 #include "nsIXPCScriptable.h"
+#include "nsIDOM3Node.h"
 #include "nsDataHashtable.h"
 #include "nsIScriptRuntime.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsIDOMEvent.h"
 #include "nsTArray.h"
 #include "nsTextFragment.h"
 #include "nsReadableUtils.h"
 #include "mozilla/AutoRestore.h"
@@ -297,20 +298,20 @@ public:
 
   /**
    * Returns true if aNode1 is before aNode2 in the same connected
    * tree.
    */
   static PRBool PositionIsBefore(nsINode* aNode1,
                                  nsINode* aNode2)
   {
-    return (aNode2->CompareDocPosition(aNode1) &
-      (nsIDOMNode::DOCUMENT_POSITION_PRECEDING |
-       nsIDOMNode::DOCUMENT_POSITION_DISCONNECTED)) ==
-      nsIDOMNode::DOCUMENT_POSITION_PRECEDING;
+    return (aNode2->CompareDocumentPosition(aNode1) &
+      (nsIDOM3Node::DOCUMENT_POSITION_PRECEDING |
+       nsIDOM3Node::DOCUMENT_POSITION_DISCONNECTED)) ==
+      nsIDOM3Node::DOCUMENT_POSITION_PRECEDING;
   }
 
   /**
    *  Utility routine to compare two "points", where a point is a
    *  node/offset pair
    *  Returns -1 if point1 < point2, 1, if point1 > point2,
    *  0 if error or if point1 == point2.
    *  NOTE! If the two nodes aren't in the same connected subtree,
@@ -336,16 +337,17 @@ public:
   /**
    * Reverses the document position flags passed in.
    *
    * @param   aDocumentPosition   The document position flags to be reversed.
    *
    * @return  The reversed document position flags.
    *
    * @see nsIDOMNode
+   * @see nsIDOM3Node
    */
   static PRUint16 ReverseDocumentPosition(PRUint16 aDocumentPosition);
 
   static PRUint32 CopyNewlineNormalizedUnicodeTo(const nsAString& aSource,
                                                  PRUint32 aSrcOffset,
                                                  PRUnichar* aDest,
                                                  PRUint32 aLength,
                                                  PRBool& aLastCharCR);
@@ -541,17 +543,16 @@ public:
 
   static nsresult SplitQName(const nsIContent* aNamespaceResolver,
                              const nsAFlatString& aQName,
                              PRInt32 *aNamespace, nsIAtom **aLocalName);
 
   static nsresult GetNodeInfoFromQName(const nsAString& aNamespaceURI,
                                        const nsAString& aQualifiedName,
                                        nsNodeInfoManager* aNodeInfoManager,
-                                       PRUint16 aNodeType,
                                        nsINodeInfo** aNodeInfo);
 
   static void SplitExpatName(const PRUnichar *aExpatName, nsIAtom **aPrefix,
                              nsIAtom **aTagName, PRInt32 *aNameSpaceID);
 
   // Get a permission-manager setting for the given uri and type.
   // If the pref doesn't exist or if it isn't ALLOW_ACTION, PR_FALSE is
   // returned, otherwise PR_TRUE is returned.
@@ -685,19 +686,17 @@ public:
    * from aNodeInfo.
    */
   static nsresult NameChanged(nsINodeInfo *aNodeInfo, nsIAtom *aName,
                               nsINodeInfo** aResult)
   {
     nsNodeInfoManager *niMgr = aNodeInfo->NodeInfoManager();
 
     *aResult = niMgr->GetNodeInfo(aName, aNodeInfo->GetPrefixAtom(),
-                                  aNodeInfo->NamespaceID(),
-                                  aNodeInfo->NodeType(),
-                                  aNodeInfo->GetExtraName()).get();
+                                  aNodeInfo->NamespaceID()).get();
     return *aResult ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
   }
 
   /**
    * Returns the appropriate event argument names for the specified
    * namespace and event name.  Added because we need to switch between
    * SVG's "evt" and the rest of the world's "event", and because onerror
    * takes 3 args.
--- a/content/base/public/nsIContent.h
+++ b/content/base/public/nsIContent.h
@@ -923,16 +923,22 @@ public:
    */
   virtual nsresult SetSMILOverrideStyleRule(mozilla::css::StyleRule* aStyleRule,
                                             PRBool aNotify) = 0;
 #endif // MOZ_SMIL
 
   nsresult LookupNamespaceURI(const nsAString& aNamespacePrefix,
                               nsAString& aNamespaceURI) const;
 
+  nsIAtom* LookupPrefix(const nsAString& aNamespaceURI);
+
+  PRBool IsEqual(nsIContent *aOther);
+
+  virtual PRBool IsEqualNode(nsINode* aOther);
+
   /**
    * If this content has independent selection, e.g., if this is input field
    * or textarea, this return TRUE.  Otherwise, false.
    */
   PRBool HasIndependentSelection();
 
   /**
    * If the content is a part of HTML editor, this returns editing
--- a/content/base/public/nsINode.h
+++ b/content/base/public/nsINode.h
@@ -431,32 +431,17 @@ public:
    *
    * @return the current document
    */
   nsIDocument *GetCurrentDoc() const
   {
     return IsInDoc() ? GetOwnerDoc() : nsnull;
   }
 
-  /**
-   * The values returned by this function are the ones defined for
-   * nsIDOMNode.nodeType
-   */
-  PRUint16 NodeType() const
-  {
-    return mNodeInfo->NodeType();
-  }
-  const nsString& NodeName() const
-  {
-    return mNodeInfo->NodeName();
-  }
-  const nsString& LocalName() const
-  {
-    return mNodeInfo->LocalName();
-  }
+  NS_IMETHOD GetNodeType(PRUint16* aNodeType) = 0;
 
   nsINode*
   InsertBefore(nsINode *aNewChild, nsINode *aRefChild, nsresult *aReturn)
   {
     return ReplaceOrInsertBefore(PR_FALSE, aNewChild, aRefChild, aReturn);
   }
   nsINode*
   ReplaceChild(nsINode *aNewChild, nsINode *aOldChild, nsresult *aReturn)
@@ -979,26 +964,23 @@ public:
    * 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;
 
-  nsresult GetDOMBaseURI(nsAString &aURI) const;
+  void GetBaseURI(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)
+  virtual void GetTextContent(nsAString &aTextContent)
   {
     SetDOMStringToNull(aTextContent);
-    return NS_OK;
   }
-  NS_IMETHOD SetTextContent(const nsAString& aTextContent)
+  virtual nsresult SetTextContent(const nsAString& aTextContent)
   {
     return NS_OK;
   }
 
   /**
    * Associate an object aData to aKey on this node. If aData is null any
    * previously registered object and UserDataHandler associated to aKey on
    * this node will be removed.
@@ -1028,61 +1010,58 @@ public:
     nsCOMPtr<nsIAtom> key = do_GetAtom(aKey);
     if (!key) {
       return nsnull;
     }
 
     return static_cast<nsIVariant*>(GetProperty(DOM_USER_DATA, key));
   }
 
-  nsresult GetUserData(const nsAString& aKey, nsIVariant** aResult)
-  {
-    NS_IF_ADDREF(*aResult = GetUserData(aKey));
-  
-    return NS_OK;
-  }
-
+  nsresult GetFeature(const nsAString& aFeature,
+                      const nsAString& aVersion,
+                      nsISupports** aReturn);
 
   /**
    * 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
+   * @see nsIDOM3Node
    */
-  PRUint16 CompareDocPosition(nsINode* aOtherNode);
-  nsresult CompareDocPosition(nsINode* aOtherNode, PRUint16* aReturn)
+  PRUint16 CompareDocumentPosition(nsINode* aOtherNode);
+  nsresult CompareDocumentPosition(nsINode* aOtherNode, PRUint16* aResult)
   {
     NS_ENSURE_ARG(aOtherNode);
-    *aReturn = CompareDocPosition(aOtherNode);
+
+    *aResult = CompareDocumentPosition(aOtherNode);
+
     return NS_OK;
   }
-  nsresult CompareDocumentPosition(nsIDOMNode* aOther,
-                                   PRUint16* aReturn);
 
-  nsresult IsSameNode(nsIDOMNode* aOther,
-                      PRBool* aReturn);
+  PRBool IsSameNode(nsINode *aOtherNode)
+  {
+    return aOtherNode == this;
+  }
 
-  nsresult LookupPrefix(const nsAString& aNamespaceURI, nsAString& aPrefix);
-  nsresult IsDefaultNamespace(const nsAString& aNamespaceURI, PRBool* aResult)
+  virtual PRBool IsEqualNode(nsINode *aOtherNode) = 0;
+
+  void LookupPrefix(const nsAString& aNamespaceURI, nsAString& aPrefix);
+  PRBool 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);
-
-  nsresult IsEqualNode(nsIDOMNode* aOther, PRBool* aReturn);
-  PRBool IsEqualTo(nsINode* aOther);
+  void LookupNamespaceURI(const nsAString& aNamespacePrefix,
+                          nsAString& aNamespaceURI);
 
   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
--- a/content/base/public/nsINodeInfo.h
+++ b/content/base/public/nsINodeInfo.h
@@ -76,17 +76,17 @@ class nsIPrincipal;
  { 0x95, 0x90, 0xcc, 0x43, 0x6b, 0xe9, 0xcf, 0xa0 } }
 
 class nsINodeInfo : public nsISupports
 {
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_INODEINFO_IID)
 
   nsINodeInfo()
-    : mInner(nsnull, nsnull, kNameSpaceID_None, 0, nsnull),
+    : mInner(nsnull, nsnull, kNameSpaceID_None),
       mOwnerManager(nsnull)
   {
   }
 
   /*
    * Get the name from this node as a string, this does not include the prefix.
    *
    * For the HTML element "<body>" this will return "body" and for the XML
@@ -116,27 +116,22 @@ public:
    * For the HTML element "<body>" this will return "body" and for the XML
    * element "<html:body>" this will return "html:body".
    */
   const nsString& QualifiedName() const {
     return mQualifiedName;
   }
 
   /*
-   * Returns the node's nodeName as defined in DOM Core
+   * As above, but return the qualified name in corrected case as
+   * needed.  For example, for HTML elements in HTML documents, this
+   * will return an ASCII-uppercased version of the qualified name.
    */
-  const nsString& NodeName() const {
-    return mNodeName;
-  }
-
-  /*
-   * Returns the node's localName as defined in DOM Core
-   */
-  const nsString& LocalName() const {
-    return mLocalName;
+  const nsString& QualifiedNameCorrectedCase() const {
+    return mQualifiedNameCorrectedCase;
   }
 
 #ifdef MOZILLA_INTERNAL_API
   /*
    * Get the prefix from this node as a string.
    *
    * For the HTML element "<body>" this will return a null string and for
    * the XML element "<html:body>" this will return the string "html".
@@ -159,46 +154,41 @@ public:
    */
   nsIAtom* GetPrefixAtom() const
   {
     return mInner.mPrefix;
   }
 
   /*
    * Get the namespace URI for a node, if the node has a namespace URI.
+   *
+   * For the HTML element "<body>" in a HTML document this will return a null
+   * string and for the XML element "<html:body>" (assuming that this element,
+   * or one of its ancestors has an
+   * xmlns:html='http://www.w3.org/1999/xhtml' attribute) this will return
+   * the string "http://www.w3.org/1999/xhtml".
    */
   virtual nsresult GetNamespaceURI(nsAString& aNameSpaceURI) const = 0;
 
   /*
    * Get the namespace ID for a node if the node has a namespace, if not this
    * returns kNameSpaceID_None.
+   *
+   * For the HTML element "<body>" in a HTML document this will return
+   * kNameSpaceID_None and for the XML element "<html:body>" (assuming that
+   * this element, or one of its ancestors has an
+   * xmlns:html='http://www.w3.org/1999/xhtml' attribute) this will return
+   * the namespace ID for "http://www.w3.org/1999/xhtml".
    */
   PRInt32 NamespaceID() const
   {
     return mInner.mNamespaceID;
   }
 
   /*
-   * Get the nodetype for the node. Returns the values specified in nsIDOMNode
-   * for nsIDOMNode.nodeType
-   */
-  PRUint16 NodeType() const
-  {
-    return mInner.mNodeType;
-  }
-
-  /*
-   * Get the extra name, used by PIs and DocTypes, for the node.
-   */
-  nsIAtom* GetExtraName() const
-  {
-    return mInner.mExtraName;
-  }
-
-  /*
    * Get and set the ID attribute atom for this node.
    * See http://www.w3.org/TR/1998/REC-xml-19980210#sec-attribute-types
    * for the definition of an ID attribute.
    *
    */
   nsIAtom* GetIDAttributeAtom() const
   {
     return mIDAttributeAtom;
@@ -327,38 +317,34 @@ protected:
    * the key is automatically deleted.
    */
 
   class nsNodeInfoInner
   {
   public:
     nsNodeInfoInner()
       : mName(nsnull), mPrefix(nsnull), mNamespaceID(kNameSpaceID_Unknown),
-        mNodeType(0), mNameString(nsnull), mExtraName(nsnull)
+        mNameString(nsnull)
     {
     }
-    nsNodeInfoInner(nsIAtom *aName, nsIAtom *aPrefix, PRInt32 aNamespaceID,
-                    PRUint16 aNodeType, nsIAtom* aExtraName)
+    nsNodeInfoInner(nsIAtom *aName, nsIAtom *aPrefix, PRInt32 aNamespaceID)
       : mName(aName), mPrefix(aPrefix), mNamespaceID(aNamespaceID),
-        mNodeType(aNodeType), mNameString(nsnull), mExtraName(aExtraName)
+        mNameString(nsnull)
     {
     }
-    nsNodeInfoInner(const nsAString& aTmpName, nsIAtom *aPrefix,
-                    PRInt32 aNamespaceID, PRUint16 aNodeType)
+    nsNodeInfoInner(const nsAString& aTmpName, nsIAtom *aPrefix, PRInt32 aNamespaceID)
       : mName(nsnull), mPrefix(aPrefix), mNamespaceID(aNamespaceID),
-        mNodeType(aNodeType), mNameString(&aTmpName), mExtraName(nsnull)
+        mNameString(&aTmpName)
     {
     }
 
     nsIAtom*            mName;
     nsIAtom*            mPrefix;
     PRInt32             mNamespaceID;
-    PRUint16            mNodeType; // As defined by nsIDOMNode.nodeType
     const nsAString*    mNameString;
-    nsIAtom*            mExtraName; // Only used by PIs and DocTypes
   };
 
   // nsNodeInfoManager needs to pass mInner to the hash table.
   friend class nsNodeInfoManager;
 
   nsNodeInfoInner mInner;
 
   nsCOMPtr<nsIAtom> mIDAttributeAtom;
@@ -367,19 +353,16 @@ protected:
   /*
    * Members for various functions of mName+mPrefix that we can be
    * asked to compute.
    */
 
   // Qualified name
   nsString mQualifiedName;
 
-  // nodeName for the node.
-  nsString mNodeName;
-
-  // localName for the node. This is either equal to mInner.mName, or a
-  // void string, depending on mInner.mNodeType.
-  nsString mLocalName;
+  // Qualified name in "corrected case"; this will depend on our
+  // document and on mNamespaceID.
+  nsString mQualifiedNameCorrectedCase;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsINodeInfo, NS_INODEINFO_IID)
 
 #endif /* nsINodeInfo_h___ */
--- a/content/base/src/nsCommentNode.cpp
+++ b/content/base/src/nsCommentNode.cpp
@@ -50,30 +50,27 @@ class nsCommentNode : public nsGenericDO
 public:
   nsCommentNode(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~nsCommentNode();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE(nsGenericDOMDataNode::)
+  NS_IMPL_NSIDOMNODE_USING_GENERIC_DOM_DATA
 
   // nsIDOMCharacterData
   NS_FORWARD_NSIDOMCHARACTERDATA(nsGenericDOMDataNode::)
 
   // nsIDOMComment
   // Empty interface
 
-  // nsINode
+  // nsIContent
   virtual PRBool IsNodeOfType(PRUint32 aFlags) const;
 
-  virtual nsGenericDOMDataNode* CloneDataNode(nsINodeInfo *aNodeInfo,
-                                              PRBool aCloneText) const;
-
   virtual nsXPCClassInfo* GetClassInfo();
 #ifdef DEBUG
   virtual void List(FILE* out, PRInt32 aIndent) const;
   virtual void DumpContent(FILE* out = stdout, PRInt32 aIndent = 0,
                            PRBool aDumpAll = PR_TRUE) const
   {
     return;
   }
@@ -99,18 +96,16 @@ NS_NewCommentNode(nsIContent** aInstance
   NS_ADDREF(*aInstancePtrResult = instance);
 
   return NS_OK;
 }
 
 nsCommentNode::nsCommentNode(already_AddRefed<nsINodeInfo> aNodeInfo)
   : nsGenericDOMDataNode(aNodeInfo)
 {
-  NS_ABORT_IF_FALSE(mNodeInfo->NodeType() == nsIDOMNode::COMMENT_NODE,
-                    "Bad NodeType in aNodeInfo");
 }
 
 nsCommentNode::~nsCommentNode()
 {
 }
 
 DOMCI_NODE_DATA(Comment, nsCommentNode)
 
@@ -127,16 +122,42 @@ NS_IMPL_RELEASE_INHERITED(nsCommentNode,
 
 
 PRBool
 nsCommentNode::IsNodeOfType(PRUint32 aFlags) const
 {
   return !(aFlags & ~(eCONTENT | eCOMMENT | eDATA_NODE));
 }
 
+NS_IMETHODIMP
+nsCommentNode::GetNodeName(nsAString& aNodeName)
+{
+  aNodeName.AssignLiteral("#comment");
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsCommentNode::GetNodeValue(nsAString& aNodeValue)
+{
+  return nsGenericDOMDataNode::GetNodeValue(aNodeValue);
+}
+
+NS_IMETHODIMP
+nsCommentNode::SetNodeValue(const nsAString& aNodeValue)
+{
+  return nsGenericDOMDataNode::SetNodeValue(aNodeValue);
+}
+
+NS_IMETHODIMP
+nsCommentNode::GetNodeType(PRUint16* aNodeType)
+{
+  *aNodeType = (PRUint16)nsIDOMNode::COMMENT_NODE;
+  return NS_OK;
+}
+
 nsGenericDOMDataNode*
 nsCommentNode::CloneDataNode(nsINodeInfo *aNodeInfo, PRBool aCloneText) const
 {
   nsCOMPtr<nsINodeInfo> ni = aNodeInfo;
   nsCommentNode *it = new nsCommentNode(ni.forget());
   if (it && aCloneText) {
     it->mText = mText;
   }
--- a/content/base/src/nsContentList.cpp
+++ b/content/base/src/nsContentList.cpp
@@ -40,16 +40,17 @@
  * nsBaseContentList is a basic list of content nodes; nsContentList
  * is a commonly used NodeList implementation (used for
  * getElementsByTagName, some properties on nsIDOMHTMLDocument, etc).
  */
 
 #include "nsContentList.h"
 #include "nsIContent.h"
 #include "nsIDOMNode.h"
+#include "nsIDOM3Node.h"
 #include "nsIDocument.h"
 #include "nsGenericElement.h"
 
 #include "nsContentUtils.h"
 
 #include "nsGkAtoms.h"
 
 // Form related includes
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -59,16 +59,17 @@
 #include "nsIContent.h"
 #include "mozilla/dom/Element.h"
 #include "nsIDocument.h"
 #include "nsINodeInfo.h"
 #include "nsReadableUtils.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOMNodeList.h"
 #include "nsIDOMNode.h"
+#include "nsIDOM3Node.h"
 #include "nsIIOService.h"
 #include "nsNetCID.h"
 #include "nsNetUtil.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsDOMError.h"
 #include "nsPIDOMWindow.h"
 #include "nsIJSContextStack.h"
 #include "nsIDocShell.h"
@@ -2083,17 +2084,16 @@ nsContentUtils::SplitQName(const nsICont
   return NS_OK;
 }
 
 // static
 nsresult
 nsContentUtils::GetNodeInfoFromQName(const nsAString& aNamespaceURI,
                                      const nsAString& aQualifiedName,
                                      nsNodeInfoManager* aNodeInfoManager,
-                                     PRUint16 aNodeType,
                                      nsINodeInfo** aNodeInfo)
 {
   nsIParserService* parserService = GetParserService();
   NS_ENSURE_TRUE(parserService, NS_ERROR_FAILURE);
 
   const nsAFlatString& qName = PromiseFlatString(aQualifiedName);
   const PRUnichar* colon;
   nsresult rv = parserService->CheckQName(qName, PR_TRUE, &colon);
@@ -2103,21 +2103,21 @@ nsContentUtils::GetNodeInfoFromQName(con
   sNameSpaceManager->RegisterNameSpace(aNamespaceURI, nsID);
   if (colon) {
     const PRUnichar* end;
     qName.EndReading(end);
 
     nsCOMPtr<nsIAtom> prefix = do_GetAtom(Substring(qName.get(), colon));
 
     rv = aNodeInfoManager->GetNodeInfo(Substring(colon + 1, end), prefix,
-                                       nsID, aNodeType, aNodeInfo);
+                                       nsID, aNodeInfo);
   }
   else {
     rv = aNodeInfoManager->GetNodeInfo(aQualifiedName, nsnull, nsID,
-                                       aNodeType, aNodeInfo);
+                                       aNodeInfo);
   }
   NS_ENSURE_SUCCESS(rv, rv);
 
   return nsContentUtils::IsValidNodeName((*aNodeInfo)->NameAtom(),
                                          (*aNodeInfo)->GetPrefixAtom(),
                                          (*aNodeInfo)->NamespaceID()) ?
          NS_OK : NS_ERROR_DOM_NAMESPACE_ERR;
 }
--- a/content/base/src/nsDOMAttribute.cpp
+++ b/content/base/src/nsDOMAttribute.cpp
@@ -67,18 +67,17 @@ using namespace mozilla::dom;
 PRBool nsDOMAttribute::sInitialized;
 
 nsDOMAttribute::nsDOMAttribute(nsDOMAttributeMap *aAttrMap,
                                already_AddRefed<nsINodeInfo> aNodeInfo,
                                const nsAString   &aValue, PRBool aNsAware)
   : nsIAttribute(aAttrMap, aNodeInfo, aNsAware), mValue(aValue), mChild(nsnull)
 {
   NS_ABORT_IF_FALSE(mNodeInfo, "We must get a nodeinfo here!");
-  NS_ABORT_IF_FALSE(mNodeInfo->NodeType() == nsIDOMNode::ATTRIBUTE_NODE,
-                    "Wrong nodeType");
+
 
   // We don't add a reference to our content. It will tell us
   // to drop our reference when it goes away.
 
   EnsureChildState();
 
   nsIContent* content = GetContentInternal();
   if (content) {
@@ -136,16 +135,17 @@ NS_INTERFACE_TABLE_HEAD(nsDOMAttribute)
   NS_INTERFACE_MAP_ENTRY_TEAROFF(nsISupportsWeakReference,
                                  new nsNodeSupportsWeakRefTearoff(this))
   NS_INTERFACE_MAP_ENTRY_TEAROFF(nsIDOMEventTarget,
                                  nsDOMEventRTTearoff::Create(this))
   NS_INTERFACE_MAP_ENTRY_TEAROFF(nsIDOM3EventTarget,
                                  nsDOMEventRTTearoff::Create(this))
   NS_INTERFACE_MAP_ENTRY_TEAROFF(nsIDOMNSEventTarget,
                                  nsDOMEventRTTearoff::Create(this))
+  NS_INTERFACE_MAP_ENTRY_TEAROFF(nsIDOM3Node, new nsNode3Tearoff(this))
   NS_INTERFACE_MAP_ENTRY_TEAROFF(nsIDOMXPathNSResolver,
                                  new nsNode3Tearoff(this))
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(Attr)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsDOMAttribute)
 NS_IMPL_CYCLE_COLLECTING_RELEASE_WITH_DESTROY(nsDOMAttribute,
                                               nsNodeUtils::LastRelease(this))
@@ -188,29 +188,28 @@ nsDOMAttribute::SetOwnerDocument(nsIDocu
   NS_ASSERTION(doc != aDocument, "bad call to nsDOMAttribute::SetOwnerDocument");
   if (doc) {
     doc->DeleteAllPropertiesFor(this);
   }
 
   nsCOMPtr<nsINodeInfo> newNodeInfo;
   newNodeInfo = aDocument->NodeInfoManager()->
     GetNodeInfo(mNodeInfo->NameAtom(), mNodeInfo->GetPrefixAtom(),
-                mNodeInfo->NamespaceID(),
-                nsIDOMNode::ATTRIBUTE_NODE);
+                mNodeInfo->NamespaceID());
   NS_ENSURE_TRUE(newNodeInfo, NS_ERROR_OUT_OF_MEMORY);
   NS_ASSERTION(newNodeInfo, "GetNodeInfo lies");
   mNodeInfo.swap(newNodeInfo);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMAttribute::GetName(nsAString& aName)
 {
-  aName = NodeName();
+  aName = mNodeInfo->QualifiedName();
   return NS_OK;
 }
 
 already_AddRefed<nsIAtom>
 nsDOMAttribute::GetNameAtom(nsIContent* aContent)
 {
   nsIAtom* result = nsnull;
   if (!mNsAware &&
@@ -495,91 +494,50 @@ nsDOMAttribute::IsSupported(const nsAStr
 already_AddRefed<nsIURI>
 nsDOMAttribute::GetBaseURI() const
 {
   nsINode *parent = GetContentInternal();
 
   return parent ? parent->GetBaseURI() : nsnull;
 }
 
-NS_IMETHODIMP
-nsDOMAttribute::GetDOMBaseURI(nsAString &aURI)
+PRBool
+nsDOMAttribute::IsEqualNode(nsINode* aOther)
 {
-  return nsINode::GetDOMBaseURI(aURI);
-}
+  if (!aOther || !aOther->IsNodeOfType(eATTRIBUTE))
+    return PR_FALSE;
+
+  nsDOMAttribute *other = static_cast<nsDOMAttribute*>(aOther);
 
-NS_IMETHODIMP
-nsDOMAttribute::CompareDocumentPosition(nsIDOMNode *other,
-                                        PRUint16 *aResult)
-{
-  return nsINode::CompareDocumentPosition(other, aResult);
+  // Prefix, namespace URI, local name, node name check.
+  if (!mNodeInfo->Equals(other->NodeInfo())) {
+    return PR_FALSE;
+  }
+
+  // Value check
+  // Checks not needed:  Child nodes, attributes.
+  nsAutoString ourValue, otherValue;
+  GetValue(ourValue);
+  other->GetValue(otherValue);
+
+  return ourValue.Equals(otherValue);
 }
 
-NS_IMETHODIMP
-nsDOMAttribute::IsEqualNode(nsIDOMNode* aOther, PRBool* aResult)
+void
+nsDOMAttribute::GetTextContent(nsAString &aTextContent)
 {
-  return nsINode::IsEqualNode(aOther, aResult);
+  GetNodeValue(aTextContent);
 }
 
-NS_IMETHODIMP
-nsDOMAttribute::GetTextContent(nsAString &aTextContent)
-{
-  return GetNodeValue(aTextContent);
-}
-
-NS_IMETHODIMP
+nsresult
 nsDOMAttribute::SetTextContent(const nsAString& aTextContent)
 {
   return SetNodeValue(aTextContent);
 }
 
-NS_IMETHODIMP
-nsDOMAttribute::IsSameNode(nsIDOMNode *other, PRBool *aResult)
-{
-  *aResult = other == this;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDOMAttribute::LookupPrefix(const nsAString & namespaceURI,
-                             nsAString & aResult)
-{
-  SetDOMStringToNull(aResult);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDOMAttribute::IsDefaultNamespace(const nsAString & namespaceURI,
-                                   PRBool *aResult)
-{
-  *aResult = namespaceURI.IsEmpty();
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDOMAttribute::LookupNamespaceURI(const nsAString & prefix,
-                              nsAString & aResult)
-{
-  SetDOMStringToNull(aResult);
-  return NS_OK;
-}
-
-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);
-}
 
 NS_IMETHODIMP
 nsDOMAttribute::GetIsId(PRBool* aReturn)
 {
   nsIContent* content = GetContentInternal();
   if (!content)
   {
     *aReturn = PR_FALSE;
--- a/content/base/src/nsDOMAttribute.h
+++ b/content/base/src/nsDOMAttribute.h
@@ -51,17 +51,17 @@
 #include "nsINodeInfo.h"
 #include "nsIDOM3Attr.h"
 #include "nsDOMAttributeMap.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsContentUtils.h"
 #include "nsStubMutationObserver.h"
 
 // Attribute helper class used to wrap up an attribute with a dom
-// object that implements nsIDOMAttr, nsIDOM3Attr, nsIDOMNode
+// object that implements nsIDOMAttr, nsIDOM3Attr, nsIDOMNode, nsIDOM3Node
 class nsDOMAttribute : public nsIAttribute,
                        public nsIDOMAttr,
                        public nsIDOM3Attr,
                        public nsStubMutationObserver
 {
 public:
   nsDOMAttribute(nsDOMAttributeMap* aAttrMap,
                  already_AddRefed<nsINodeInfo> aNodeInfo,
@@ -107,16 +107,19 @@ public:
                                             const nsIID& aIID);
   virtual nsresult GetSystemEventGroup(nsIDOMEventGroup** aGroup);
   virtual nsIScriptContext* GetContextForEventHandlers(nsresult* aRv)
   {
     return nsContentUtils::GetContextForEventHandlers(this, aRv);
   }
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
   virtual already_AddRefed<nsIURI> GetBaseURI() const;
+  virtual PRBool IsEqualNode(nsINode *aOtherNode);
+  virtual void GetTextContent(nsAString &aTextContent);
+  virtual nsresult SetTextContent(const nsAString& aTextContent);
 
   static void Initialize();
   static void Shutdown();
 
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsDOMAttribute,
                                                          nsIAttribute)
 
   NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED
--- a/content/base/src/nsDOMAttributeMap.cpp
+++ b/content/base/src/nsDOMAttributeMap.cpp
@@ -336,18 +336,17 @@ nsDOMAttributeMap::SetNamedItemInternal(
         if (mContent->IsInHTMLDocument() &&
             mContent->IsHTML()) {
           nsAutoString lower;
           ToLowerCase(name, lower);
           name = lower;
         }
 
         rv = mContent->NodeInfo()->NodeInfoManager()->
-          GetNodeInfo(name, nsnull, kNameSpaceID_None,
-                      nsIDOMNode::ATTRIBUTE_NODE, getter_AddRefs(ni));
+          GetNodeInfo(name, nsnull, kNameSpaceID_None, getter_AddRefs(ni));
         NS_ENSURE_SUCCESS(rv, rv);
         // value is already empty
       }
     }
 
     nsAutoString value;
     attribute->GetValue(value);
 
@@ -403,18 +402,17 @@ nsDOMAttributeMap::GetItemAt(PRUint32 aI
   nsDOMAttribute* node = nsnull;
 
   const nsAttrName* name;
   if (mContent && (name = mContent->GetAttrNameAt(aIndex))) {
     // Don't use the nodeinfo even if one exists since it can
     // have the wrong owner document.
     nsCOMPtr<nsINodeInfo> ni;
     ni = mContent->NodeInfo()->NodeInfoManager()->
-      GetNodeInfo(name->LocalName(), name->GetPrefix(), name->NamespaceID(),
-                  nsIDOMNode::ATTRIBUTE_NODE);
+      GetNodeInfo(name->LocalName(), name->GetPrefix(), name->NamespaceID());
     if (ni) {
       node = GetAttribute(ni, PR_TRUE);
     }
     else {
       *aResult = NS_ERROR_OUT_OF_MEMORY;
     }
   }
 
@@ -481,18 +479,17 @@ nsDOMAttributeMap::GetNamedItemNSInterna
     const nsAttrName* name = mContent->GetAttrNameAt(i);
     PRInt32 attrNS = name->NamespaceID();
     nsIAtom* nameAtom = name->LocalName();
 
     if (nameSpaceID == attrNS &&
         nameAtom->Equals(aLocalName)) {
       nsCOMPtr<nsINodeInfo> ni;
       ni = mContent->NodeInfo()->NodeInfoManager()->
-        GetNodeInfo(nameAtom, name->GetPrefix(), nameSpaceID,
-                    nsIDOMNode::ATTRIBUTE_NODE);
+        GetNodeInfo(nameAtom, name->GetPrefix(), nameSpaceID);
       NS_ENSURE_TRUE(ni, NS_ERROR_OUT_OF_MEMORY);
 
       if (aRemove) {
         return RemoveAttribute(ni, aReturn);
       }
 
       NS_ADDREF(*aReturn = GetAttribute(ni, PR_TRUE));
 
--- a/content/base/src/nsDOMDocumentType.cpp
+++ b/content/base/src/nsDOMDocumentType.cpp
@@ -41,16 +41,17 @@
 
 #include "nsDOMDocumentType.h"
 #include "nsDOMAttributeMap.h"
 #include "nsIDOMNamedNodeMap.h"
 #include "nsGkAtoms.h"
 #include "nsCOMPtr.h"
 #include "nsContentUtils.h"
 #include "nsDOMString.h"
+#include "nsIDOM3Node.h"
 #include "nsNodeInfoManager.h"
 #include "nsIDocument.h"
 #include "nsIXPConnect.h"
 #include "nsIDOMDocument.h"
 #include "xpcpublic.h"
 
 nsresult
 NS_NewDOMDocumentType(nsIDOMDocumentType** aDocType,
@@ -73,41 +74,39 @@ NS_NewDOMDocumentType(nsIDOMDocumentType
   else {
     nimgr = new nsNodeInfoManager();
     nsresult rv = nimgr->Init(nsnull);
     NS_ENSURE_SUCCESS(rv, rv);
 
     nimgr->SetDocumentPrincipal(aPrincipal);
   }
 
-  nsCOMPtr<nsINodeInfo> ni =
-    nimgr->GetNodeInfo(nsGkAtoms::documentTypeNodeName, nsnull,
-                       kNameSpaceID_None,
-                       nsIDOMNode::DOCUMENT_TYPE_NODE,
-                       aName);
+  nsCOMPtr<nsINodeInfo> ni;
+  ni = nimgr->GetNodeInfo(nsGkAtoms::documentTypeNodeName, nsnull,
+                          kNameSpaceID_None);
   NS_ENSURE_TRUE(ni, NS_ERROR_OUT_OF_MEMORY);
 
-  *aDocType = new nsDOMDocumentType(ni.forget(), aPublicId, aSystemId,
+  *aDocType = new nsDOMDocumentType(ni.forget(), aName, aPublicId, aSystemId,
                                     aInternalSubset);
   NS_ADDREF(*aDocType);
 
   return NS_OK;
 }
 
 nsDOMDocumentType::nsDOMDocumentType(already_AddRefed<nsINodeInfo> aNodeInfo,
+                                     nsIAtom *aName,
                                      const nsAString& aPublicId,
                                      const nsAString& aSystemId,
                                      const nsAString& aInternalSubset) :
-  nsDOMDocumentTypeForward(aNodeInfo),
+  nsGenericDOMDataNode(aNodeInfo),
+  mName(aName),
   mPublicId(aPublicId),
   mSystemId(aSystemId),
   mInternalSubset(aInternalSubset)
 {
-  NS_ABORT_IF_FALSE(mNodeInfo->NodeType() == nsIDOMNode::DOCUMENT_TYPE_NODE,
-                    "Bad NodeType in aNodeInfo");
 }
 
 nsDOMDocumentType::~nsDOMDocumentType()
 {
 }
 
 DOMCI_NODE_DATA(DocumentType, nsDOMDocumentType)
 
@@ -136,17 +135,17 @@ const nsTextFragment*
 nsDOMDocumentType::GetText()
 {
   return nsnull;
 }
 
 NS_IMETHODIMP    
 nsDOMDocumentType::GetName(nsAString& aName)
 {
-  aName = NodeName();
+  mName->ToString(aName);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMDocumentType::GetPublicId(nsAString& aPublicId)
 {
   aPublicId = mPublicId;
 
@@ -163,21 +162,50 @@ nsDOMDocumentType::GetSystemId(nsAString
 
 NS_IMETHODIMP
 nsDOMDocumentType::GetInternalSubset(nsAString& aInternalSubset)
 {
   aInternalSubset = mInternalSubset;
   return NS_OK;
 }
 
+NS_IMETHODIMP
+nsDOMDocumentType::GetNodeName(nsAString& aNodeName)
+{
+  mName->ToString(aNodeName);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDOMDocumentType::GetNodeValue(nsAString& aNodeValue)
+{
+  SetDOMStringToNull(aNodeValue);
+
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDOMDocumentType::SetNodeValue(const nsAString& aNodeValue)
+{
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDOMDocumentType::GetNodeType(PRUint16* aNodeType)
+{
+  *aNodeType = nsIDOMNode::DOCUMENT_TYPE_NODE;
+
+  return NS_OK;
+}
+
 nsGenericDOMDataNode*
 nsDOMDocumentType::CloneDataNode(nsINodeInfo *aNodeInfo, PRBool aCloneText) const
 {
   nsCOMPtr<nsINodeInfo> ni = aNodeInfo;
-  return new nsDOMDocumentType(ni.forget(), mPublicId, mSystemId,
+  return new nsDOMDocumentType(ni.forget(), mName, mPublicId, mSystemId,
                                mInternalSubset);
 }
 
 nsresult
 nsDOMDocumentType::BindToTree(nsIDocument *aDocument, nsIContent *aParent,
                               nsIContent *aBindingParent,
                               PRBool aCompileEventHandlers)
 {
@@ -193,19 +221,17 @@ nsDOMDocumentType::BindToTree(nsIDocumen
     //     break inserting DOMDocumentType nodes through other DOM methods
     //     though.
     nsNodeInfoManager *nimgr = aParent ?
       aParent->NodeInfo()->NodeInfoManager() :
       aDocument->NodeInfoManager();
     nsCOMPtr<nsINodeInfo> newNodeInfo;
     newNodeInfo = nimgr->GetNodeInfo(mNodeInfo->NameAtom(),
                                      mNodeInfo->GetPrefixAtom(),
-                                     mNodeInfo->NamespaceID(),
-                                     nsIDOMNode::DOCUMENT_TYPE_NODE,
-                                     mNodeInfo->GetExtraName());
+                                     mNodeInfo->NamespaceID());
     NS_ENSURE_TRUE(newNodeInfo, NS_ERROR_OUT_OF_MEMORY);
 
     mNodeInfo.swap(newNodeInfo);
 
     JSObject *oldScope = GetWrapper();
     if (oldScope) {
       nsIXPConnect *xpc = nsContentUtils::XPConnect();
 
--- a/content/base/src/nsDOMDocumentType.h
+++ b/content/base/src/nsDOMDocumentType.h
@@ -48,73 +48,47 @@
 #include "nsGenericDOMDataNode.h"
 #include "nsString.h"
 
 // XXX DocumentType is currently implemented by inheriting the generic
 // CharacterData object, even though DocumentType is not character
 // data. This is done simply for convenience and should be changed if
 // this restricts what should be done for character data.
 
-class nsDOMDocumentTypeForward : public nsGenericDOMDataNode,
-                                 public nsIDOMDocumentType
-{
-public:
-  nsDOMDocumentTypeForward(already_AddRefed<nsINodeInfo> aNodeInfo)
-    : nsGenericDOMDataNode(aNodeInfo)
-  {
-  }
-
-  // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE(nsGenericDOMDataNode::)
-};
-
-class nsDOMDocumentType : public nsDOMDocumentTypeForward
+class nsDOMDocumentType : public nsGenericDOMDataNode,
+                          public nsIDOMDocumentType
 {
 public:
   nsDOMDocumentType(already_AddRefed<nsINodeInfo> aNodeInfo,
+                    nsIAtom *aName,
                     const nsAString& aPublicId,
                     const nsAString& aSystemId,
                     const nsAString& aInternalSubset);
 
   virtual ~nsDOMDocumentType();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
-  // Forwarded by base class
+  NS_IMPL_NSIDOMNODE_USING_GENERIC_DOM_DATA
 
   // nsIDOMDocumentType
   NS_DECL_NSIDOMDOCUMENTTYPE
 
-  NS_IMETHODIMP GetNodeValue(nsAString& aNodeValue)
-  {
-    SetDOMStringToNull(aNodeValue);
-  
-    return NS_OK;
-  }
-  NS_IMETHODIMP SetNodeValue(const nsAString& aNodeValue)
-  {
-    return NS_OK;
-  }
-
-  // nsINode
+  // nsIContent overrides
   virtual PRBool IsNodeOfType(PRUint32 aFlags) const;
-
-  // nsIContent overrides
   virtual const nsTextFragment* GetText();
   virtual nsresult BindToTree(nsIDocument *aDocument, nsIContent *aParent,
                               nsIContent *aBindingParent,
                               PRBool aCompileEventHandlers);
 
-  virtual nsGenericDOMDataNode* CloneDataNode(nsINodeInfo *aNodeInfo,
-                                              PRBool aCloneText) const;
-
   virtual nsXPCClassInfo* GetClassInfo();
 protected:
+  nsCOMPtr<nsIAtom> mName;
   nsString mPublicId;
   nsString mSystemId;
   nsString mInternalSubset;
 };
 
 nsresult
 NS_NewDOMDocumentType(nsIDOMDocumentType** aDocType,
                       nsNodeInfoManager *aOwnerDoc,
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -1697,16 +1697,17 @@ NS_INTERFACE_TABLE_HEAD(nsDocument)
     NS_INTERFACE_TABLE_ENTRY(nsDocument, nsIRadioGroupContainer)
     NS_INTERFACE_TABLE_ENTRY(nsDocument, nsIRadioGroupContainer_MOZILLA_2_0_BRANCH)
     NS_INTERFACE_TABLE_ENTRY(nsDocument, nsIMutationObserver)
     NS_INTERFACE_TABLE_ENTRY(nsDocument, nsIApplicationCacheContainer)
     NS_INTERFACE_TABLE_ENTRY(nsDocument, nsIDOMDocumentTouch)
   NS_OFFSET_AND_INTERFACE_TABLE_END
   NS_OFFSET_AND_INTERFACE_TABLE_TO_MAP_SEGUE
   NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(nsDocument)
+  NS_INTERFACE_MAP_ENTRY_TEAROFF(nsIDOM3Node, new nsNode3Tearoff(this))
   NS_INTERFACE_MAP_ENTRY_TEAROFF(nsIDOMXPathNSResolver,
                                  new nsNode3Tearoff(this))
   NS_INTERFACE_MAP_ENTRY_TEAROFF(nsIDOMNodeSelector,
                                  new nsNodeSelectorTearoff(this))
   if (aIID.Equals(NS_GET_IID(nsIDOMXPathEvaluator)) ||
       aIID.Equals(NS_GET_IID(nsIXPathEvaluatorInternal))) {
     if (!mXPathEvaluatorTearoff) {
       nsresult rv;
@@ -1992,18 +1993,16 @@ nsDocument::Init()
 
   NS_ADDREF(mNodeInfoManager);
 
   nsresult  rv = mNodeInfoManager->Init(this);
   NS_ENSURE_SUCCESS(rv, rv);
 
   mNodeInfo = mNodeInfoManager->GetDocumentNodeInfo();
   NS_ENSURE_TRUE(mNodeInfo, NS_ERROR_OUT_OF_MEMORY);
-  NS_ABORT_IF_FALSE(mNodeInfo->NodeType() == nsIDOMNode::DOCUMENT_NODE,
-                    "Bad NodeType in aNodeInfo");
 
   NS_ASSERTION(GetOwnerDoc() == this, "Our nodeinfo is busted!");
 
   mScriptLoader = new nsScriptLoader(this);
   NS_ENSURE_TRUE(mScriptLoader, NS_ERROR_OUT_OF_MEMORY);
 
   if (!mImageTracker.Init()) {
     return NS_ERROR_OUT_OF_MEMORY;
@@ -3379,28 +3378,16 @@ nsDocument::FindContentForSubDocument(ns
 }
 
 PRBool
 nsDocument::IsNodeOfType(PRUint32 aFlags) const
 {
     return !(aFlags & ~eDOCUMENT);
 }
 
-PRUint16
-nsDocument::NodeType()
-{
-    return (PRUint16)nsIDOMNode::DOCUMENT_NODE;
-}
-
-void
-nsDocument::NodeName(nsAString& aNodeName)
-{
-  aNodeName.AssignLiteral("#document");
-}
-
 Element*
 nsDocument::GetRootElementInternal() const
 {
   // Loop backwards because any non-elements, such as doctypes and PIs
   // are likely to appear before the root element.
   PRUint32 i;
   for (i = mChildren.ChildCount(); i > 0; --i) {
     nsIContent* child = mChildren.ChildAt(i - 1);
@@ -4381,17 +4368,16 @@ nsresult
 nsDocument::CreateElementNS(const nsAString& aNamespaceURI,
                             const nsAString& aQualifiedName,
                             nsIContent** aReturn)
 {
   nsCOMPtr<nsINodeInfo> nodeInfo;
   nsresult rv = nsContentUtils::GetNodeInfoFromQName(aNamespaceURI,
                                                      aQualifiedName,
                                                      mNodeInfoManager,
-                                                     nsIDOMNode::ELEMENT_NODE,
                                                      getter_AddRefs(nodeInfo));
   NS_ENSURE_SUCCESS(rv, rv);
 
   PRInt32 ns = nodeInfo->NamespaceID();
   return NS_NewElement(aReturn, ns,
                        nodeInfo.forget(), NOT_FROM_PARSER);
 }
 
@@ -4514,17 +4500,16 @@ nsDocument::CreateAttribute(const nsAStr
   nsresult rv = nsContentUtils::CheckQName(aName, PR_FALSE);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsAutoString value;
   nsDOMAttribute* attribute;
 
   nsCOMPtr<nsINodeInfo> nodeInfo;
   rv = mNodeInfoManager->GetNodeInfo(aName, nsnull, kNameSpaceID_None,
-                                     nsIDOMNode::ATTRIBUTE_NODE,
                                      getter_AddRefs(nodeInfo));
   NS_ENSURE_SUCCESS(rv, rv);
 
   attribute = new nsDOMAttribute(nsnull, nodeInfo.forget(), value, PR_FALSE);
   NS_ENSURE_TRUE(attribute, NS_ERROR_OUT_OF_MEMORY);
 
   return CallQueryInterface(attribute, aReturn);
 }
@@ -4536,17 +4521,16 @@ nsDocument::CreateAttributeNS(const nsAS
 {
   NS_ENSURE_ARG_POINTER(aResult);
   *aResult = nsnull;
 
   nsCOMPtr<nsINodeInfo> nodeInfo;
   nsresult rv = nsContentUtils::GetNodeInfoFromQName(aNamespaceURI,
                                                      aQualifiedName,
                                                      mNodeInfoManager,
-                                                     nsIDOMNode::ATTRIBUTE_NODE,
                                                      getter_AddRefs(nodeInfo));
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsAutoString value;
   nsDOMAttribute* attribute =
     new nsDOMAttribute(nsnull, nodeInfo.forget(), value, PR_TRUE);
   NS_ENSURE_TRUE(attribute, NS_ERROR_OUT_OF_MEMORY);
 
@@ -5199,18 +5183,17 @@ nsDocument::SetTitle(const nsAString& aT
   if (!title) {
     Element *head = GetHeadElement();
     if (!head)
       return NS_OK;
 
     {
       nsCOMPtr<nsINodeInfo> titleInfo;
       titleInfo = mNodeInfoManager->GetNodeInfo(nsGkAtoms::title, nsnull,
-                                                kNameSpaceID_XHTML,
-                                                nsIDOMNode::ELEMENT_NODE);
+                                                kNameSpaceID_XHTML);
       if (!titleInfo)
         return NS_OK;
       title = NS_NewHTMLTitleElement(titleInfo.forget());
       if (!title)
         return NS_OK;
     }
 
     head->AppendChildTo(title, PR_TRUE);
@@ -5777,91 +5760,45 @@ nsDocument::Normalize()
 NS_IMETHODIMP
 nsDocument::IsSupported(const nsAString& aFeature, const nsAString& aVersion,
                         PRBool* aReturn)
 {
   return nsGenericElement::InternalIsSupported(static_cast<nsIDOMDocument*>(this),
                                                aFeature, aVersion, aReturn);
 }
 
-NS_IMETHODIMP
-nsDocument::GetDOMBaseURI(nsAString &aURI)
-{
-  return nsIDocument::GetDOMBaseURI(aURI);
-}
-
-NS_IMETHODIMP
+void
 nsDocument::GetTextContent(nsAString &aTextContent)
 {
   SetDOMStringToNull(aTextContent);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDocument::IsEqualNode(nsIDOMNode* aOther, PRBool* aResult)
-{
-  return nsINode::IsEqualNode(aOther, aResult);
-}
-
-NS_IMETHODIMP
-nsDocument::CompareDocumentPosition(nsIDOMNode *other,
-                                   PRUint16 *aResult)
-{
-  return nsINode::CompareDocumentPosition(other, aResult);
-}
-
-NS_IMETHODIMP
-nsDocument::SetTextContent(const nsAString & aTextContent)
-{
-  return nsINode::SetTextContent(aTextContent);
-}
-
-NS_IMETHODIMP
-nsDocument::IsSameNode(nsIDOMNode *other, PRBool *aResult)
-{
-  *aResult = other == this;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDocument::LookupPrefix(const nsAString & namespaceURI, nsAString & aResult)
-{
-  SetDOMStringToNull(aResult);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDocument::IsDefaultNamespace(const nsAString & namespaceURI,
-                              PRBool *aResult)
-{
-  *aResult = namespaceURI.IsEmpty();
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDocument::LookupNamespaceURI(const nsAString & prefix,
-                              nsAString & aResult)
-{
-  SetDOMStringToNull(aResult);
-  return NS_OK;
-}
-
-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);
+}
+
+PRBool
+nsDocument::IsEqualNode(nsINode* aOther)
+{
+  if (!aOther || !aOther->IsNodeOfType(eDOCUMENT))
+    return PR_FALSE;
+
+  // Child nodes check.
+  PRUint32 childCount = GetChildCount();
+  if (childCount != aOther->GetChildCount()) {
+    return PR_FALSE;
+  }
+
+  for (PRUint32 i = 0; i < childCount; i++) {
+    if (!GetChildAt(i)->IsEqual(aOther->GetChildAt(i))) {
+      return PR_FALSE;
+    }
+  }
+
+  /* Checks not needed:  Prefix, namespace URI, local name, node name,
+     node value, attributes.
+   */
+
+  return PR_TRUE;
 }
 
 NS_IMETHODIMP
 nsDocument::GetInputEncoding(nsAString& aInputEncoding)
 {
   if (mHaveInputEncoding) {
     return GetCharacterSet(aInputEncoding);
   }
@@ -6930,17 +6867,16 @@ nsDocument::CreateElem(const nsAString& 
 
   *aResult = nsnull;
   
   PRInt32 elementType = aDocumentDefaultType ? mDefaultElementType :
     aNamespaceID;
 
   nsCOMPtr<nsINodeInfo> nodeInfo;
   mNodeInfoManager->GetNodeInfo(aName, aPrefix, aNamespaceID,
-                                nsIDOMNode::ELEMENT_NODE,
                                 getter_AddRefs(nodeInfo));
   NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
 
   return NS_NewElement(aResult, elementType, nodeInfo.forget(),
                        NOT_FROM_PARSER);
 }
 
 PRBool
--- a/content/base/src/nsDocument.h
+++ b/content/base/src/nsDocument.h
@@ -56,16 +56,17 @@
 #include "nsStubDocumentObserver.h"
 #include "nsIDOM3EventTarget.h"
 #include "nsIDOMNSEventTarget.h"
 #include "nsIDOMStyleSheetList.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsIDOMEventTarget.h"
 #include "nsIContent.h"
 #include "nsIEventListenerManager.h"
+#include "nsIDOM3Node.h"
 #include "nsIDOMNodeSelector.h"
 #include "nsIPrincipal.h"
 #include "nsIParser.h"
 #include "nsBindingManager.h"
 #include "nsINodeInfo.h"
 #include "nsHashtable.h"
 #include "nsInterfaceHashtable.h"
 #include "nsIBoxObject.h"
@@ -713,18 +714,16 @@ public:
   virtual void OnPageShow(PRBool aPersisted, nsIDOMEventTarget* aDispatchStartTarget);
   virtual void OnPageHide(PRBool aPersisted, nsIDOMEventTarget* aDispatchStartTarget);
   
   virtual void WillDispatchMutationEvent(nsINode* aTarget);
   virtual void MutationEventDispatched(nsINode* aTarget);
 
   // nsINode
   virtual PRBool IsNodeOfType(PRUint32 aFlags) const;
-  virtual PRUint16 NodeType();
-  virtual void NodeName(nsAString& aNodeName);
   virtual nsIContent *GetChildAt(PRUint32 aIndex) const;
   virtual nsIContent * const * GetChildArray(PRUint32* aChildCount) const;
   virtual PRInt32 IndexOf(nsINode* aPossibleChild) const;
   virtual PRUint32 GetChildCount() const;
   virtual nsresult InsertChildAt(nsIContent* aKid, PRUint32 aIndex,
                                  PRBool aNotify);
   virtual nsresult AppendChildTo(nsIContent* aKid, PRBool aNotify);
   virtual nsresult RemoveChildAt(PRUint32 aIndex, PRBool aNotify);
@@ -742,16 +741,18 @@ public:
   virtual nsIScriptContext* GetContextForEventHandlers(nsresult* aRv)
   {
     return nsContentUtils::GetContextForEventHandlers(this, aRv);
   }
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const
   {
     return NS_ERROR_NOT_IMPLEMENTED;
   }
+  virtual PRBool IsEqualNode(nsINode* aOther);
+  virtual void GetTextContent(nsAString &aTextContent);
 
   // nsIRadioGroupContainer
   NS_IMETHOD WalkRadioGroup(const nsAString& aName,
                             nsIRadioVisitor* aVisitor,
                             PRBool aFlushContent);
   NS_IMETHOD SetCurrentRadioButton(const nsAString& aName,
                                    nsIDOMHTMLInputElement* aRadio);
   NS_IMETHOD GetCurrentRadioButton(const nsAString& aName,
--- a/content/base/src/nsDocumentEncoder.cpp
+++ b/content/base/src/nsDocumentEncoder.cpp
@@ -372,17 +372,19 @@ nsDocumentEncoder::SerializeNodeStart(ns
     mozilla::dom::Element* originalElement =
       aOriginalNode && aOriginalNode->IsElement() ?
         aOriginalNode->AsElement() : nsnull;
     mSerializer->AppendElementStart(node->AsElement(),
                                     originalElement, aStr);
     return NS_OK;
   }
 
-  switch (node->NodeType()) {
+  PRUint16 type;
+  node->GetNodeType(&type);
+  switch (type) {
     case nsIDOMNode::TEXT_NODE:
     {
       mSerializer->AppendText(static_cast<nsIContent*>(node),
                               aStartOffset, aEndOffset, aStr);
       break;
     }
     case nsIDOMNode::CDATA_SECTION_NODE:
     {
--- a/content/base/src/nsDocumentFragment.cpp
+++ b/content/base/src/nsDocumentFragment.cpp
@@ -45,37 +45,90 @@
 #include "nsGenericElement.h"
 #include "nsINameSpaceManager.h"
 #include "nsINodeInfo.h"
 #include "nsNodeInfoManager.h"
 #include "nsIDocument.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOMAttr.h"
 #include "nsDOMError.h"
+#include "nsIDOM3Node.h"
 #include "nsGkAtoms.h"
 #include "nsDOMString.h"
 #include "nsIDOMUserDataHandler.h"
 
 class nsDocumentFragment : public nsGenericElement,
                            public nsIDOMDocumentFragment
 {
 public:
+  nsDocumentFragment(already_AddRefed<nsINodeInfo> aNodeInfo);
+  virtual ~nsDocumentFragment();
+
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
-  // interface nsIDOMNode
-  NS_FORWARD_NSIDOMNODE(nsGenericElement::)
-
   // interface nsIDOMDocumentFragment
-  // NS_DECL_NSIDOCUMENTFRAGMENT  Empty
-
-  nsDocumentFragment(already_AddRefed<nsINodeInfo> aNodeInfo);
-  virtual ~nsDocumentFragment()
+  NS_IMETHOD    GetNodeName(nsAString& aNodeName)
+  { return nsGenericElement::GetNodeName(aNodeName); }
+  NS_IMETHOD    GetNodeValue(nsAString& aNodeValue)
+  { return nsGenericElement::GetNodeValue(aNodeValue); }
+  NS_IMETHOD    SetNodeValue(const nsAString& aNodeValue)
+  { return nsGenericElement::SetNodeValue(aNodeValue); }
+  NS_IMETHOD    GetNodeType(PRUint16* aNodeType);
+  NS_IMETHOD    GetParentNode(nsIDOMNode** aParentNode)
+  { return nsGenericElement::GetParentNode(aParentNode); }
+  NS_IMETHOD    GetChildNodes(nsIDOMNodeList** aChildNodes)
+  { return nsGenericElement::GetChildNodes(aChildNodes); }
+  NS_IMETHOD    GetFirstChild(nsIDOMNode** aFirstChild)
+  { return nsGenericElement::GetFirstChild(aFirstChild); }
+  NS_IMETHOD    GetLastChild(nsIDOMNode** aLastChild)
+  { return nsGenericElement::GetLastChild(aLastChild); }
+  NS_IMETHOD    GetPreviousSibling(nsIDOMNode** aPreviousSibling)
+  { return nsGenericElement::GetPreviousSibling(aPreviousSibling); }
+  NS_IMETHOD    GetNextSibling(nsIDOMNode** aNextSibling)
+  { return nsGenericElement::GetNextSibling(aNextSibling); }
+  NS_IMETHOD    GetAttributes(nsIDOMNamedNodeMap** aAttributes)
+    {
+      *aAttributes = nsnull;
+      return NS_OK;
+    }
+  NS_IMETHOD    GetOwnerDocument(nsIDOMDocument** aOwnerDocument)
+  { return nsGenericElement::GetOwnerDocument(aOwnerDocument); }
+  NS_IMETHOD    InsertBefore(nsIDOMNode* aNewChild, nsIDOMNode* aRefChild, 
+                             nsIDOMNode** aReturn)
+  { return nsGenericElement::InsertBefore(aNewChild, aRefChild, aReturn); }
+  NS_IMETHOD    ReplaceChild(nsIDOMNode* aNewChild, nsIDOMNode* aOldChild, 
+                             nsIDOMNode** aReturn)
+  { return nsGenericElement::ReplaceChild(aNewChild, aOldChild, aReturn); }
+  NS_IMETHOD    RemoveChild(nsIDOMNode* aOldChild, nsIDOMNode** aReturn)
+  { return nsGenericElement::RemoveChild(aOldChild, aReturn); }
+  NS_IMETHOD    AppendChild(nsIDOMNode* aNewChild, nsIDOMNode** aReturn)
+  { return nsGenericElement::AppendChild(aNewChild, aReturn); }
+  NS_IMETHOD    HasChildNodes(PRBool* aReturn)
+  { return nsGenericElement::HasChildNodes(aReturn); }
+  NS_IMETHOD    HasAttributes(PRBool* aReturn)
+  { return nsGenericElement::HasAttributes(aReturn); }
+  NS_IMETHOD    CloneNode(PRBool aDeep, nsIDOMNode** aReturn)
+  { return nsGenericElement::CloneNode(aDeep, aReturn); }
+  NS_IMETHOD    GetPrefix(nsAString& aPrefix)
+  { return nsGenericElement::GetPrefix(aPrefix); }
+  NS_IMETHOD    SetPrefix(const nsAString& aPrefix);
+  NS_IMETHOD    GetNamespaceURI(nsAString& aNamespaceURI)
+  { return nsGenericElement::GetNamespaceURI(aNamespaceURI); }
+  NS_IMETHOD    GetLocalName(nsAString& aLocalName)
   {
+    SetDOMStringToNull(aLocalName);
+    return NS_OK;
   }
+  NS_IMETHOD    Normalize()
+  { return nsGenericElement::Normalize(); }
+  NS_IMETHOD    IsSupported(const nsAString& aFeature,
+                            const nsAString& aVersion,
+                            PRBool* aReturn)
+  { return nsGenericElement::IsSupported(aFeature, aVersion, aReturn); }
 
   // nsIContent
   nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
                    const nsAString& aValue, PRBool aNotify)
   {
     return SetAttr(aNameSpaceID, aName, nsnull, aValue, aNotify);
   }
   virtual nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
@@ -113,18 +166,17 @@ protected:
 nsresult
 NS_NewDocumentFragment(nsIDOMDocumentFragment** aInstancePtrResult,
                        nsNodeInfoManager *aNodeInfoManager)
 {
   NS_ENSURE_ARG(aNodeInfoManager);
 
   nsCOMPtr<nsINodeInfo> nodeInfo;
   nodeInfo = aNodeInfoManager->GetNodeInfo(nsGkAtoms::documentFragmentNodeName,
-                                           nsnull, kNameSpaceID_None,
-                                           nsIDOMNode::DOCUMENT_FRAGMENT_NODE);
+                                           nsnull, kNameSpaceID_None);
   NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
 
   nsDocumentFragment *it = new nsDocumentFragment(nodeInfo.forget());
   if (!it) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   NS_ADDREF(*aInstancePtrResult = it);
@@ -133,16 +185,20 @@ NS_NewDocumentFragment(nsIDOMDocumentFra
 }
 
 nsDocumentFragment::nsDocumentFragment(already_AddRefed<nsINodeInfo> aNodeInfo)
   : nsGenericElement(aNodeInfo)
 {
   ClearIsElement();
 }
 
+nsDocumentFragment::~nsDocumentFragment()
+{
+}
+
 PRBool
 nsDocumentFragment::IsNodeOfType(PRUint32 aFlags) const
 {
   return !(aFlags & ~(eCONTENT | eDOCUMENT_FRAGMENT));
 }
 
 nsIAtom*
 nsDocumentFragment::DoGetID() const
@@ -164,9 +220,22 @@ NS_INTERFACE_TABLE_HEAD(nsDocumentFragme
                            nsIDOMDocumentFragment)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(DocumentFragment)
 NS_INTERFACE_MAP_END_INHERITING(nsGenericElement)
 
 
 NS_IMPL_ADDREF_INHERITED(nsDocumentFragment, nsGenericElement)
 NS_IMPL_RELEASE_INHERITED(nsDocumentFragment, nsGenericElement)
 
+NS_IMETHODIMP    
+nsDocumentFragment::GetNodeType(PRUint16* aNodeType)
+{
+  *aNodeType = (PRUint16)nsIDOMNode::DOCUMENT_FRAGMENT_NODE;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDocumentFragment::SetPrefix(const nsAString& aPrefix)
+{
+  return NS_ERROR_DOM_NAMESPACE_ERR;
+}
+
 NS_IMPL_ELEMENT_CLONE(nsDocumentFragment)
--- a/content/base/src/nsGenericDOMDataNode.cpp
+++ b/content/base/src/nsGenericDOMDataNode.cpp
@@ -43,16 +43,17 @@
 #include "nsGenericDOMDataNode.h"
 #include "nsGenericElement.h"
 #include "nsIDocument.h"
 #include "nsIEventListenerManager.h"
 #include "nsIDOMDocument.h"
 #include "nsReadableUtils.h"
 #include "nsMutationEvent.h"
 #include "nsINameSpaceManager.h"
+#include "nsIDOM3Node.h"
 #include "nsIURI.h"
 #include "nsIPrivateDOMEvent.h"
 #include "nsIDOMEvent.h"
 #include "nsIDOMText.h"
 #include "nsCOMPtr.h"
 #include "nsDOMString.h"
 #include "nsIDOMUserDataHandler.h"
 #include "nsChangeHint.h"
@@ -67,23 +68,16 @@
 #include "pldhash.h"
 #include "prprf.h"
 
 namespace css = mozilla::css;
 
 nsGenericDOMDataNode::nsGenericDOMDataNode(already_AddRefed<nsINodeInfo> aNodeInfo)
   : nsIContent(aNodeInfo)
 {
-  NS_ABORT_IF_FALSE(mNodeInfo->NodeType() == nsIDOMNode::TEXT_NODE ||
-                    mNodeInfo->NodeType() == nsIDOMNode::CDATA_SECTION_NODE ||
-                    mNodeInfo->NodeType() == nsIDOMNode::COMMENT_NODE ||
-                    mNodeInfo->NodeType() ==
-                      nsIDOMNode::PROCESSING_INSTRUCTION_NODE ||
-                    mNodeInfo->NodeType() == nsIDOMNode::DOCUMENT_TYPE_NODE,
-                    "Bad NodeType in aNodeInfo");
 }
 
 nsGenericDOMDataNode::~nsGenericDOMDataNode()
 {
   NS_PRECONDITION(!IsInDoc(),
                   "Please remove this from the document properly");
 }
 
@@ -130,16 +124,17 @@ NS_INTERFACE_MAP_BEGIN(nsGenericDOMDataN
   NS_INTERFACE_MAP_ENTRY_TEAROFF(nsIDOMEventTarget,
                                  nsDOMEventRTTearoff::Create(this))
   NS_INTERFACE_MAP_ENTRY_TEAROFF(nsIDOM3EventTarget,
                                  nsDOMEventRTTearoff::Create(this))
   NS_INTERFACE_MAP_ENTRY_TEAROFF(nsIDOMNSEventTarget,
                                  nsDOMEventRTTearoff::Create(this))
   NS_INTERFACE_MAP_ENTRY_TEAROFF(nsISupportsWeakReference,
                                  new nsNodeSupportsWeakRefTearoff(this))
+  NS_INTERFACE_MAP_ENTRY_TEAROFF(nsIDOM3Node, new nsNode3Tearoff(this))
   NS_INTERFACE_MAP_ENTRY_TEAROFF(nsIDOMXPathNSResolver,
                                  new nsNode3Tearoff(this))
   // nsNodeSH::PreCreate() depends on the identity pointer being the
   // same as nsINode (which nsIContent inherits), so if you change the
   // below line, make sure nsNodeSH::PreCreate() still does the right
   // thing!
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIContent)
 NS_INTERFACE_MAP_END
@@ -174,16 +169,24 @@ nsresult
 nsGenericDOMDataNode::GetPrefix(nsAString& aPrefix)
 {
   SetDOMStringToNull(aPrefix);
 
   return NS_OK;
 }
 
 nsresult
+nsGenericDOMDataNode::GetLocalName(nsAString& aLocalName)
+{
+  SetDOMStringToNull(aLocalName);
+
+  return NS_OK;
+}
+
+nsresult
 nsGenericDOMDataNode::Normalize()
 {
   return NS_OK;
 }
 
 nsresult
 nsGenericDOMDataNode::IsSupported(const nsAString& aFeature,
                                   const nsAString& aVersion,
--- a/content/base/src/nsGenericDOMDataNode.h
+++ b/content/base/src/nsGenericDOMDataNode.h
@@ -84,26 +84,16 @@ class nsGenericDOMDataNode : public nsIC
 {
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
 
   nsGenericDOMDataNode(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~nsGenericDOMDataNode();
 
   // Implementation for nsIDOMNode
-  nsresult GetNodeName(nsAString& aNodeName)
-  {
-    aNodeName = NodeName();
-    return NS_OK;
-  }
-  nsresult GetNodeType(PRUint16* 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 = nsnull;
     return NS_OK;
   }
@@ -133,30 +123,22 @@ public:
   {
     return nsINode::RemoveChild(aOldChild, aReturn);
   }
   nsresult AppendChild(nsIDOMNode* aNewChild, nsIDOMNode** aReturn)
   {
     return InsertBefore(aNewChild, nsnull, aReturn);
   }
   nsresult GetNamespaceURI(nsAString& aNamespaceURI);
-  nsresult GetLocalName(nsAString& aLocalName)
-  {
-    aLocalName = LocalName();
-    return NS_OK;
-  }
+  nsresult GetLocalName(nsAString& aLocalName);
   nsresult GetPrefix(nsAString& aPrefix);
   nsresult Normalize();
   nsresult IsSupported(const nsAString& aFeature,
                        const nsAString& aVersion,
                        PRBool* aReturn);
-  nsresult CloneNode(PRBool aDeep, nsIDOMNode** aReturn)
-  {
-    return nsNodeUtils::CloneNodeImpl(this, aDeep, PR_TRUE, aReturn);
-  }
 
   // Implementation for nsIDOMCharacterData
   nsresult GetData(nsAString& aData) const;
   nsresult SetData(const nsAString& aData);
   nsresult GetLength(PRUint32* aLength);
   nsresult SubstringData(PRUint32 aOffset, PRUint32 aCount,
                          nsAString& aReturn);
   nsresult AppendData(const nsAString& aArg);
@@ -183,23 +165,25 @@ public:
                                          const nsIID& aIID);
   virtual nsresult RemoveEventListenerByIID(nsIDOMEventListener *aListener,
                                             const nsIID& aIID);
   virtual nsresult GetSystemEventGroup(nsIDOMEventGroup** aGroup);
   virtual nsIScriptContext* GetContextForEventHandlers(nsresult* aRv)
   {
     return nsContentUtils::GetContextForEventHandlers(this, aRv);
   }
-  NS_IMETHOD GetTextContent(nsAString &aTextContent)
+  virtual void GetTextContent(nsAString &aTextContent)
   {
-    nsresult rv = GetNodeValue(aTextContent);
+#ifdef DEBUG
+    nsresult rv =
+#endif
+    GetNodeValue(aTextContent);
     NS_ASSERTION(NS_SUCCEEDED(rv), "GetNodeValue() failed?");
-    return rv;
   }
-  NS_IMETHOD SetTextContent(const nsAString& aTextContent)
+  virtual nsresult SetTextContent(const nsAString& aTextContent)
   {
     // Batch possible DOMSubtreeModified events.
     mozAutoSubtreeModified subtree(GetOwnerDoc(), nsnull);
     return SetNodeValue(aTextContent);
   }
 
   // Implementation for nsIContent
   virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
@@ -378,9 +362,94 @@ protected:
   nsTextFragment mText;
 
 private:
   void UpdateBidiStatus(const PRUnichar* aBuffer, PRUint32 aLength);
 
   already_AddRefed<nsIAtom> GetCurrentValueAtom();
 };
 
+//----------------------------------------------------------------------
+
+/**
+ * Mostly implement the nsIDOMNode API by forwarding the methods to
+ * nsGenericDOMDataNode
+ *
+ * Note that classes using this macro will need to implement:
+ *       NS_IMETHOD GetNodeType(PRUint16* aNodeType);
+ *       nsGenericDOMDataNode *CloneDataNode(nsINodeInfo *aNodeInfo,
+ *                                           PRBool aCloneText) const;
+ */
+#define NS_IMPL_NSIDOMNODE_USING_GENERIC_DOM_DATA                           \
+  NS_IMETHOD GetNodeName(nsAString& aNodeName);                             \
+  NS_IMETHOD GetLocalName(nsAString& aLocalName) {                          \
+    return nsGenericDOMDataNode::GetLocalName(aLocalName);                  \
+  }                                                                         \
+  NS_IMETHOD GetNodeValue(nsAString& aNodeValue);                           \
+  NS_IMETHOD SetNodeValue(const nsAString& aNodeValue);                     \
+  NS_IMETHOD GetNodeType(PRUint16* aNodeType);                              \
+  NS_IMETHOD GetParentNode(nsIDOMNode** aParentNode) {                      \
+    return nsGenericDOMDataNode::GetParentNode(aParentNode);                \
+  }                                                                         \
+  NS_IMETHOD GetChildNodes(nsIDOMNodeList** aChildNodes) {                  \
+    return nsGenericDOMDataNode::GetChildNodes(aChildNodes);                \
+  }                                                                         \
+  NS_IMETHOD HasChildNodes(PRBool* aHasChildNodes) {                        \
+    return nsGenericDOMDataNode::HasChildNodes(aHasChildNodes);             \
+  }                                                                         \
+  NS_IMETHOD HasAttributes(PRBool* aHasAttributes) {                        \
+    return nsGenericDOMDataNode::HasAttributes(aHasAttributes);             \
+  }                                                                         \
+  NS_IMETHOD GetFirstChild(nsIDOMNode** aFirstChild) {                      \
+    return nsGenericDOMDataNode::GetFirstChild(aFirstChild);                \
+  }                                                                         \
+  NS_IMETHOD GetLastChild(nsIDOMNode** aLastChild) {                        \
+    return nsGenericDOMDataNode::GetLastChild(aLastChild);                  \
+  }                                                                         \
+  NS_IMETHOD GetPreviousSibling(nsIDOMNode** aPreviousSibling) {            \
+    return nsGenericDOMDataNode::GetPreviousSibling(aPreviousSibling);      \
+  }                                                                         \
+  NS_IMETHOD GetNextSibling(nsIDOMNode** aNextSibling) {                    \
+    return nsGenericDOMDataNode::GetNextSibling(aNextSibling);              \
+  }                                                                         \
+  NS_IMETHOD GetAttributes(nsIDOMNamedNodeMap** aAttributes) {              \
+    return nsGenericDOMDataNode::GetAttributes(aAttributes);                \
+  }                                                                         \
+  NS_IMETHOD InsertBefore(nsIDOMNode* aNewChild, nsIDOMNode* aRefChild,     \
+                             nsIDOMNode** aReturn) {                        \
+    return nsGenericDOMDataNode::InsertBefore(aNewChild, aRefChild,         \
+                                              aReturn);                     \
+  }                                                                         \
+  NS_IMETHOD AppendChild(nsIDOMNode* aOldChild, nsIDOMNode** aReturn) {     \
+    return nsGenericDOMDataNode::AppendChild(aOldChild, aReturn);           \
+  }                                                                         \
+  NS_IMETHOD ReplaceChild(nsIDOMNode* aNewChild, nsIDOMNode* aOldChild,     \
+                             nsIDOMNode** aReturn) {                        \
+    return nsGenericDOMDataNode::ReplaceChild(aNewChild, aOldChild,         \
+                                              aReturn);                     \
+  }                                                                         \
+  NS_IMETHOD RemoveChild(nsIDOMNode* aOldChild, nsIDOMNode** aReturn) {     \
+    return nsGenericDOMDataNode::RemoveChild(aOldChild, aReturn);           \
+  }                                                                         \
+  NS_IMETHOD GetOwnerDocument(nsIDOMDocument** aOwnerDocument) {            \
+    return nsGenericDOMDataNode::GetOwnerDocument(aOwnerDocument);          \
+  }                                                                         \
+  NS_IMETHOD GetNamespaceURI(nsAString& aNamespaceURI) {                    \
+    return nsGenericDOMDataNode::GetNamespaceURI(aNamespaceURI);            \
+  }                                                                         \
+  NS_IMETHOD GetPrefix(nsAString& aPrefix) {                                \
+    return nsGenericDOMDataNode::GetPrefix(aPrefix);                        \
+  }                                                                         \
+  NS_IMETHOD Normalize() {                                                  \
+    return NS_OK;                                                           \
+  }                                                                         \
+  NS_IMETHOD IsSupported(const nsAString& aFeature,                         \
+                      const nsAString& aVersion,                            \
+                      PRBool* aReturn) {                                    \
+    return nsGenericDOMDataNode::IsSupported(aFeature, aVersion, aReturn);  \
+  }                                                                         \
+  NS_IMETHOD CloneNode(PRBool aDeep, nsIDOMNode** aReturn) {                \
+    return nsNodeUtils::CloneNodeImpl(this, aDeep, PR_TRUE, aReturn);       \
+  }                                                                         \
+  virtual nsGenericDOMDataNode *CloneDataNode(nsINodeInfo *aNodeInfo,       \
+                                              PRBool aCloneText) const;
+
 #endif /* nsGenericDOMDataNode_h___ */
--- a/content/base/src/nsGenericElement.cpp
+++ b/content/base/src/nsGenericElement.cpp
@@ -107,16 +107,17 @@
 #include "nsIDOMEventListener.h"
 #include "nsIWebNavigation.h"
 #include "nsIBaseWindow.h"
 
 #include "jsapi.h"
 
 #include "nsNodeInfoManager.h"
 #include "nsICategoryManager.h"
+#include "nsIDOMNSFeatureFactory.h"
 #include "nsIDOMDocumentType.h"
 #include "nsIDOMUserDataHandler.h"
 #include "nsGenericHTMLElement.h"
 #include "nsIEditor.h"
 #include "nsIEditorIMESupport.h"
 #include "nsIEditorDocShell.h"
 #include "nsEventDispatcher.h"
 #include "nsContentCreatorFunctions.h"
@@ -568,70 +569,40 @@ nsINode::RemoveChild(nsIDOMNode* aOldChi
   nsCOMPtr<nsIContent> oldChild = do_QueryInterface(aOldChild);
   nsresult rv = RemoveChild(oldChild);
   if (NS_SUCCEEDED(rv)) {
     NS_ADDREF(*aReturn = aOldChild);
   }
   return rv;
 }
 
-nsresult
-nsINode::GetDOMBaseURI(nsAString &aURI) const
+void
+nsINode::GetBaseURI(nsAString &aURI) const
 {
   nsCOMPtr<nsIURI> baseURI = GetBaseURI();
 
   nsCAutoString 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,
-    // return the prefix (i.e. the attribute localName).
-    for (nsIContent* content = element; content;
-         content = content->GetParent()) {
-      PRUint32 attrCount = content->GetAttrCount();
-  
-      for (PRUint32 i = 0; i < attrCount; ++i) {
-        const nsAttrName* name = content->GetAttrNameAt(i);
-  
-        if (name->NamespaceEquals(kNameSpaceID_XMLNS) &&
-            content->AttrValueIs(kNameSpaceID_XMLNS, name->LocalName(),
-                                 aNamespaceURI, eCaseMatters)) {
-          // If the localName is "xmlns", the prefix we output should be
-          // null.
-          nsIAtom *localName = name->LocalName();
-  
-          if (localName != nsGkAtoms::xmlns) {
-            localName->ToString(aPrefix);
-          }
-          else {
-            SetDOMStringToNull(aPrefix);
-          }
-          return NS_OK;
-        }
-      }
-    }
-  }
-
-  SetDOMStringToNull(aPrefix);
-
-  return NS_OK;
+  nsIAtom *prefix = element ? element->LookupPrefix(aNamespaceURI) : nsnull;
+  if (prefix) {
+    prefix->ToString(aPrefix);
+  }
+  else {
+    SetDOMStringToNull(aPrefix);
+  }
 }
 
 static nsresult
 SetUserDataProperty(PRUint16 aCategory, nsINode *aNode, nsIAtom *aKey,
                     nsISupports* aValue, void** aOldValue)
 {
   nsresult rv = aNode->SetProperty(aCategory, aKey, aValue,
                                    nsPropertyTable::SupportsDtorFunc, PR_TRUE,
@@ -684,17 +655,17 @@ nsINode::SetUserData(const nsAString &aK
   }
 
   oldData.swap(*aResult);
 
   return NS_OK;
 }
 
 PRUint16
-nsINode::CompareDocPosition(nsINode* aOtherNode)
+nsINode::CompareDocumentPosition(nsINode* aOtherNode)
 {
   NS_PRECONDITION(aOtherNode, "don't pass null");
 
   if (this == aOtherNode) {
     return 0;
   }
 
   nsAutoTPtrArray<nsINode, 32> parents1, parents2;
@@ -721,26 +692,26 @@ nsINode::CompareDocPosition(nsINode* aOt
       // Compare position between the attributes.
 
       PRUint32 i;
       const nsAttrName* attrName;
       for (i = 0; (attrName = elem->GetAttrNameAt(i)); ++i) {
         if (attrName->Equals(attr1->NodeInfo())) {
           NS_ASSERTION(!attrName->Equals(attr2->NodeInfo()),
                        "Different attrs at same position");
-          return nsIDOMNode::DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC |
-            nsIDOMNode::DOCUMENT_POSITION_PRECEDING;
+          return nsIDOM3Node::DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC |
+            nsIDOM3Node::DOCUMENT_POSITION_PRECEDING;
         }
         if (attrName->Equals(attr2->NodeInfo())) {
-          return nsIDOMNode::DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC |
-            nsIDOMNode::DOCUMENT_POSITION_FOLLOWING;
+          return nsIDOM3Node::DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC |
+            nsIDOM3Node::DOCUMENT_POSITION_FOLLOWING;
         }
       }
       NS_NOTREACHED("neither attribute in the element");
-      return nsIDOMNode::DOCUMENT_POSITION_DISCONNECTED;
+      return nsIDOM3Node::DOCUMENT_POSITION_DISCONNECTED;
     }
 
     if (elem) {
       node2 = elem;
       parents2.AppendElement(static_cast<nsINode*>(attr2));
     }
   }
 
@@ -761,240 +732,60 @@ nsINode::CompareDocPosition(nsINode* aOt
 
   // Check if the nodes are disconnected.
   PRUint32 pos1 = parents1.Length();
   PRUint32 pos2 = parents2.Length();
   nsINode* top1 = parents1.ElementAt(--pos1);
   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);
+      (nsIDOM3Node::DOCUMENT_POSITION_PRECEDING |
+       nsIDOM3Node::DOCUMENT_POSITION_DISCONNECTED |
+       nsIDOM3Node::DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC) :
+      (nsIDOM3Node::DOCUMENT_POSITION_FOLLOWING |
+       nsIDOM3Node::DOCUMENT_POSITION_DISCONNECTED |
+       nsIDOM3Node::DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC);
   }
 
   // Find where the parent chain differs and check indices in the parent.
   nsINode* parent = top1;
   PRUint32 len;
   for (len = NS_MIN(pos1, pos2); len > 0; --len) {
     nsINode* child1 = parents1.ElementAt(--pos1);
     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<PRUint16>(nsIDOMNode::DOCUMENT_POSITION_PRECEDING) :
-        static_cast<PRUint16>(nsIDOMNode::DOCUMENT_POSITION_FOLLOWING);
+        static_cast<PRUint16>(nsIDOM3Node::DOCUMENT_POSITION_PRECEDING) :
+        static_cast<PRUint16>(nsIDOM3Node::DOCUMENT_POSITION_FOLLOWING);
     }
     parent = child1;
   }
 
   // We hit the end of one of the parent chains without finding a difference
   // between the chains. That must mean that one node is an ancestor of the
   // other. The one with the shortest chain must be the ancestor.
   return pos1 < pos2 ?
-    (nsIDOMNode::DOCUMENT_POSITION_PRECEDING |
-     nsIDOMNode::DOCUMENT_POSITION_CONTAINS) :
-    (nsIDOMNode::DOCUMENT_POSITION_FOLLOWING |
-     nsIDOMNode::DOCUMENT_POSITION_CONTAINED_BY);    
-}
-
-PRBool
-nsINode::IsEqualTo(nsINode* aOther)
-{
-  if (!aOther) {
-    return PR_FALSE;
-  }
-
-  nsAutoString string1, string2;
-
-  nsINode* node1 = this;
-  nsINode* node2 = aOther;
-  do {
-    PRUint16 nodeType = node1->NodeType();
-    if (nodeType != node2->NodeType()) {
-      return PR_FALSE;
-    }
-    
-    if (!node1->mNodeInfo->Equals(node2->mNodeInfo)) {
-      return PR_FALSE;
-    }
-
-    switch(nodeType) {
-      case nsIDOMNode::ELEMENT_NODE:
-      {
-        // Both are elements (we checked that their nodeinfos are equal). Do the
-        // check on attributes.
-        Element* element1 = node1->AsElement();
-        Element* element2 = node2->AsElement();
-        PRUint32 attrCount = element1->GetAttrCount();
-        if (attrCount != element2->GetAttrCount()) {
-          return PR_FALSE;
-        }
-
-        // Iterate over attributes.
-        for (PRUint32 i = 0; i < attrCount; ++i) {
-          const nsAttrName* attrName = element1->GetAttrNameAt(i);
-#ifdef DEBUG
-          PRBool hasAttr =
-#endif
-          element1->GetAttr(attrName->NamespaceID(), attrName->LocalName(),
-                            string1);
-          NS_ASSERTION(hasAttr, "Why don't we have an attr?");
-    
-          if (!element2->AttrValueIs(attrName->NamespaceID(),
-                                     attrName->LocalName(),
-                                     string1,
-                                     eCaseMatters)) {
-            return PR_FALSE;
-          }
-        }
-        break;
-      }
-      case nsIDOMNode::TEXT_NODE:
-      case nsIDOMNode::COMMENT_NODE:
-      case nsIDOMNode::CDATA_SECTION_NODE:
-      case nsIDOMNode::PROCESSING_INSTRUCTION_NODE:
-      {
-        string1.Truncate();
-        static_cast<nsIContent*>(node1)->AppendTextTo(string1);
-        string2.Truncate();
-        static_cast<nsIContent*>(node2)->AppendTextTo(string2);
-
-        if (!string1.Equals(string2)) {
-          return PR_FALSE;
-        }
-
-        if (nodeType == nsIDOMNode::PROCESSING_INSTRUCTION_NODE) {
-          nsCOMPtr<nsIDOMNode> domNode1 = do_QueryInterface(node1);
-          nsCOMPtr<nsIDOMNode> domNode2 = do_QueryInterface(node2);
-          domNode1->GetNodeName(string1);
-          domNode2->GetNodeName(string2);
-          if (!string1.Equals(string2)) {
-            return PR_FALSE;
-          }
-        }
-
-        break;
-      }
-      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);
-        
-        // 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:
-      {
-        nsCOMPtr<nsIDOMDocumentType> docType1 = do_QueryInterface(this);
-        nsCOMPtr<nsIDOMDocumentType> docType2 = do_QueryInterface(aOther);
-    
-        NS_ASSERTION(docType1 && docType2, "Why don't we have a document type node?");
-
-        // Node name
-        docType1->GetNodeName(string1);
-        docType2->GetNodeName(string2);
-        if (!string1.Equals(string2)) {
-          return PR_FALSE;
-        }
-    
-        // Public ID
-        docType1->GetPublicId(string1);
-        docType2->GetPublicId(string2);
-        if (!string1.Equals(string2)) {
-          return PR_FALSE;
-        }
-    
-        // System ID
-        docType1->GetSystemId(string1);
-        docType2->GetSystemId(string2);
-        if (!string1.Equals(string2)) {
-          return PR_FALSE;
-        }
-    
-        // Internal subset
-        docType1->GetInternalSubset(string1);
-        docType2->GetInternalSubset(string2);
-        if (!string1.Equals(string2)) {
-          return PR_FALSE;
-        }
-
-        break;
-      }
-      default:
-        NS_ABORT_IF_FALSE(PR_FALSE, "Unknown node type");
-    }
-
-    nsINode* nextNode = node1->GetFirstChild();
-    if (nextNode) {
-      node1 = nextNode;
-      node2 = node2->GetFirstChild();
-    }
-    else {
-      if (node2->GetFirstChild()) {
-        // node2 has a firstChild, but node1 doesn't
-        return PR_FALSE;
-      }
-
-      // Find next sibling, possibly walking parent chain.
-      while (1) {
-        if (node1 == this) {
-          NS_ASSERTION(node2 == aOther, "Should have reached the start node "
-                                        "for both trees at the same time");
-          return PR_TRUE;
-        }
-
-        nextNode = node1->GetNextSibling();
-        if (nextNode) {
-          node1 = nextNode;
-          node2 = node2->GetNextSibling();
-          break;
-        }
-
-        if (node2->GetNextSibling()) {
-          // node2 has a nextSibling, but node1 doesn't
-          return PR_FALSE;
-        }
-        
-        node1 = node1->GetNodeParent();
-        node2 = node2->GetNodeParent();
-        NS_ASSERTION(node1 && node2, "no parent while walking subtree");
-      }
-    }
-  } while(node2);
-
-  return PR_FALSE;
-}
-
-nsresult
+    (nsIDOM3Node::DOCUMENT_POSITION_PRECEDING |
+     nsIDOM3Node::DOCUMENT_POSITION_CONTAINS) :
+    (nsIDOM3Node::DOCUMENT_POSITION_FOLLOWING |
+     nsIDOM3Node::DOCUMENT_POSITION_CONTAINED_BY);    
+}
+
+void
 nsINode::LookupNamespaceURI(const nsAString& aNamespacePrefix,
                             nsAString& aNamespaceURI)
 {
   Element *element = GetNameSpaceElement();
   if (!element || NS_FAILED(element->LookupNamespaceURI(aNamespacePrefix,
                                                         aNamespaceURI))) {
     SetDOMStringToNull(aNamespaceURI);
   }
-
-  return NS_OK;
 }
 
 //----------------------------------------------------------------------
 
 nsEventStates
 Element::IntrinsicState() const
 {
   return IsEditable() ? NS_EVENT_STATE_MOZ_READWRITE :
@@ -1343,27 +1134,259 @@ nsChildContentList::IndexOf(nsIContent* 
   return -1;
 }
 
 //----------------------------------------------------------------------
 
 NS_IMPL_CYCLE_COLLECTION_1(nsNode3Tearoff, mNode)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsNode3Tearoff)
+  NS_INTERFACE_MAP_ENTRY(nsIDOM3Node)
   NS_INTERFACE_MAP_ENTRY(nsIDOMXPathNSResolver)
 NS_INTERFACE_MAP_END_AGGREGATED(mNode)
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsNode3Tearoff)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsNode3Tearoff)
 
 NS_IMETHODIMP
+nsNode3Tearoff::GetBaseURI(nsAString& aURI)
+{
+  mNode->GetBaseURI(aURI);
+  
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsNode3Tearoff::GetTextContent(nsAString &aTextContent)
+{
+  mNode->GetTextContent(aTextContent);
+
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsNode3Tearoff::SetTextContent(const nsAString &aTextContent)
+{
+  return mNode->SetTextContent(aTextContent);
+}
+
+NS_IMETHODIMP
+nsNode3Tearoff::CompareDocumentPosition(nsIDOMNode* aOther,
+                                        PRUint16* aReturn)
+{
+  nsCOMPtr<nsINode> other = do_QueryInterface(aOther);
+
+  return mNode->CompareDocumentPosition(other, aReturn);
+}
+
+NS_IMETHODIMP
+nsNode3Tearoff::IsSameNode(nsIDOMNode* aOther,
+                           PRBool* aReturn)
+{
+  nsCOMPtr<nsINode> other = do_QueryInterface(aOther);
+  *aReturn = mNode->IsSameNode(other);
+
+  return NS_OK;
+}
+
+PRBool
+nsIContent::IsEqual(nsIContent* aOther)
+{
+  // We use nsIContent instead of nsINode for the attributes of elements.
+
+  NS_PRECONDITION(aOther, "Who called IsEqual?");
+
+  nsAutoString string1, string2;
+
+  // Prefix, namespace URI, local name, node name check.
+  if (!NodeInfo()->Equals(aOther->NodeInfo())) {
+    return PR_FALSE;
+  }
+
+  if (Tag() == nsGkAtoms::documentTypeNodeName) {
+    nsCOMPtr<nsIDOMDocumentType> docType1 = do_QueryInterface(this);
+    nsCOMPtr<nsIDOMDocumentType> docType2 = do_QueryInterface(aOther);
+
+    NS_ASSERTION(docType1 && docType2, "Why don't we have a document type node?");
+
+    // Public ID
+    docType1->GetPublicId(string1);
+    docType2->GetPublicId(string2);
+
+    if (!string1.Equals(string2)) {
+      return PR_FALSE;
+    }
+
+    // System ID
+    docType1->GetSystemId(string1);
+    docType2->GetSystemId(string2);
+
+    if (!string1.Equals(string2)) {
+      return PR_FALSE;
+    }
+
+    // Internal subset
+    docType1->GetInternalSubset(string1);
+    docType2->GetInternalSubset(string2);
+
+    if (!string1.Equals(string2)) {
+      return PR_FALSE;
+    }
+  }
+
+  if (IsElement()) {
+    // Both are elements (we checked that their nodeinfos are equal). Do the
+    // check on attributes.
+    Element* element2 = aOther->AsElement();
+    PRUint32 attrCount = GetAttrCount();
+    if (attrCount != element2->GetAttrCount()) {
+      return PR_FALSE;
+    }
+
+    // Iterate over attributes.
+    for (PRUint32 i = 0; i < attrCount; ++i) {
+      const nsAttrName* attrName1 = GetAttrNameAt(i);
+#ifdef DEBUG
+      PRBool hasAttr =
+#endif
+      GetAttr(attrName1->NamespaceID(), attrName1->LocalName(), string1);
+      NS_ASSERTION(hasAttr, "Why don't we have an attr?");
+
+      if (!element2->AttrValueIs(attrName1->NamespaceID(),
+                                 attrName1->LocalName(),
+                                 string1,
+                                 eCaseMatters)) {
+        return PR_FALSE;
+      }
+    }
+  } else {
+    // Node value check.
+    nsCOMPtr<nsIDOMNode> domNode1 = do_QueryInterface(this);
+    nsCOMPtr<nsIDOMNode> domNode2 = do_QueryInterface(aOther);
+    NS_ASSERTION(domNode1 && domNode2, "How'd we get nsIContent without nsIDOMNode?");
+    domNode1->GetNodeValue(string1);
+    domNode2->GetNodeValue(string2);
+    if (!string1.Equals(string2)) {
+      return PR_FALSE;
+    }
+  }
+
+  // Child nodes count.
+  PRUint32 childCount = GetChildCount();
+  if (childCount != aOther->GetChildCount()) {
+    return PR_FALSE;
+  }
+
+  // Iterate over child nodes.
+  for (PRUint32 i = 0; i < childCount; ++i) {
+    if (!GetChildAt(i)->IsEqual(aOther->GetChildAt(i))) {
+      return PR_FALSE;
+    }
+  }
+  return PR_TRUE;
+}
+
+PRBool
+nsIContent::IsEqualNode(nsINode* aOther)
+{
+  if (!aOther || !aOther->IsNodeOfType(eCONTENT))
+    return PR_FALSE;
+
+  return IsEqual(static_cast<nsIContent*>(aOther));
+}
+
+NS_IMETHODIMP
+nsNode3Tearoff::IsEqualNode(nsIDOMNode* aOther, PRBool* aReturn)
+{
+  // Since we implement nsINode, aOther must as well.
+  nsCOMPtr<nsINode> other = do_QueryInterface(aOther);
+
+  *aReturn = other && mNode->IsEqualNode(other);
+
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsNode3Tearoff::GetFeature(const nsAString& aFeature,
+                           const nsAString& aVersion,
+                           nsISupports** aReturn)
+{
+  return mNode->GetFeature(aFeature, aVersion, aReturn);
+}
+
+NS_IMETHODIMP
+nsNode3Tearoff::SetUserData(const nsAString& aKey,
+                            nsIVariant* aData,
+                            nsIDOMUserDataHandler* aHandler,
+                            nsIVariant** aResult)
+{
+  return mNode->SetUserData(aKey, aData, aHandler, aResult);
+}
+
+NS_IMETHODIMP
+nsNode3Tearoff::GetUserData(const nsAString& aKey,
+                            nsIVariant** aResult)
+{
+  NS_IF_ADDREF(*aResult = mNode->GetUserData(aKey));
+
+  return NS_OK;
+}
+
+nsIAtom*
+nsIContent::LookupPrefix(const nsAString& aNamespaceURI)
+{
+  // 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,
+  // return the prefix (i.e. the attribute localName).
+  for (nsIContent* content = this; content;
+       content = content->GetParent()) {
+    PRUint32 attrCount = content->GetAttrCount();
+
+    for (PRUint32 i = 0; i < attrCount; ++i) {
+      const nsAttrName* name = content->GetAttrNameAt(i);
+
+      if (name->NamespaceEquals(kNameSpaceID_XMLNS) &&
+          content->AttrValueIs(kNameSpaceID_XMLNS, name->LocalName(),
+                               aNamespaceURI, eCaseMatters)) {
+        // If the localName is "xmlns", the prefix we output should be
+        // null.
+        nsIAtom *localName = name->LocalName();
+
+        return localName == nsGkAtoms::xmlns ? nsnull : localName;
+      }
+    }
+  }
+
+  return nsnull;
+}
+
+NS_IMETHODIMP
+nsNode3Tearoff::LookupPrefix(const nsAString& aNamespaceURI,
+                             nsAString& aPrefix)
+{
+  mNode->LookupPrefix(aNamespaceURI, aPrefix);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
 nsNode3Tearoff::LookupNamespaceURI(const nsAString& aNamespacePrefix,
                                    nsAString& aNamespaceURI)
 {
-  return mNode->LookupNamespaceURI(aNamespacePrefix, aNamespaceURI);
+  mNode->LookupNamespaceURI(aNamespacePrefix, aNamespaceURI);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsNode3Tearoff::IsDefaultNamespace(const nsAString& aNamespaceURI,
+                                   PRBool* aReturn)
+{
+  *aReturn = mNode->IsDefaultNamespace(aNamespaceURI);
+  return NS_OK;
 }
 
 nsIContent*
 nsGenericElement::GetFirstElementChild()
 {
   nsAttrAndChildArray& children = mAttrsAndChildren;
   PRUint32 i, count = children.ChildCount();
   for (i = 0; i < count; ++i) {
@@ -2218,46 +2241,39 @@ nsGenericElement::nsDOMSlots::~nsDOMSlot
   if (mClassList) {
     mClassList->DropReference();
   }
 }
 
 nsGenericElement::nsGenericElement(already_AddRefed<nsINodeInfo> aNodeInfo)
   : Element(aNodeInfo)
 {
-  NS_ABORT_IF_FALSE(mNodeInfo->NodeType() == nsIDOMNode::ELEMENT_NODE ||
-                    (mNodeInfo->NodeType() ==
-                       nsIDOMNode::DOCUMENT_FRAGMENT_NODE &&
-                     mNodeInfo->Equals(nsGkAtoms::documentFragmentNodeName,
-                                       kNameSpaceID_None)),
-                    "Bad NodeType in aNodeInfo");
-
   // Set the default scriptID to JS - but skip SetScriptTypeID as it
   // does extra work we know isn't necessary here...
   SetFlags((nsIProgrammingLanguage::JAVASCRIPT << NODE_SCRIPT_TYPE_OFFSET));
   SetIsElement();
 }
 
 nsGenericElement::~nsGenericElement()
 {
   NS_PRECONDITION(!IsInDoc(),
                   "Please remove this from the document properly");
 }
 
 NS_IMETHODIMP
 nsGenericElement::GetNodeName(nsAString& aNodeName)
 {
-  aNodeName = NodeName();
+  aNodeName = mNodeInfo->QualifiedNameCorrectedCase();
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsGenericElement::GetLocalName(nsAString& aLocalName)
 {
-  aLocalName = LocalName();
+  mNodeInfo->GetName(aLocalName);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsGenericElement::GetNodeValue(nsAString& aNodeValue)
 {
   SetDOMStringToNull(aNodeValue);
 
@@ -2270,33 +2286,53 @@ nsGenericElement::SetNodeValue(const nsA
   // 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
 nsGenericElement::GetNodeType(PRUint16* aNodeType)
 {
-  *aNodeType = NodeType();
+  *aNodeType = (PRUint16)nsIDOMNode::ELEMENT_NODE;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsGenericElement::GetNamespaceURI(nsAString& aNamespaceURI)
 {
   return mNodeInfo->GetNamespaceURI(aNamespaceURI);
 }
 
 NS_IMETHODIMP
 nsGenericElement::GetPrefix(nsAString& aPrefix)
 {
   mNodeInfo->GetPrefix(aPrefix);
   return NS_OK;
 }
 
+static already_AddRefed<nsIDOMNSFeatureFactory>
+GetDOMFeatureFactory(const nsAString& aFeature, const nsAString& aVersion)
+{
+  nsIDOMNSFeatureFactory *factory = nsnull;
+  nsCOMPtr<nsICategoryManager> categoryManager =
+    do_GetService(NS_CATEGORYMANAGER_CONTRACTID);
+  if (categoryManager) {
+    nsCAutoString featureCategory(NS_DOMNS_FEATURE_PREFIX);
+    AppendUTF16toUTF8(aFeature, featureCategory);
+    nsXPIDLCString contractID;
+    nsresult rv = categoryManager->GetCategoryEntry(featureCategory.get(),
+                                                    NS_ConvertUTF16toUTF8(aVersion).get(),
+                                                    getter_Copies(contractID));
+    if (NS_SUCCEEDED(rv)) {
+      CallGetService(contractID.get(), &factory);  // addrefs
+    }
+  }
+  return factory;
+}
+
 nsresult
 nsGenericElement::InternalIsSupported(nsISupports* aObject,
                                       const nsAString& aFeature,
                                       const nsAString& aVersion,
                                       PRBool* aReturn)
 {
   NS_ENSURE_ARG_POINTER(aReturn);
   *aReturn = PR_FALSE;
@@ -2349,16 +2385,39 @@ nsGenericElement::InternalIsSupported(ns
   }
 #ifdef MOZ_SMIL
   else if (NS_SMILEnabled() && PL_strcasecmp(f, "TimeControl") == 0) {
     if (aVersion.IsEmpty() || PL_strcmp(v, "1.0") == 0) {
       *aReturn = PR_TRUE;
     }
   }
 #endif /* MOZ_SMIL */
+  else {
+    nsCOMPtr<nsIDOMNSFeatureFactory> factory =
+      GetDOMFeatureFactory(aFeature, aVersion);
+
+    if (factory) {
+      factory->HasFeature(aObject, aFeature, aVersion, aReturn);
+    }
+  }
+  return NS_OK;
+}
+
+nsresult
+nsINode::GetFeature(const nsAString& aFeature,
+                    const nsAString& aVersion,
+                    nsISupports** aReturn)
+{
+  *aReturn = nsnull;
+  nsCOMPtr<nsIDOMNSFeatureFactory> factory =
+    GetDOMFeatureFactory(aFeature, aVersion);
+
+  if (factory) {
+    factory->GetFeature(this, aFeature, aVersion, aReturn);
+  }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsGenericElement::IsSupported(const nsAString& aFeature,
                               const nsAString& aVersion,
                               PRBool* aReturn)
@@ -2374,25 +2433,24 @@ nsGenericElement::HasAttributes(PRBool* 
   *aReturn = GetAttrCount() > 0;
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsGenericElement::GetAttributes(nsIDOMNamedNodeMap** aAttributes)
 {
-  if (!IsElement()) {
-    *aAttributes = nsnull;
-    return NS_OK;
-  }
-
+  NS_ENSURE_ARG_POINTER(aAttributes);
   nsDOMSlots *slots = DOMSlots();
 
   if (!slots->mAttributeMap) {
     slots->mAttributeMap = new nsDOMAttributeMap(this);
+    if (!slots->mAttributeMap) {
+      return NS_ERROR_OUT_OF_MEMORY;
+    }
     if (!slots->mAttributeMap->Init()) {
       slots->mAttributeMap = nsnull;
       return NS_ERROR_FAILURE;
     }
   }
 
   NS_ADDREF(*aAttributes = slots->mAttributeMap);
 
@@ -2405,17 +2463,17 @@ nsGenericElement::HasChildNodes(PRBool* 
   *aReturn = mAttrsAndChildren.ChildCount() > 0;
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsGenericElement::GetTagName(nsAString& aTagName)
 {
-  aTagName = NodeName();
+  aTagName = mNodeInfo->QualifiedNameCorrectedCase();
   return NS_OK;
 }
 
 nsresult
 nsGenericElement::GetAttribute(const nsAString& aName,
                                nsAString& aReturn)
 {
   const nsAttrName* name = InternalGetExistingAttrNameFromQName(aName);
@@ -2586,17 +2644,16 @@ nsresult
 nsGenericElement::SetAttributeNS(const nsAString& aNamespaceURI,
                                  const nsAString& aQualifiedName,
                                  const nsAString& aValue)
 {
   nsCOMPtr<nsINodeInfo> ni;
   nsresult rv =
     nsContentUtils::GetNodeInfoFromQName(aNamespaceURI, aQualifiedName,
                                          mNodeInfo->NodeInfoManager(),
-                                         nsIDOMNode::ATTRIBUTE_NODE,
                                          getter_AddRefs(ni));
   NS_ENSURE_SUCCESS(rv, rv);
 
   return SetAttr(ni->NamespaceID(), ni->NameAtom(), ni->GetPrefixAtom(),
                  aValue, PR_TRUE);
 }
 
 nsresult
@@ -2759,66 +2816,79 @@ nsGenericElement::Normalize()
     HasMutationListeners(doc, NS_EVENT_BITS_MUTATION_NODEREMOVED);
 
   nsresult result = NS_OK;
   PRUint32 index, count = GetChildCount();
 
   for (index = 0; (index < count) && (NS_OK == result); index++) {
     nsIContent *child = GetChildAt(index);
 
-    switch (child->NodeType()) {
-      case nsIDOMNode::TEXT_NODE:
-
-        // ensure that if the text node is empty, it is removed
-        if (0 == child->TextLength()) {
-          if (hasRemoveListeners) {
-            nsContentUtils::MaybeFireNodeRemoved(child, this, doc);
-          }
-          result = RemoveChildAt(index, PR_TRUE);
-          if (NS_FAILED(result)) {
-            return result;
-          }
-
-          count--;
-          index--;
-          break;
-        }
-
-        if (index+1 < count) {
-          // Get the sibling. If it's also a text node, then
-          // remove it from the tree and join the two text
-          // nodes.
-          nsCOMPtr<nsIContent> sibling = GetChildAt(index + 1);
-
-          if (sibling->NodeType() == nsIDOMNode::TEXT_NODE) {
+    nsCOMPtr<nsIDOMNode> node = do_QueryInterface(child);
+    if (node) {
+      PRUint16 nodeType;
+      node->GetNodeType(&nodeType);
+
+      switch (nodeType) {
+        case nsIDOMNode::TEXT_NODE:
+
+          // ensure that if the text node is empty, it is removed
+          if (0 == child->TextLength()) {
             if (hasRemoveListeners) {
-              nsContentUtils::MaybeFireNodeRemoved(sibling, this, doc);
+              nsContentUtils::MaybeFireNodeRemoved(child, this, doc);
             }
-            result = RemoveChildAt(index+1, PR_TRUE);
+            result = RemoveChildAt(index, PR_TRUE);
             if (NS_FAILED(result)) {
               return result;
             }
 
-            result = JoinTextNodes(child, sibling);
-            if (NS_FAILED(result)) {
-              return result;
-            }
             count--;
             index--;
+            break;
           }
-        }
-        break;
-
-      case nsIDOMNode::ELEMENT_NODE:
-        nsCOMPtr<nsIDOMElement> element = do_QueryInterface(child);
-
-        if (element) {
-          result = element->Normalize();
-        }
-        break;
+ 
+          if (index+1 < count) {
+            // Get the sibling. If it's also a text node, then
+            // remove it from the tree and join the two text
+            // nodes.
+            nsCOMPtr<nsIContent> sibling = GetChildAt(index + 1);
+
+            nsCOMPtr<nsIDOMNode> siblingNode = do_QueryInterface(sibling);
+
+            if (siblingNode) {
+              PRUint16 siblingNodeType;
+              siblingNode->GetNodeType(&siblingNodeType);
+
+              if (siblingNodeType == nsIDOMNode::TEXT_NODE) {
+                if (hasRemoveListeners) {
+                  nsContentUtils::MaybeFireNodeRemoved(sibling, this, doc);
+                }
+                result = RemoveChildAt(index+1, PR_TRUE);
+                if (NS_FAILED(result)) {
+                  return result;
+                }
+
+                result = JoinTextNodes(child, sibling);
+                if (NS_FAILED(result)) {
+                  return result;
+                }
+                count--;
+                index--;
+              }
+            }
+          }
+          break;
+
+        case nsIDOMNode::ELEMENT_NODE:
+          nsCOMPtr<nsIDOMElement> element = do_QueryInterface(child);
+
+          if (element) {
+            result = element->Normalize();
+          }
+          break;
+      }
     }
   }
 
   return result;
 }
 
 static nsXBLBinding*
 GetFirstBindingWithContent(nsBindingManager* aBmgr, nsIContent* aBoundElem)
@@ -3450,19 +3520,18 @@ nsGenericElement::GetExistingAttrNameFro
 {
   const nsAttrName* name = InternalGetExistingAttrNameFromQName(aStr);
   if (!name) {
     return nsnull;
   }
 
   nsINodeInfo* nodeInfo;
   if (name->IsAtom()) {
-    nodeInfo = mNodeInfo->NodeInfoManager()->
-      GetNodeInfo(name->Atom(), nsnull, kNameSpaceID_None,
-                  nsIDOMNode::ATTRIBUTE_NODE).get();
+    nodeInfo = mNodeInfo->NodeInfoManager()->GetNodeInfo(name->Atom(), nsnull,
+                                                         kNameSpaceID_None).get();
   }
   else {
     NS_ADDREF(nodeInfo = name->NodeInfo());
   }
 
   return nodeInfo;
 }
 
@@ -3589,21 +3658,28 @@ nsINode::doInsertChildAt(nsIContent* aKi
   // react to unexpected attribute changes.
   nsMutationGuard::DidMutate();
 
   // Do this before checking the child-count since this could cause mutations
   nsIDocument* doc = GetCurrentDoc();
   mozAutoDocUpdate updateBatch(doc, UPDATE_CONTENT_MODEL, aNotify);
 
   if (!HasSameOwnerDoc(aKid)) {
+    nsCOMPtr<nsIDOMNode> kid = do_QueryInterface(aKid, &rv);
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    PRUint16 nodeType = 0;
+    rv = kid->GetNodeType(&nodeType);
+    NS_ENSURE_SUCCESS(rv, rv);
+
     // 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 (aKid->NodeType() != nsIDOMNode::DOCUMENT_TYPE_NODE ||
-        aKid->GetOwnerDoc()) {
+
+    if (nodeType != nsIDOMNode::DOCUMENT_TYPE_NODE || aKid->GetOwnerDoc()) {
       rv = AdoptNodeIntoOwnerDoc(this, aKid);
       NS_ENSURE_SUCCESS(rv, rv);
     }
   }
 
   PRUint32 childCount = aChildArray.ChildCount();
   NS_ENSURE_TRUE(aIndex <= childCount, NS_ERROR_ILLEGAL_VALUE);
   PRBool isAppend = (aIndex == childCount);
@@ -3807,34 +3883,43 @@ nsGenericElement::SaveSubtreeState()
 //----------------------------------------------------------------------
 
 // Generic DOMNode implementations
 
 // When replacing, aRefContent is the content being replaced; when
 // inserting it's the content before which we're inserting.  In the
 // latter case it may be null.
 static
-PRBool IsAllowedAsChild(nsIContent* aNewChild, nsINode* aParent,
-                        PRBool aIsReplace, nsIContent* aRefContent)
+PRBool IsAllowedAsChild(nsIContent* aNewChild, PRUint16 aNewNodeType,
+                        nsINode* aParent, PRBool aIsReplace,
+                        nsIContent* aRefContent)
 {
   NS_PRECONDITION(aNewChild, "Must have new child");
   NS_PRECONDITION(!aIsReplace || aRefContent,
                   "Must have ref content for replace");
   NS_PRECONDITION(aParent->IsNodeOfType(nsINode::eDOCUMENT) ||
                   aParent->IsNodeOfType(nsINode::eDOCUMENT_FRAGMENT) ||
                   aParent->IsElement(),
                   "Nodes that are not documents, document fragments or "
                   "elements can't be parents!");
+#ifdef DEBUG
+  PRUint16 debugNodeType = 0;
+  nsCOMPtr<nsIDOMNode> debugNode(do_QueryInterface(aNewChild));
+  nsresult debugRv = debugNode->GetNodeType(&debugNodeType);
+
+  NS_PRECONDITION(NS_SUCCEEDED(debugRv) && debugNodeType == aNewNodeType,
+                  "Bogus node type passed");
+#endif
 
   if (aParent && nsContentUtils::ContentIsDescendantOf(aParent, aNewChild)) {
     return PR_FALSE;
   }
 
   // The allowed child nodes differ for documents and elements
-  switch (aNewChild->NodeType()) {
+  switch (aNewNodeType) {
   case nsIDOMNode::COMMENT_NODE :
   case nsIDOMNode::PROCESSING_INSTRUCTION_NODE :
     // OK in both cases
     return PR_TRUE;
   case nsIDOMNode::TEXT_NODE :
   case nsIDOMNode::CDATA_SECTION_NODE :
   case nsIDOMNode::ENTITY_REFERENCE_NODE :
     // Only allowed under elements
@@ -3940,17 +4025,20 @@ PRBool IsAllowedAsChild(nsIContent* aNew
           if (sawElement) {
             // Can't put two elements into a document
             return PR_FALSE;
           }
           sawElement = PR_TRUE;
         }
         // If we can put this content at the the right place, we might be ok;
         // if not, we bail out.
-        if (!IsAllowedAsChild(childContent, aParent, aIsReplace,
+        nsCOMPtr<nsIDOMNode> childNode(do_QueryInterface(childContent));
+        PRUint16 type;
+        childNode->GetNodeType(&type);
+        if (!IsAllowedAsChild(childContent, type, aParent, aIsReplace,
                               aRefContent)) {
           return PR_FALSE;
         }
       }
 
       // Everything in the fragment checked out ok, so we can stick it in here
       return PR_TRUE;
     }
@@ -3994,17 +4082,19 @@ nsINode::ReplaceOrInsertBefore(PRBool aR
 
   if ((!IsNodeOfType(eDOCUMENT) &&
        !IsNodeOfType(eDOCUMENT_FRAGMENT) &&
        !IsElement()) ||
       !aNewChild->IsNodeOfType(eCONTENT)){
     return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
   }
 
-  PRUint16 nodeType = aNewChild->NodeType();
+  PRUint16 nodeType = 0;
+  nsresult res = aNewChild->GetNodeType(&nodeType);
+  NS_ENSURE_SUCCESS(res, res);
 
   // 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).
@@ -4060,22 +4150,20 @@ nsINode::ReplaceOrInsertBefore(PRBool aR
     refContent = static_cast<nsIContent*>(aRefChild);
   }
   else {
     insPos = GetChildCount();
     refContent = nsnull;
   }
 
   // Make sure that the inserted node is allowed as a child of its new parent.
-  if (!IsAllowedAsChild(newContent, this, aReplace, refContent)) {
+  if (!IsAllowedAsChild(newContent, nodeType, this, aReplace, refContent)) {
     return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
   }
 
-  nsresult res;
-
   // If we're replacing
   if (aReplace) {
     refContent = GetChildAt(insPos + 1);
 
     res = RemoveChildAt(insPos, PR_TRUE);
     NS_ENSURE_SUCCESS(res, res);
   }
 
@@ -4189,44 +4277,17 @@ nsINode::ReplaceOrInsertBefore(PRBool aR
     //       We need to reparent here for nodes for which the parent of their
     //       wrapper is not the wrapper for their ownerDocument (XUL elements,
     //       form controls, ...). Also applies in the fragment code above.
 
     res = InsertChildAt(newContent, insPos, PR_TRUE);
     NS_ENSURE_SUCCESS(res, res);
   }
 
-  return NS_OK;
-}
-
-nsresult
-nsINode::CompareDocumentPosition(nsIDOMNode* aOther, PRUint16* aReturn)
-{
-  nsCOMPtr<nsINode> other = do_QueryInterface(aOther);
-  if (!other) {
-    return NS_ERROR_NULL_POINTER;
-  }
-  *aReturn = CompareDocPosition(other);
-  return NS_OK;
-}
-
-nsresult
-nsINode::IsEqualNode(nsIDOMNode* aOther, PRBool* aReturn)
-{
-  nsCOMPtr<nsINode> other = do_QueryInterface(aOther);
-  *aReturn = IsEqualTo(other);
-  return NS_OK;
-}
-
-nsresult
-nsINode::IsSameNode(nsIDOMNode* aOther, PRBool* aReturn)
-{
-  nsCOMPtr<nsINode> other = do_QueryInterface(aOther);
-  *aReturn = other == this;
-  return NS_OK;
+  return res;
 }
 
 //----------------------------------------------------------------------
 
 // nsISupports implementation
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsGenericElement)
 
@@ -4397,16 +4458,17 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 
 NS_INTERFACE_MAP_BEGIN(nsGenericElement)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(nsGenericElement)
   NS_INTERFACE_MAP_ENTRY(nsIContent)
   NS_INTERFACE_MAP_ENTRY(nsINode)
   NS_INTERFACE_MAP_ENTRY(nsPIDOMEventTarget)
+  NS_INTERFACE_MAP_ENTRY_TEAROFF(nsIDOM3Node, new nsNode3Tearoff(this))
   NS_INTERFACE_MAP_ENTRY_TEAROFF(nsIDOMNSElement, new nsNSElementTearoff(this))
   NS_INTERFACE_MAP_ENTRY_TEAROFF(nsIDOMEventTarget,
                                  nsDOMEventRTTearoff::Create(this))
   NS_INTERFACE_MAP_ENTRY_TEAROFF(nsIDOM3EventTarget,
                                  nsDOMEventRTTearoff::Create(this))
   NS_INTERFACE_MAP_ENTRY_TEAROFF(nsIDOMNSEventTarget,
                                  nsDOMEventRTTearoff::Create(this))
   NS_INTERFACE_MAP_ENTRY_TEAROFF(nsISupportsWeakReference,
@@ -4660,18 +4722,17 @@ nsGenericElement::SetAttrAndNotify(PRInt
     if (!IsAttributeMapped(aName) ||
         !SetMappedAttribute(document, aName, aParsedValue, &rv)) {
       rv = mAttrsAndChildren.SetAndTakeAttr(aName, aParsedValue);
     }
   }
   else {
     nsCOMPtr<nsINodeInfo> ni;
     ni = mNodeInfo->NodeInfoManager()->GetNodeInfo(aName, aPrefix,
-                                                   aNamespaceID,
-                                                   nsIDOMNode::ATTRIBUTE_NODE);
+                                                   aNamespaceID);
     NS_ENSURE_TRUE(ni, NS_ERROR_OUT_OF_MEMORY);
 
     rv = mAttrsAndChildren.SetAndTakeAttr(ni, aParsedValue);
   }
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (document || HasFlag(NODE_FORCE_XBL_BINDINGS)) {
     nsIDocument* ownerDoc = GetOwnerDoc();
--- a/content/base/src/nsGenericElement.h
+++ b/content/base/src/nsGenericElement.h
@@ -46,16 +46,17 @@
 
 #include "nsCOMPtr.h"
 #include "nsAutoPtr.h"
 #include "mozilla/dom/Element.h"
 #include "nsIDOMElement.h"
 #include "nsIDOMDocumentFragment.h"
 #include "nsIDOMEventTarget.h"
 #include "nsIDOM3EventTarget.h"
+#include "nsIDOM3Node.h"
 #include "nsIDOMNSEventTarget.h"
 #include "nsIDOMNSElement.h"
 #include "nsILinkHandler.h"
 #include "nsContentUtils.h"
 #include "nsNodeUtils.h"
 #include "nsAttrAndChildArray.h"
 #include "mozFlushType.h"
 #include "nsDOMAttributeMap.h"
@@ -75,16 +76,17 @@ class nsIDOMAttr;
 class nsIDOMEventListener;
 class nsIFrame;
 class nsIDOMNamedNodeMap;
 class nsICSSDeclaration;
 class nsIDOMCSSStyleDeclaration;
 class nsIURI;
 class nsINodeInfo;
 class nsIControllers;
+class nsIDOMNSFeatureFactory;
 class nsIEventListenerManager;
 class nsIScrollableFrame;
 class nsContentList;
 class nsDOMTokenList;
 struct nsRect;
 
 typedef PRUptrdiff PtrBits;
 
@@ -124,24 +126,24 @@ public:
 private:
   // The node whose children make up the list (weak reference)
   nsINode* mNode;
 };
 
 /**
  * A tearoff class for nsGenericElement to implement additional interfaces
  */
-class nsNode3Tearoff : public nsIDOMXPathNSResolver
+class nsNode3Tearoff : public nsIDOM3Node, public nsIDOMXPathNSResolver
 {
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
 
-  NS_DECL_CYCLE_COLLECTION_CLASS(nsNode3Tearoff)
+  NS_DECL_NSIDOM3NODE
 
-  NS_DECL_NSIDOMXPATHNSRESOLVER
+  NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsNode3Tearoff, nsIDOM3Node)
 
   nsNode3Tearoff(nsINode *aNode) : mNode(aNode)
   {
   }
 
 protected:
   virtual ~nsNode3Tearoff() {}
 
@@ -338,22 +340,21 @@ public:
                                          const nsIID& aIID);
   virtual nsresult RemoveEventListenerByIID(nsIDOMEventListener *aListener,
                                             const nsIID& aIID);
   virtual nsresult GetSystemEventGroup(nsIDOMEventGroup** aGroup);
   virtual nsIScriptContext* GetContextForEventHandlers(nsresult* aRv)
   {
     return nsContentUtils::GetContextForEventHandlers(this, aRv);
   }
-  NS_IMETHOD GetTextContent(nsAString &aTextContent)
+  virtual void GetTextContent(nsAString &aTextContent)
   {
     nsContentUtils::GetNodeTextContent(this, PR_TRUE, aTextContent);
-    return NS_OK;
   }
-  NS_IMETHOD SetTextContent(const nsAString& aTextContent)
+  virtual nsresult SetTextContent(const nsAString& aTextContent)
   {
     return nsContentUtils::SetNodeTextContent(this, aTextContent, PR_FALSE);
   }
 
   // nsIContent interface methods
   virtual void UpdateEditableState(PRBool aNotify);
 
   virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
--- a/content/base/src/nsGkAtomList.h
+++ b/content/base/src/nsGkAtomList.h
@@ -1084,17 +1084,16 @@ GK_ATOM(headerWindowTarget, "window-targ
 GK_ATOM(withParam, "with-param")
 GK_ATOM(wizard, "wizard")
 GK_ATOM(wrap, "wrap")
 GK_ATOM(headerDNSPrefetchControl,"x-dns-prefetch-control")
 GK_ATOM(headerCSP, "x-content-security-policy")
 GK_ATOM(headerCSPReportOnly, "x-content-security-policy-report-only")
 GK_ATOM(headerXFO, "x-frame-options")
 GK_ATOM(xml, "xml")
-GK_ATOM(xml_stylesheet, "xml-stylesheet")
 GK_ATOM(xmlns, "xmlns")
 GK_ATOM(xmp, "xmp")
 GK_ATOM(xulcontentsgenerated, "xulcontentsgenerated")
 GK_ATOM(yes, "yes")
 GK_ATOM(z_index, "z-index")
 GK_ATOM(zeroDigit, "zero-digit")
 
 
--- a/content/base/src/nsNodeInfo.cpp
+++ b/content/base/src/nsNodeInfo.cpp
@@ -64,17 +64,16 @@ static const PRInt32 kNodeInfoPoolInitia
   (NS_SIZE_IN_HEAP(sizeof(nsNodeInfo))) * 64;
 
 // static
 nsFixedSizeAllocator* nsNodeInfo::sNodeInfoPool = nsnull;
 
 // static
 nsNodeInfo*
 nsNodeInfo::Create(nsIAtom *aName, nsIAtom *aPrefix, PRInt32 aNamespaceID,
-                   PRUint16 aNodeType, nsIAtom *aExtraName,
                    nsNodeInfoManager *aOwnerManager)
 {
   if (!sNodeInfoPool) {
     sNodeInfoPool = new nsFixedSizeAllocator();
     if (!sNodeInfoPool)
       return nsnull;
 
     nsresult rv = sNodeInfoPool->Init("NodeInfo Pool", kNodeInfoPoolSizes,
@@ -84,88 +83,65 @@ nsNodeInfo::Create(nsIAtom *aName, nsIAt
       sNodeInfoPool = nsnull;
       return nsnull;
     }
   }
 
   // Create a new one
   void* place = sNodeInfoPool->Alloc(sizeof(nsNodeInfo));
   return place ?
-    new (place) nsNodeInfo(aName, aPrefix, aNamespaceID, aNodeType, aExtraName,
-                           aOwnerManager) :
+    new (place) nsNodeInfo(aName, aPrefix, aNamespaceID, aOwnerManager) :
     nsnull;
 }
 
 nsNodeInfo::~nsNodeInfo()
 {
   mOwnerManager->RemoveNodeInfo(this);
   NS_RELEASE(mOwnerManager);
 
   NS_RELEASE(mInner.mName);
   NS_IF_RELEASE(mInner.mPrefix);
-  NS_IF_RELEASE(mInner.mExtraName);
 }
 
 
 nsNodeInfo::nsNodeInfo(nsIAtom *aName, nsIAtom *aPrefix, PRInt32 aNamespaceID,
-                       PRUint16 aNodeType, nsIAtom* aExtraName,
                        nsNodeInfoManager *aOwnerManager)
 {
-  CHECK_VALID_NODEINFO(aNodeType, aName, aNamespaceID, aExtraName);
-  NS_ABORT_IF_FALSE(aOwnerManager, "Invalid aOwnerManager");
+  NS_ABORT_IF_FALSE(aName, "Must have a name");
+  NS_ABORT_IF_FALSE(aOwnerManager, "Must have an owner manager");
+
+  mInner.mName = aName;
+  NS_ADDREF(mInner.mName);
 
-  // Initialize mInner
-  NS_ADDREF(mInner.mName = aName);
-  NS_IF_ADDREF(mInner.mPrefix = aPrefix);
+  mInner.mPrefix = aPrefix;
+  NS_IF_ADDREF(mInner.mPrefix);
+
   mInner.mNamespaceID = aNamespaceID;
-  mInner.mNodeType = aNodeType;
-  NS_ADDREF(mOwnerManager = aOwnerManager);
-  NS_IF_ADDREF(mInner.mExtraName = aExtraName);
+
+  mOwnerManager = aOwnerManager;
+  NS_ADDREF(mOwnerManager);
 
   // Now compute our cached members.
 
   // Qualified name.  If we have no prefix, use ToString on
   // mInner.mName so that we get to share its buffer.
   if (aPrefix) {
-    mQualifiedName = nsDependentAtomString(mInner.mPrefix) +
-                     NS_LITERAL_STRING(":") +
-                     nsDependentAtomString(mInner.mName);
+    aPrefix->ToString(mQualifiedName);
+    mQualifiedName.Append(PRUnichar(':'));
+    mQualifiedName.Append(nsDependentAtomString(mInner.mName));
   } else {
     mInner.mName->ToString(mQualifiedName);
   }
 
-  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);
-      } else {
-        mNodeName = mQualifiedName;
-      }
-      mInner.mName->ToString(mLocalName);
-      break;
-    case nsIDOMNode::TEXT_NODE:
-    case nsIDOMNode::CDATA_SECTION_NODE:
-    case nsIDOMNode::COMMENT_NODE:
-    case nsIDOMNode::DOCUMENT_NODE:
-    case nsIDOMNode::DOCUMENT_FRAGMENT_NODE:
-      mInner.mName->ToString(mNodeName);
-      SetDOMStringToNull(mLocalName);
-      break;
-    case nsIDOMNode::PROCESSING_INSTRUCTION_NODE:
-    case nsIDOMNode::DOCUMENT_TYPE_NODE:
-      mInner.mExtraName->ToString(mNodeName);
-      SetDOMStringToNull(mLocalName);
-      break;
-    default:
-      NS_ABORT_IF_FALSE(aNodeType == PR_UINT16_MAX,
-                        "Unknown node type");
+  // Qualified name in corrected case
+  if (aNamespaceID == kNameSpaceID_XHTML && GetDocument() &&
+      GetDocument()->IsHTML()) {
+    nsContentUtils::ASCIIToUpper(mQualifiedName, mQualifiedNameCorrectedCase);
+  } else {
+    mQualifiedNameCorrectedCase = mQualifiedName;
   }
 }
 
 
 // nsISupports
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsNodeInfo)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_0(nsNodeInfo)
--- a/content/base/src/nsNodeInfo.h
+++ b/content/base/src/nsNodeInfo.h
@@ -64,24 +64,22 @@ public:
 
   // nsNodeInfo
   // Create objects with Create
 public:
   /*
    * aName and aOwnerManager may not be null.
    */
   static nsNodeInfo *Create(nsIAtom *aName, nsIAtom *aPrefix,
-                            PRInt32 aNamespaceID, PRUint16 aNodeType,
-                            nsIAtom *aExtraName,
+                            PRInt32 aNamespaceID,
                             nsNodeInfoManager *aOwnerManager);
 private:
   nsNodeInfo(); // Unimplemented
   nsNodeInfo(const nsNodeInfo& aOther); // Unimplemented
   nsNodeInfo(nsIAtom *aName, nsIAtom *aPrefix, PRInt32 aNamespaceID,
-             PRUint16 aNodeType, nsIAtom *aExtraName,
              nsNodeInfoManager *aOwnerManager);
 protected:
   virtual ~nsNodeInfo();
 
 public:
   /**
    * Call before shutdown to clear the cache and free memory for this class.
    */
@@ -93,47 +91,9 @@ private:
   /**
    * This method gets called by Release() when it's time to delete 
    * this object, instead of always deleting the object we'll put the
    * object in the cache unless the cache is already full.
    */
    void LastRelease();
 };
 
-#define CHECK_VALID_NODEINFO(_nodeType, _name, _namespaceID, _extraName)    \
-NS_ABORT_IF_FALSE(_nodeType == nsIDOMNode::ELEMENT_NODE ||                  \
-                  _nodeType == nsIDOMNode::ATTRIBUTE_NODE ||                \
-                  _nodeType == nsIDOMNode::TEXT_NODE ||                     \
-                  _nodeType == nsIDOMNode::CDATA_SECTION_NODE ||            \
-                  _nodeType == nsIDOMNode::PROCESSING_INSTRUCTION_NODE ||   \
-                  _nodeType == nsIDOMNode::COMMENT_NODE ||                  \
-                  _nodeType == nsIDOMNode::DOCUMENT_NODE ||                 \
-                  _nodeType == nsIDOMNode::DOCUMENT_TYPE_NODE ||            \
-                  _nodeType == nsIDOMNode::DOCUMENT_FRAGMENT_NODE ||        \
-                  _nodeType == PR_UINT16_MAX,                               \
-                  "Invalid nodeType");                                      \
-NS_ABORT_IF_FALSE((_nodeType == nsIDOMNode::PROCESSING_INSTRUCTION_NODE ||  \
-                   _nodeType == nsIDOMNode::DOCUMENT_TYPE_NODE) ==          \
-                  (_extraName != nsnull),                                   \
-                  "Supply aExtraName for and only for PIs and doctypes");   \
-NS_ABORT_IF_FALSE(_nodeType == nsIDOMNode::ELEMENT_NODE ||                  \
-                  _nodeType == nsIDOMNode::ATTRIBUTE_NODE ||                \
-                  _nodeType == PR_UINT16_MAX ||                             \
-                  aNamespaceID == kNameSpaceID_None,                        \
-                  "Only attributes and elements can be in a namespace");    \
-NS_ABORT_IF_FALSE(_name && _name != nsGkAtoms::_empty, "Invalid localName");\
-NS_ABORT_IF_FALSE(((_nodeType == nsIDOMNode::TEXT_NODE) ==                  \
-                   (_name == nsGkAtoms::textTagName)) &&                    \
-                  ((_nodeType == nsIDOMNode::CDATA_SECTION_NODE) ==         \
-                   (_name == nsGkAtoms::cdataTagName)) &&                   \
-                  ((_nodeType == nsIDOMNode::COMMENT_NODE) ==               \
-                   (_name == nsGkAtoms::commentTagName)) &&                 \
-                  ((_nodeType == nsIDOMNode::DOCUMENT_NODE) ==              \
-                   (_name == nsGkAtoms::documentNodeName)) &&               \
-                  ((_nodeType == nsIDOMNode::DOCUMENT_FRAGMENT_NODE) ==     \
-                   (_name == nsGkAtoms::documentFragmentNodeName)) &&       \
-                  ((_nodeType == nsIDOMNode::DOCUMENT_TYPE_NODE) ==         \
-                   (_name == nsGkAtoms::documentTypeNodeName)) &&           \
-                  ((_nodeType == nsIDOMNode::PROCESSING_INSTRUCTION_NODE) ==\
-                   (_name == nsGkAtoms::processingInstructionTagName)),     \
-                  "Wrong localName for nodeType");
-
 #endif /* nsNodeInfo_h___ */
--- a/content/base/src/nsNodeInfoManager.cpp
+++ b/content/base/src/nsNodeInfoManager.cpp
@@ -86,19 +86,17 @@ nsNodeInfoManager::NodeInfoInnerKeyCompa
   NS_ASSERTION(key1 && key2, "Null key passed to NodeInfoInnerKeyCompare!");
 
   const nsINodeInfo::nsNodeInfoInner *node1 =
     reinterpret_cast<const nsINodeInfo::nsNodeInfoInner *>(key1);
   const nsINodeInfo::nsNodeInfoInner *node2 =
     reinterpret_cast<const nsINodeInfo::nsNodeInfoInner *>(key2);
 
   if (node1->mPrefix != node2->mPrefix ||
-      node1->mNamespaceID != node2->mNamespaceID ||
-      node1->mNodeType != node2->mNodeType ||
-      node1->mExtraName != node2->mExtraName) {
+      node1->mNamespaceID != node2->mNamespaceID) {
     return 0;
   }
 
   if (node1->mName) {
     if (node2->mName) {
       return (node1->mName == node2->mName);
     }
     return (node1->mName->Equals(*(node2->mNameString)));
@@ -202,37 +200,36 @@ nsNodeInfoManager::DropDocumentReference
   }
 
   mDocument = nsnull;
 }
 
 
 already_AddRefed<nsINodeInfo>
 nsNodeInfoManager::GetNodeInfo(nsIAtom *aName, nsIAtom *aPrefix,
-                               PRInt32 aNamespaceID, PRUint16 aNodeType,
-                               nsIAtom* aExtraName /* = nsnull */)
+                               PRInt32 aNamespaceID)
 {
-  CHECK_VALID_NODEINFO(aNodeType, aName, aNamespaceID, aExtraName);
+  NS_ENSURE_TRUE(aName, nsnull);
+  NS_ASSERTION(!aName->Equals(EmptyString()),
+               "Don't pass an empty string to GetNodeInfo, fix caller.");
 
-  nsINodeInfo::nsNodeInfoInner tmpKey(aName, aPrefix, aNamespaceID, aNodeType,
-                                      aExtraName);
+  nsINodeInfo::nsNodeInfoInner tmpKey(aName, aPrefix, aNamespaceID);
 
   void *node = PL_HashTableLookup(mNodeInfoHash, &tmpKey);
 
   if (node) {
     nsINodeInfo* nodeInfo = static_cast<nsINodeInfo *>(node);
 
     NS_ADDREF(nodeInfo);
 
     return nodeInfo;
   }
 
   nsRefPtr<nsNodeInfo> newNodeInfo =
-    nsNodeInfo::Create(aName, aPrefix, aNamespaceID, aNodeType, aExtraName,
-                       this);
+    nsNodeInfo::Create(aName, aPrefix, aNamespaceID, this);
   NS_ENSURE_TRUE(newNodeInfo, nsnull);
   
   PLHashEntry *he;
   he = PL_HashTableAdd(mNodeInfoHash, &newNodeInfo->mInner, newNodeInfo);
   NS_ENSURE_TRUE(he, nsnull);
 
   // Have to do the swap thing, because already_AddRefed<nsNodeInfo>
   // doesn't cast to already_AddRefed<nsINodeInfo>
@@ -240,111 +237,102 @@ nsNodeInfoManager::GetNodeInfo(nsIAtom *
   newNodeInfo.swap(nodeInfo);
 
   return nodeInfo;
 }
 
 
 nsresult
 nsNodeInfoManager::GetNodeInfo(const nsAString& aName, nsIAtom *aPrefix,
-                               PRInt32 aNamespaceID, PRUint16 aNodeType,
-                               nsINodeInfo** aNodeInfo)
+                               PRInt32 aNamespaceID, nsINodeInfo** aNodeInfo)
 {
-#ifdef DEBUG
-  {
-    nsCOMPtr<nsIAtom> nameAtom = do_GetAtom(aName);
-    CHECK_VALID_NODEINFO(aNodeType, nameAtom, aNamespaceID, nsnull);
-  }
-#endif
+  NS_ASSERTION(!aName.IsEmpty(),
+               "Don't pass an empty string to GetNodeInfo, fix caller.");
 
-  nsINodeInfo::nsNodeInfoInner tmpKey(aName, aPrefix, aNamespaceID, aNodeType);
+  nsINodeInfo::nsNodeInfoInner tmpKey(aName, aPrefix, aNamespaceID);
 
   void *node = PL_HashTableLookup(mNodeInfoHash, &tmpKey);
 
   if (node) {
     nsINodeInfo* nodeInfo = static_cast<nsINodeInfo *>(node);
 
     NS_ADDREF(*aNodeInfo = nodeInfo);
 
     return NS_OK;
   }
 
   
   nsCOMPtr<nsIAtom> nameAtom = do_GetAtom(aName);
   NS_ENSURE_TRUE(nameAtom, NS_ERROR_OUT_OF_MEMORY);
 
   nsRefPtr<nsNodeInfo> newNodeInfo =
-      nsNodeInfo::Create(nameAtom, aPrefix, aNamespaceID, aNodeType, nsnull,
-                         this);
+      nsNodeInfo::Create(nameAtom, aPrefix, aNamespaceID, this);
   NS_ENSURE_TRUE(newNodeInfo, NS_ERROR_OUT_OF_MEMORY);
 
   PLHashEntry *he;
   he = PL_HashTableAdd(mNodeInfoHash, &newNodeInfo->mInner, newNodeInfo);
   NS_ENSURE_TRUE(he, NS_ERROR_FAILURE);
 
   newNodeInfo.forget(aNodeInfo);
 
   return NS_OK;
 }
 
 
 nsresult
 nsNodeInfoManager::GetNodeInfo(const nsAString& aName, nsIAtom *aPrefix,
                                const nsAString& aNamespaceURI,
-                               PRUint16 aNodeType,
                                nsINodeInfo** aNodeInfo)
 {
+  nsCOMPtr<nsIAtom> nameAtom = do_GetAtom(aName);
+  NS_ENSURE_TRUE(nameAtom, NS_ERROR_OUT_OF_MEMORY);
+
   PRInt32 nsid = kNameSpaceID_None;
 
   if (!aNamespaceURI.IsEmpty()) {
     nsresult rv = nsContentUtils::NameSpaceManager()->
       RegisterNameSpace(aNamespaceURI, nsid);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
-  return GetNodeInfo(aName, aPrefix, nsid, aNodeType, aNodeInfo);
+  *aNodeInfo = GetNodeInfo(nameAtom, aPrefix, nsid).get();
+  return *aNodeInfo ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
 }
 
 already_AddRefed<nsINodeInfo>
 nsNodeInfoManager::GetTextNodeInfo()
 {
   if (!mTextNodeInfo) {
-    mTextNodeInfo = GetNodeInfo(nsGkAtoms::textTagName, nsnull,
-                                kNameSpaceID_None,
-                                nsIDOMNode::TEXT_NODE, nsnull).get();
+    mTextNodeInfo = GetNodeInfo(nsGkAtoms::textTagName, nsnull, kNameSpaceID_None).get();
   }
   else {
     NS_ADDREF(mTextNodeInfo);
   }
 
   return mTextNodeInfo;
 }
 
 already_AddRefed<nsINodeInfo>
 nsNodeInfoManager::GetCommentNodeInfo()
 {
   if (!mCommentNodeInfo) {
-    mCommentNodeInfo = GetNodeInfo(nsGkAtoms::commentTagName, nsnull,
-                                   kNameSpaceID_None,
-                                   nsIDOMNode::COMMENT_NODE, nsnull).get();
+    mCommentNodeInfo = GetNodeInfo(nsGkAtoms::commentTagName, nsnull, kNameSpaceID_None).get();
   }
   else {
     NS_ADDREF(mCommentNodeInfo);
   }
 
   return mCommentNodeInfo;
 }
 
 already_AddRefed<nsINodeInfo>
 nsNodeInfoManager::GetDocumentNodeInfo()
 {
   if (!mDocumentNodeInfo) {
-    mDocumentNodeInfo = GetNodeInfo(nsGkAtoms::documentNodeName, nsnull,
-                                    kNameSpaceID_None,
-                                    nsIDOMNode::DOCUMENT_NODE, nsnull).get();
+    mDocumentNodeInfo = GetNodeInfo(nsGkAtoms::documentNodeName, nsnull, kNameSpaceID_None).get();
   }
   else {
     NS_ADDREF(mDocumentNodeInfo);
   }
 
   return mDocumentNodeInfo;
 }
 
--- a/content/base/src/nsNodeInfoManager.h
+++ b/content/base/src/nsNodeInfoManager.h
@@ -80,24 +80,21 @@ public:
    * the document is going away.
    */
   void DropDocumentReference();
 
   /**
    * Methods for creating nodeinfo's from atoms and/or strings.
    */
   already_AddRefed<nsINodeInfo> GetNodeInfo(nsIAtom *aName, nsIAtom *aPrefix,
-                                            PRInt32 aNamespaceID,
-                                            PRUint16 aNodeType,
-                                            nsIAtom* aExtraName = nsnull);
+                                            PRInt32 aNamespaceID);
   nsresult GetNodeInfo(const nsAString& aName, nsIAtom *aPrefix,
-                       PRInt32 aNamespaceID, PRUint16 aNodeType,
-                       nsINodeInfo** aNodeInfo);
+                       PRInt32 aNamespaceID, nsINodeInfo** aNodeInfo);
   nsresult GetNodeInfo(const nsAString& aName, nsIAtom *aPrefix,
-                       const nsAString& aNamespaceURI, PRUint16 aNodeType,
+                       const nsAString& aNamespaceURI,
                        nsINodeInfo** aNodeInfo);
 
   /**
    * Returns the nodeinfo for text nodes. Can return null if OOM.
    */
   already_AddRefed<nsINodeInfo> GetTextNodeInfo();
 
   /**
--- a/content/base/src/nsNodeUtils.cpp
+++ b/content/base/src/nsNodeUtils.cpp
@@ -497,19 +497,17 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNod
       NS_ENSURE_STATE(currentDoc &&
                       (nsContentUtils::IsChromeDoc(currentDoc) ||
                        (!currentDoc->GetScriptHandlingObject(hasHadScriptHandlingObject) &&
                         !hasHadScriptHandlingObject)));
     }
 
     newNodeInfo = nodeInfoManager->GetNodeInfo(nodeInfo->NameAtom(),
                                                nodeInfo->GetPrefixAtom(),
-                                               nodeInfo->NamespaceID(),
-                                               nodeInfo->NodeType(),
-                                               nodeInfo->GetExtraName());
+                                               nodeInfo->NamespaceID());
     NS_ENSURE_TRUE(newNodeInfo, NS_ERROR_OUT_OF_MEMORY);
 
     nodeInfo = newNodeInfo;
   }
 
   nsGenericElement *elem = aNode->IsElement() ?
                            static_cast<nsGenericElement*>(aNode) :
                            nsnull;
--- a/content/base/src/nsTextNode.cpp
+++ b/content/base/src/nsTextNode.cpp
@@ -138,18 +138,16 @@ NS_NewTextNode(nsIContent** aInstancePtr
   NS_ADDREF(*aInstancePtrResult = instance);
 
   return NS_OK;
 }
 
 nsTextNode::nsTextNode(already_AddRefed<nsINodeInfo> aNodeInfo)
   : nsGenericDOMDataNode(aNodeInfo)
 {
-  NS_ABORT_IF_FALSE(mNodeInfo->NodeType() == nsIDOMNode::TEXT_NODE,
-                    "Bad NodeType in aNodeInfo");
 }
 
 nsTextNode::~nsTextNode()
 {
 }
 
 NS_IMPL_ADDREF_INHERITED(nsTextNode, nsGenericDOMDataNode)
 NS_IMPL_RELEASE_INHERITED(nsTextNode, nsGenericDOMDataNode)
@@ -159,16 +157,42 @@ DOMCI_NODE_DATA(Text, nsTextNode)
 // QueryInterface implementation for nsTextNode
 NS_INTERFACE_TABLE_HEAD(nsTextNode)
   NS_NODE_INTERFACE_TABLE3(nsTextNode, nsIDOMNode, nsIDOMText,
                            nsIDOMCharacterData)
   NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(nsTextNode)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(Text)
 NS_INTERFACE_MAP_END_INHERITING(nsGenericDOMDataNode)
 
+NS_IMETHODIMP
+nsTextNode::GetNodeName(nsAString& aNodeName)
+{
+  aNodeName.AssignLiteral("#text");
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsTextNode::GetNodeValue(nsAString& aNodeValue)
+{
+  return nsGenericDOMDataNode::GetNodeValue(aNodeValue);
+}
+
+NS_IMETHODIMP
+nsTextNode::SetNodeValue(const nsAString& aNodeValue)
+{
+  return nsGenericDOMDataNode::SetNodeValue(aNodeValue);
+}
+
+NS_IMETHODIMP
+nsTextNode::GetNodeType(PRUint16* aNodeType)
+{
+  *aNodeType = (PRUint16)nsIDOMNode::TEXT_NODE;
+  return NS_OK;
+}
+
 PRBool
 nsTextNode::IsNodeOfType(PRUint32 aFlags) const
 {
   return !(aFlags & ~(eCONTENT | eTEXT | eDATA_NODE));
 }
 
 nsGenericDOMDataNode*
 nsTextNode::CloneDataNode(nsINodeInfo *aNodeInfo, PRBool aCloneText) const
--- a/content/base/src/nsTextNode.h
+++ b/content/base/src/nsTextNode.h
@@ -58,30 +58,27 @@ class nsTextNode : public nsGenericDOMDa
 public:
   nsTextNode(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~nsTextNode();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE(nsGenericDOMDataNode::)
+  NS_IMPL_NSIDOMNODE_USING_GENERIC_DOM_DATA
 
   // nsIDOMCharacterData
   NS_FORWARD_NSIDOMCHARACTERDATA(nsGenericDOMDataNode::)
 
   // nsIDOMText
   NS_FORWARD_NSIDOMTEXT(nsGenericDOMDataNode::)
 
-  // nsINode
+  // nsIContent
   virtual PRBool IsNodeOfType(PRUint32 aFlags) const;
 
-  virtual nsGenericDOMDataNode* CloneDataNode(nsINodeInfo *aNodeInfo,
-                                              PRBool aCloneText) const;
-
   nsresult BindToAttribute(nsIAttribute* aAttr);
   nsresult UnbindFromAttribute();
 
   virtual nsXPCClassInfo* GetClassInfo();
 
 #ifdef DEBUG
   virtual void List(FILE* out, PRInt32 aIndent) const;
   virtual void DumpContent(FILE* out, PRInt32 aIndent, PRBool aDumpAll) const;
--- a/content/base/src/nsTraversal.cpp
+++ b/content/base/src/nsTraversal.cpp
@@ -75,24 +75,53 @@ nsTraversal::~nsTraversal()
 nsresult nsTraversal::TestNode(nsINode* aNode, PRInt16* _filtered)
 {
     NS_ENSURE_TRUE(!mInAcceptNode, NS_ERROR_DOM_INVALID_STATE_ERR);
 
     nsresult rv;
 
     *_filtered = nsIDOMNodeFilter::FILTER_SKIP;
 
-    PRUint16 nodeType = aNode->NodeType();
+    PRUint16 nodeType = 0;
+    // Check the most common cases
+    if (aNode->IsElement()) {
+        nodeType = nsIDOMNode::ELEMENT_NODE;
+    }
+    else if (aNode->IsNodeOfType(nsINode::eCONTENT)) {
+        nsIAtom* tag = static_cast<nsIContent*>(aNode)->Tag();
+        if (tag == nsGkAtoms::textTagName) {
+            nodeType = nsIDOMNode::TEXT_NODE;
+        }
+        else if (tag == nsGkAtoms::cdataTagName) {
+            nodeType = nsIDOMNode::CDATA_SECTION_NODE;
+        }
+        else if (tag == nsGkAtoms::commentTagName) {
+            nodeType = nsIDOMNode::COMMENT_NODE;
+        }
+        else if (tag == nsGkAtoms::processingInstructionTagName) {
+            nodeType = nsIDOMNode::PROCESSING_INSTRUCTION_NODE;
+        }
+    }
+
+    nsCOMPtr<nsIDOMNode> domNode;
+    if (!nodeType) {
+        domNode = do_QueryInterface(aNode);
+        rv = domNode->GetNodeType(&nodeType);
+        NS_ENSURE_SUCCESS(rv, rv);
+    }
 
     if (nodeType <= 12 && !((1 << (nodeType-1)) & mWhatToShow)) {
         return NS_OK;
     }
 
     if (mFilter) {
-        nsCOMPtr<nsIDOMNode> domNode = do_QueryInterface(aNode);
+        if (!domNode) {
+            domNode = do_QueryInterface(aNode);
+        }
+
         mInAcceptNode = PR_TRUE;
         rv = mFilter->AcceptNode(domNode, _filtered);
         mInAcceptNode = PR_FALSE;
         return rv;
     }
 
     *_filtered = nsIDOMNodeFilter::FILTER_ACCEPT;
     return NS_OK;
--- a/content/base/test/test_bug352728.html
+++ b/content/base/test/test_bug352728.html
@@ -48,17 +48,17 @@ function testCharacterData(aNode, aText)
 function testComment(aText, aShouldSucceed)
 {
   try {
     var comment = document.createComment(aText);
     var types = [ Comment, CharacterData, Node ];
     checkTypes(comment, "comment", types);
 
     var interfaces = [ "nsIDOMComment", "nsIDOMCharacterData", "nsIDOMNode",
-                       "nsIDOMEventTarget" ];
+                       "nsIDOM3Node", "nsIDOMEventTarget" ];
     checkInterfaces(comment, "comment", interfaces);
 
     testCharacterData(comment, aText);
     is(comment.nodeName, "#comment", "Check nodeName");
     is(comment.nodeType, Node.COMMENT_NODE, "Check nodeType");
 
     if (!aShouldSucceed) {
       ok(0, "Invalid comment creation",
--- a/content/base/test/test_bug352728.xhtml
+++ b/content/base/test/test_bug352728.xhtml
@@ -72,17 +72,17 @@ function testCharacterData(aNode, aText)
 function testComment(aText, aShouldSucceed)
 {
   try {
     var comment = document.createComment(aText);
     var types = [ Comment, CharacterData, Node ];
     checkTypes(comment, "comment", types);
 
     var interfaces = [ "nsIDOMComment", "nsIDOMCharacterData", "nsIDOMNode",
-                       "nsIDOMEventTarget" ];
+                       "nsIDOM3Node", "nsIDOMEventTarget" ];
     checkInterfaces(comment, "comment", interfaces);
 
     testCharacterData(comment, aText);
     is(comment.nodeName, "#comment", "Check nodeName");
     is(comment.nodeType, Node.COMMENT_NODE, "Check nodeType");
 
     if (!aShouldSucceed) {
       ok(0, "Invalid comment creation",
@@ -100,17 +100,17 @@ function testComment(aText, aShouldSucce
 function testCDATASection(aText, aShouldSucceed)
 {
   try {
     var cdataSection = document.createCDATASection(aText);
     var types = [ CDATASection, CharacterData, Node ];
     checkTypes(cdataSection, "CDATA section", types);
 
     var interfaces = [ "nsIDOMCDATASection", "nsIDOMCharacterData",
-                       "nsIDOMNode", "nsIDOMEventTarget" ];
+                       "nsIDOMNode", "nsIDOM3Node", "nsIDOMEventTarget" ];
     checkInterfaces(cdataSection, "CDATA section", interfaces);
 
     testCharacterData(cdataSection, aText);
     is(cdataSection.nodeName, "#cdata-section", "Check nodeName");
     is(cdataSection.nodeType, Node.CDATA_SECTION_NODE, "Check nodeType");
 
     if (!aShouldSucceed) {
       ok(0, "Invalid CDATA section creation",
@@ -131,17 +131,17 @@ function testCDATASection(aText, aShould
 function testPI(aTarget, aData, aShouldSucceed, aReason)
 {
   try {
     var pi = document.createProcessingInstruction(aTarget, aData);
     var types = [ ProcessingInstruction, Node ];
     checkTypes(pi, "processing instruction", types);
 
     var interfaces = [ "nsIDOMProcessingInstruction", "nsIDOMNode",
-                       "nsIDOMEventTarget" ];
+                       "nsIDOM3Node", "nsIDOMEventTarget" ];
     checkInterfaces(pi, "processing instruction", interfaces);
 
     is(pi.target, aTarget, "Check target");
     is(pi.data, aData, "Check data");
     is(pi.nodeName, aTarget, "Check nodeName");
     is(pi.nodeValue, aData, "Check nodeValue");
     is(pi.localName, null, "Check localName")
     is(pi.namespaceURI, null, "Check namespaceURI");
--- a/content/html/content/src/nsHTMLAudioElement.cpp
+++ b/content/html/content/src/nsHTMLAudioElement.cpp
@@ -79,18 +79,17 @@ NS_NewHTMLAudioElement(already_AddRefed<
    */
   nsCOMPtr<nsINodeInfo> nodeInfo(aNodeInfo);
   if (!nodeInfo) {
     nsCOMPtr<nsIDocument> doc =
       do_QueryInterface(nsContentUtils::GetDocumentFromCaller());
     NS_ENSURE_TRUE(doc, nsnull);
 
     nodeInfo = doc->NodeInfoManager()->GetNodeInfo(nsGkAtoms::audio, nsnull,
-                                                   kNameSpaceID_XHTML,
-                                                   nsIDOMNode::ELEMENT_NODE);
+                                                   kNameSpaceID_XHTML);
     NS_ENSURE_TRUE(nodeInfo, nsnull);
   }
 
   return new nsHTMLAudioElement(nodeInfo.forget(), aFromParser);
 }
 
 NS_IMPL_ADDREF_INHERITED(nsHTMLAudioElement, nsHTMLMediaElement)
 NS_IMPL_RELEASE_INHERITED(nsHTMLAudioElement, nsHTMLMediaElement)
--- a/content/html/content/src/nsHTMLImageElement.cpp
+++ b/content/html/content/src/nsHTMLImageElement.cpp
@@ -165,18 +165,17 @@ NS_NewHTMLImageElement(already_AddRefed<
    */
   nsCOMPtr<nsINodeInfo> nodeInfo(aNodeInfo);
   if (!nodeInfo) {
     nsCOMPtr<nsIDocument> doc =
       do_QueryInterface(nsContentUtils::GetDocumentFromCaller());
     NS_ENSURE_TRUE(doc, nsnull);
 
     nodeInfo = doc->NodeInfoManager()->GetNodeInfo(nsGkAtoms::img, nsnull,
-                                                   kNameSpaceID_XHTML,
-                                                   nsIDOMNode::ELEMENT_NODE);
+                                                   kNameSpaceID_XHTML);
     NS_ENSURE_TRUE(nodeInfo, nsnull);
   }
 
   return new nsHTMLImageElement(nodeInfo.forget());
 }
 
 nsHTMLImageElement::nsHTMLImageElement(already_AddRefed<nsINodeInfo> aNodeInfo)
   : nsGenericHTMLElement(aNodeInfo)
--- a/content/html/content/src/nsHTMLOptionElement.cpp
+++ b/content/html/content/src/nsHTMLOptionElement.cpp
@@ -102,18 +102,17 @@ NS_NewHTMLOptionElement(already_AddRefed
    */
   nsCOMPtr<nsINodeInfo> nodeInfo(aNodeInfo);
   if (!nodeInfo) {
     nsCOMPtr<nsIDocument> doc =
       do_QueryInterface(nsContentUtils::GetDocumentFromCaller());
     NS_ENSURE_TRUE(doc, nsnull);
 
     nodeInfo = doc->NodeInfoManager()->GetNodeInfo(nsGkAtoms::option, nsnull,
-                                                   kNameSpaceID_XHTML,
-                                                   nsIDOMNode::ELEMENT_NODE);
+                                                   kNameSpaceID_XHTML);
     NS_ENSURE_TRUE(nodeInfo, nsnull);
   }
 
   return new nsHTMLOptionElement(nodeInfo.forget());
 }
 
 nsHTMLOptionElement::nsHTMLOptionElement(already_AddRefed<nsINodeInfo> aNodeInfo)
   : nsGenericHTMLElement(aNodeInfo),
--- a/content/html/content/src/nsTextEditorState.cpp
+++ b/content/html/content/src/nsTextEditorState.cpp
@@ -1557,18 +1557,17 @@ nsTextEditorState::CreateRootNode()
   NS_ENSURE_TRUE(shell, NS_ERROR_FAILURE);
 
   nsIDocument *doc = shell->GetDocument();
   NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
 
   // Now create a DIV and add it to the anonymous content child list.
   nsCOMPtr<nsINodeInfo> nodeInfo;
   nodeInfo = doc->NodeInfoManager()->GetNodeInfo(nsGkAtoms::div, nsnull,
-                                                 kNameSpaceID_XHTML,
-                                                 nsIDOMNode::ELEMENT_NODE);
+                                                 kNameSpaceID_XHTML);
   NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
 
   nsresult rv = NS_NewHTMLElement(getter_AddRefs(mRootNode), nodeInfo.forget(),
                                   NOT_FROM_PARSER);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Set the necessary classes on the text control. We use class values
   // instead of a 'style' attribute so that the style comes from a user-agent
@@ -1635,18 +1634,17 @@ be called if @placeholder is the empty s
 
   nsresult rv;
   nsCOMPtr<nsIContent> placeholderText;
 
   // Create a DIV for the placeholder
   // and add it to the anonymous content child list
   nsCOMPtr<nsINodeInfo> nodeInfo;
   nodeInfo = pNodeInfoManager->GetNodeInfo(nsGkAtoms::div, nsnull,
-                                           kNameSpaceID_XHTML,
-                                           nsIDOMNode::ELEMENT_NODE);
+                                           kNameSpaceID_XHTML);
   NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
 
   rv = NS_NewHTMLElement(getter_AddRefs(mPlaceholderDiv), nodeInfo.forget(),
                          NOT_FROM_PARSER);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Create the text node for the placeholder text before doing anything else
   rv = NS_NewTextNode(getter_AddRefs(placeholderText), pNodeInfoManager);
--- a/content/html/content/test/test_bug389797.html
+++ b/content/html/content/test/test_bug389797.html
@@ -27,17 +27,18 @@ var interfacesNonClassinfo = {};
 function getClassName(tag) {
   return "HTML" + classInfos[tag] + "Element";
 }
 
 function HTML_TAG(aTagName, aImplClass) {
   allTags.push(aTagName);
   classInfos[aTagName] = aImplClass;
   interfaces[aTagName] =
-    [ "nsIDOMNSElement",
+    [ "nsIDOM3Node",
+      "nsIDOMNSElement",
       "nsIDOMEventTarget",
       "nsIDOMNSEventTarget",
       "nsIDOMNSHTMLElement",
       "nsIDOMElementCSSInlineStyle",
       "nsIDOMNodeSelector" ];
 
   // Some interfaces don't appear in classinfo because other interfaces that
   // inherit from them do.
--- a/content/html/document/src/ImageDocument.cpp
+++ b/content/html/document/src/ImageDocument.cpp
@@ -646,18 +646,17 @@ ImageDocument::CreateSyntheticDocument()
   Element* body = GetBodyElement();
   if (!body) {
     NS_WARNING("no body on image document!");
     return NS_ERROR_FAILURE;
   }
 
   nsCOMPtr<nsINodeInfo> nodeInfo;
   nodeInfo = mNodeInfoManager->GetNodeInfo(nsGkAtoms::img, nsnull,
-                                           kNameSpaceID_XHTML,
-                                           nsIDOMNode::ELEMENT_NODE);
+                                           kNameSpaceID_XHTML);
   NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
 
   mImageContent = NS_NewHTMLImageElement(nodeInfo.forget());
   if (!mImageContent) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
   nsCOMPtr<nsIImageLoadingContent> imageLoader = do_QueryInterface(mImageContent);
   NS_ENSURE_TRUE(imageLoader, NS_ERROR_UNEXPECTED);
--- a/content/html/document/src/MediaDocument.cpp
+++ b/content/html/document/src/MediaDocument.cpp
@@ -232,45 +232,42 @@ MediaDocument::StartDocumentLoad(const c
 nsresult
 MediaDocument::CreateSyntheticDocument()
 {
   // Synthesize an empty html document
   nsresult rv;
 
   nsCOMPtr<nsINodeInfo> nodeInfo;
   nodeInfo = mNodeInfoManager->GetNodeInfo(nsGkAtoms::html, nsnull,
-                                           kNameSpaceID_XHTML,
-                                           nsIDOMNode::ELEMENT_NODE);
+                                           kNameSpaceID_XHTML);
   NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
 
   nsRefPtr<nsGenericHTMLElement> root = NS_NewHTMLHtmlElement(nodeInfo.forget());
   if (!root) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   NS_ASSERTION(GetChildCount() == 0, "Shouldn't have any kids");
   rv = AppendChildTo(root, PR_FALSE);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nodeInfo = mNodeInfoManager->GetNodeInfo(nsGkAtoms::head, nsnull,
-                                           kNameSpaceID_XHTML,
-                                           nsIDOMNode::ELEMENT_NODE);
+                                           kNameSpaceID_XHTML);
   NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
 
   // Create a <head> so our title has somewhere to live
   nsRefPtr<nsGenericHTMLElement> head = NS_NewHTMLHeadElement(nodeInfo.forget());
   if (!head) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   root->AppendChildTo(head, PR_FALSE);
 
   nodeInfo = mNodeInfoManager->GetNodeInfo(nsGkAtoms::body, nsnull,
-                                           kNameSpaceID_XHTML,
-                                           nsIDOMNode::ELEMENT_NODE);
+                                           kNameSpaceID_XHTML);
   NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
 
   nsRefPtr<nsGenericHTMLElement> body = NS_NewHTMLBodyElement(nodeInfo.forget());
   if (!body) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   root->AppendChildTo(body, PR_FALSE);
--- a/content/html/document/src/PluginDocument.cpp
+++ b/content/html/document/src/PluginDocument.cpp
@@ -293,18 +293,17 @@ PluginDocument::CreateSyntheticPluginDoc
   NS_NAMED_LITERAL_STRING(zero, "0");
   body->SetAttr(kNameSpaceID_None, nsGkAtoms::marginwidth, zero, PR_FALSE);
   body->SetAttr(kNameSpaceID_None, nsGkAtoms::marginheight, zero, PR_FALSE);
 
 
   // make plugin content
   nsCOMPtr<nsINodeInfo> nodeInfo;
   nodeInfo = mNodeInfoManager->GetNodeInfo(nsGkAtoms::embed, nsnull,
-                                           kNameSpaceID_XHTML,
-                                           nsIDOMNode::ELEMENT_NODE);
+                                           kNameSpaceID_XHTML);
   NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
   rv = NS_NewHTMLElement(getter_AddRefs(mPluginContent), nodeInfo.forget(),
                          NOT_FROM_PARSER);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // make it a named element
   mPluginContent->SetAttr(kNameSpaceID_None, nsGkAtoms::name,
                           NS_LITERAL_STRING("plugin"), PR_FALSE);
--- a/content/html/document/src/VideoDocument.cpp
+++ b/content/html/document/src/VideoDocument.cpp
@@ -107,18 +107,17 @@ VideoDocument::CreateSyntheticVideoDocum
   if (!body) {
     NS_WARNING("no body on video document!");
     return NS_ERROR_FAILURE;
   }
 
   // make content
   nsCOMPtr<nsINodeInfo> nodeInfo;
   nodeInfo = mNodeInfoManager->GetNodeInfo(nsGkAtoms::video, nsnull,
-                                           kNameSpaceID_XHTML,
-                                           nsIDOMNode::ELEMENT_NODE);
+                                           kNameSpaceID_XHTML);
   NS_ENSURE_TRUE(nodeInfo, NS_ERROR_FAILURE);
 
   nsRefPtr<nsHTMLMediaElement> element =
     static_cast<nsHTMLMediaElement*>(NS_NewHTMLVideoElement(nodeInfo.forget(),
                                                             NOT_FROM_PARSER));
   if (!element)
     return NS_ERROR_OUT_OF_MEMORY;
   element->SetAutoplay(PR_TRUE);
--- a/content/html/document/src/nsHTMLContentSink.cpp
+++ b/content/html/document/src/nsHTMLContentSink.cpp
@@ -529,32 +529,30 @@ HTMLContentSink::CreateContentObject(con
   // Find/create atom for the tag name
 
   nsCOMPtr<nsINodeInfo> nodeInfo;
 
   if (aNodeType == eHTMLTag_userdefined) {
     nsAutoString lower;
     nsContentUtils::ASCIIToLower(aNode.GetText(), lower);
     nsCOMPtr<nsIAtom> name = do_GetAtom(lower);
-    nodeInfo = mNodeInfoManager->GetNodeInfo(name, nsnull, kNameSpaceID_XHTML,
-                                             nsIDOMNode::ELEMENT_NODE);
+    nodeInfo = mNodeInfoManager->GetNodeInfo(name, nsnull, kNameSpaceID_XHTML);
   }
   else if (mNodeInfoCache[aNodeType]) {
     nodeInfo = mNodeInfoCache[aNodeType];
   }
   else {
     nsIParserService *parserService = nsContentUtils::GetParserService();
     if (!parserService)
       return nsnull;
 
     nsIAtom *name = parserService->HTMLIdToAtomTag(aNodeType);
     NS_ASSERTION(name, "What? Reverse mapping of id to string broken!!!");
 
-    nodeInfo = mNodeInfoManager->GetNodeInfo(name, nsnull, kNameSpaceID_XHTML,
-                                             nsIDOMNode::ELEMENT_NODE);
+    nodeInfo = mNodeInfoManager->GetNodeInfo(name, nsnull, kNameSpaceID_XHTML);
     NS_IF_ADDREF(mNodeInfoCache[aNodeType] = nodeInfo);
   }
 
   NS_ENSURE_TRUE(nodeInfo, nsnull);
 
   // Make the content object
   return CreateHTMLElement(aNodeType, nodeInfo.forget(), FROM_PARSER_NETWORK);
 }
@@ -1599,35 +1597,33 @@ HTMLContentSink::Init(nsIDocument* aDoc,
 
 
   // Changed from 8192 to greatly improve page loading performance on
   // large pages.  See bugzilla bug 77540.
   mMaxTextRun = Preferences::GetInt("content.maxtextrun", 8191);
 
   nsCOMPtr<nsINodeInfo> nodeInfo;
   nodeInfo = mNodeInfoManager->GetNodeInfo(nsGkAtoms::html, nsnull,
-                                           kNameSpaceID_XHTML,
-                                           nsIDOMNode::ELEMENT_NODE);
+                                           kNameSpaceID_XHTML);
   NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
 
   // Make root part
   mRoot = NS_NewHTMLHtmlElement(nodeInfo.forget());
   if (!mRoot) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   NS_ASSERTION(mDocument->GetChildCount() == 0,
                "Document should have no kids here!");
   rv = mDocument->AppendChildTo(mRoot, PR_FALSE);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Make head part
   nodeInfo = mNodeInfoManager->GetNodeInfo(nsGkAtoms::head,
-                                           nsnull, kNameSpaceID_XHTML,
-                                           nsIDOMNode::ELEMENT_NODE);
+                                           nsnull, kNameSpaceID_XHTML);
   NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
 
   mHead = NS_NewHTMLHeadElement(nodeInfo.forget());
   if (NS_FAILED(rv)) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   mRoot->AppendChildTo(mHead, PR_FALSE);
@@ -2594,19 +2590,17 @@ nsresult
 HTMLContentSink::ProcessLINKTag(const nsIParserNode& aNode)
 {
   nsresult  result = NS_OK;
 
   if (mCurrentContext) {
     // Create content object
     nsCOMPtr<nsIContent> element;
     nsCOMPtr<nsINodeInfo> nodeInfo;
-    nodeInfo = mNodeInfoManager->GetNodeInfo(nsGkAtoms::link, nsnull,
-                                             kNameSpaceID_XHTML,
-                                             nsIDOMNode::ELEMENT_NODE);
+    nodeInfo = mNodeInfoManager->GetNodeInfo(nsGkAtoms::link, nsnull, kNameSpaceID_XHTML);
 
     result = NS_NewHTMLElement(getter_AddRefs(element), nodeInfo.forget(),
                                NOT_FROM_PARSER);
     NS_ENSURE_SUCCESS(result, result);
 
     nsCOMPtr<nsIStyleSheetLinkingElement> ssle(do_QueryInterface(element));
 
     if (ssle) {
--- a/content/html/document/src/nsHTMLFragmentContentSink.cpp
+++ b/content/html/document/src/nsHTMLFragmentContentSink.cpp
@@ -362,35 +362,33 @@ nsHTMLFragmentContentSink::OpenContainer
     nsCOMPtr<nsINodeInfo> nodeInfo;
 
     if (nodeType == eHTMLTag_userdefined) {
       nsAutoString lower;
       nsContentUtils::ASCIIToLower(aNode.GetText(), lower);
       nsCOMPtr<nsIAtom> name = do_GetAtom(lower);
       nodeInfo = mNodeInfoManager->GetNodeInfo(name, 
                                                nsnull, 
-                                               kNameSpaceID_XHTML,
-                                               nsIDOMNode::ELEMENT_NODE);
+                                               kNameSpaceID_XHTML);
       NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
     }
     else if (mNodeInfoCache[nodeType]) {
       nodeInfo = mNodeInfoCache[nodeType];
     }
     else {
       nsIParserService* parserService = nsContentUtils::GetParserService();
       if (!parserService)
         return NS_ERROR_OUT_OF_MEMORY;
 
       nsIAtom *name = parserService->HTMLIdToAtomTag(nodeType);
       NS_ASSERTION(name, "This should not happen!");
 
       nodeInfo = mNodeInfoManager->GetNodeInfo(name, 
                                                nsnull, 
-                                               kNameSpaceID_XHTML,
-                                               nsIDOMNode::ELEMENT_NODE);
+                                               kNameSpaceID_XHTML);
       NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
 
       NS_ADDREF(mNodeInfoCache[nodeType] = nodeInfo);
     }
 
     content =
       CreateHTMLElement(nodeType, nodeInfo.forget(), NOT_FROM_PARSER).get();
     NS_ENSURE_TRUE(content, NS_ERROR_OUT_OF_MEMORY);
@@ -458,30 +456,28 @@ nsHTMLFragmentContentSink::AddLeaf(const
 
         nsCOMPtr<nsINodeInfo> nodeInfo;
 
         if (nodeType == eHTMLTag_userdefined) {
           nsAutoString lower;
           nsContentUtils::ASCIIToLower(aNode.GetText(), lower);
           nsCOMPtr<nsIAtom> name = do_GetAtom(lower);
           nodeInfo = mNodeInfoManager->GetNodeInfo(name, nsnull,
-                                                   kNameSpaceID_XHTML,
-                                                   nsIDOMNode::ELEMENT_NODE);
+                                                   kNameSpaceID_XHTML);
           NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
         }
         else if (mNodeInfoCache[nodeType]) {
           nodeInfo = mNodeInfoCache[nodeType];
         }
         else {
           nsIAtom *name = parserService->HTMLIdToAtomTag(nodeType);
           NS_ASSERTION(name, "This should not happen!");
 
           nodeInfo = mNodeInfoManager->GetNodeInfo(name, nsnull,
-                                                   kNameSpaceID_XHTML,
-                                                   nsIDOMNode::ELEMENT_NODE);
+                                                   kNameSpaceID_XHTML);
           NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
           NS_ADDREF(mNodeInfoCache[nodeType] = nodeInfo);
         }
 
         content =
           CreateHTMLElement(nodeType, nodeInfo.forget(), NOT_FROM_PARSER);
         NS_ENSURE_TRUE(content, NS_ERROR_OUT_OF_MEMORY);
 
@@ -943,17 +939,23 @@ nsresult
 nsHTMLParanoidFragmentSink::NameFromNode(const nsIParserNode& aNode,
                                          nsIAtom **aResult)
 {
   nsresult rv;
   eHTMLTags type = (eHTMLTags)aNode.GetNodeType();
   
   *aResult = nsnull;
   if (type == eHTMLTag_userdefined) {
-    *aResult = NS_NewAtom(aNode.GetText());
+    nsCOMPtr<nsINodeInfo> nodeInfo;
+    rv =
+      mNodeInfoManager->GetNodeInfo(aNode.GetText(), nsnull,
+                                    kNameSpaceID_XHTML,
+                                    getter_AddRefs(nodeInfo));
+    NS_ENSURE_SUCCESS(rv, rv);
+    NS_IF_ADDREF(*aResult = nodeInfo->NameAtom());
   } else {
     rv = NameFromType(type, aResult);
   }
   return rv;
 }
 
 void
 nsHTMLParanoidFragmentSink::AllowStyles()
--- a/content/svg/content/src/nsSVGElement.cpp
+++ b/content/svg/content/src/nsSVGElement.cpp
@@ -1359,18 +1359,17 @@ nsSVGElement::AddMappedSVGValue(nsIAtom*
 
   if (aNamespaceID == kNameSpaceID_None) {
     rv = mMappedAttributes.SetAndTakeAttr(aName, attrVal);
     NS_ENSURE_SUCCESS(rv, rv);
   }
   else {
     nsCOMPtr<nsINodeInfo> ni;
     ni = mNodeInfo->NodeInfoManager()->GetNodeInfo(aName, nsnull,
-                                                   aNamespaceID,
-                                                   nsIDOMNode::ATTRIBUTE_NODE);
+                                                   aNamespaceID);
     NS_ENSURE_TRUE(ni, NS_ERROR_OUT_OF_MEMORY);
 
     rv = mMappedAttributes.SetAndTakeAttr(ni, attrVal);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   return NS_OK;
 }
--- a/content/svg/content/src/nsSVGUseElement.cpp
+++ b/content/svg/content/src/nsSVGUseElement.cpp
@@ -334,19 +334,17 @@ nsSVGUseElement::CreateAnonymousContent(
     if (!document)
       return nsnull;
 
     nsNodeInfoManager *nodeInfoManager = document->NodeInfoManager();
     if (!nodeInfoManager)
       return nsnull;
 
     nsCOMPtr<nsINodeInfo> nodeInfo;
-    nodeInfo = nodeInfoManager->GetNodeInfo(nsGkAtoms::svg, nsnull,
-                                            kNameSpaceID_SVG,
-                                            nsIDOMNode::ELEMENT_NODE);
+    nodeInfo = nodeInfoManager->GetNodeInfo(nsGkAtoms::svg, nsnull, kNameSpaceID_SVG);
     if (!nodeInfo)
       return nsnull;
 
     nsCOMPtr<nsIContent> svgNode;
     NS_NewSVGSVGElement(getter_AddRefs(svgNode), nodeInfo.forget(),
                         NOT_FROM_PARSER);
 
     if (!svgNode)
--- a/content/test/unit/head_content.js
+++ b/content/test/unit/head_content.js
@@ -45,16 +45,17 @@ const nsIProperties        = I.nsIProper
 const nsIFileInputStream   = I.nsIFileInputStream;
 const nsIInputStream       = I.nsIInputStream;
 
 const nsIDOMParser         = I.nsIDOMParser;
 const nsIDOMSerializer     = I.nsIDOMSerializer;
 const nsIDOMDocument       = I.nsIDOMDocument;
 const nsIDOMElement        = I.nsIDOMElement;
 const nsIDOMNode           = I.nsIDOMNode;
+const nsIDOM3Node          = I.nsIDOM3Node;
 const nsIDOMCharacterData  = I.nsIDOMCharacterData;
 const nsIDOMAttr           = I.nsIDOMAttr;
 const nsIDOMNodeList       = I.nsIDOMNodeList;
 const nsIDOMXULElement     = I.nsIDOMXULElement;
 const nsIDOMProcessingInstruction = I.nsIDOMProcessingInstruction;
 
 function DOMParser() {
   var parser = C["@mozilla.org/xmlextras/domparser;1"].createInstance(nsIDOMParser);
--- a/content/test/unit/test_isequalnode.js
+++ b/content/test/unit/test_isequalnode.js
@@ -399,16 +399,17 @@ function test_isEqualNode_null()
     }
   }
 }
 
 
 // UTILITY FUNCTIONS
 
 function n(node)  { return node ? node.QueryInterface(nsIDOMNode) : null; }
+function n3(node) { return node ? node.QueryInterface(nsIDOM3Node) : null; }
 function el(node) { return node ? node.QueryInterface(nsIDOMElement) : null; }
 function at(node) { return node ? node.QueryInterface(nsIDOMAttr) : null; }
 
 
 // TESTING FUNCTIONS
 
 /**
  * Compares the first and third (zero-indexed) child nodes of the element
@@ -428,25 +429,31 @@ function equality_check_kids(parentId, a
   if (areEqual)
     check_eq_nodes(kid1, kid2);
   else
     check_neq_nodes(kid1, kid2);
 }
 
 function check_eq_nodes(n1, n2)
 {
+  n1 = n3(n1);
+  n2 = n3(n2);
+
   if (n1 && !n1.isEqualNode(n2))
     do_throw(n1 + " should be equal to " + n2);
   if (n2 && !n2.isEqualNode(n1))
     do_throw(n2 + " should be equal to " + n1);
   if (!n1 && !n2)
     do_throw("nodes both null!");
 }
 
 function check_neq_nodes(n1, n2)
 {
+  n1 = n3(n1);
+  n2 = n3(n2);
+
   if (n1 && n1.isEqualNode(n2))
     do_throw(n1 + " should not be equal to " + n2);
   if (n2 && n2.isEqualNode(n1))
     do_throw(n2 + " should not be equal to " + n1);
   if (!n1 && !n2)
     do_throw("n1 and n2 both null!");
 }
--- a/content/test/unit/test_range.js
+++ b/content/test/unit/test_range.js
@@ -61,16 +61,17 @@ function isWhitespace(aNode) {
  * Create a DocumentFragment with cloned children equaling a node's children.
  *
  * @param aNode The node to copy from.
  *
  * @return DocumentFragment node.
  */
 function getFragment(aNode) {
   var frag = aNode.ownerDocument.createDocumentFragment();
+  do_check_true(frag instanceof C_i.nsIDOM3Node);
   for (var i = 0; i < aNode.childNodes.length; i++) {
     frag.appendChild(aNode.childNodes.item(i).cloneNode(true));
   }
   return frag;
 }
 
 // Goodies from head_content.js
 const serializer = new DOMSerializer();
@@ -274,17 +275,17 @@ function run_extract_test() {
     do_check_eq(baseExtract.nextSibling, null);
 
     /* We do all our tests on DOM document fragments, derived from the test
        element's children.  This lets us rip the various fragments to shreds,
        while preserving the original elements so we can make more copies of
        them.
 
        After the range's extraction or deletion is done, we use
-       nsIDOMNode.isEqualNode() between the altered source fragment and the
+       nsIDOM3Node.isEqualNode() between the altered source fragment and the
        result fragment.  We also run isEqualNode() between the extracted
        fragment and the fragment from the baseExtract node.  If they are not
        equal, we have failed a test.
 
        We also have to ensure the original nodes on the end points of the
        range are still in the source fragment.  This is bug 332148.  The nodes
        may not be replaced with equal but separate nodes.  The range extraction
        may alter these nodes - in the case of text containers, they will - but
@@ -315,16 +316,18 @@ function run_extract_test() {
     dump("Ensure the original nodes weren't extracted - test " + i + "\n\n");
     var walker = doc.createTreeWalker(baseFrag,
 				      C_i.nsIDOMNodeFilter.SHOW_ALL,
 				      null,
 				      false);
     var foundStart = false;
     var foundEnd = false;
     do {
+      do_check_true(walker.currentNode instanceof C_i.nsIDOM3Node);
+
       if (walker.currentNode.isSameNode(startContainer)) {
         foundStart = true;
       }
 
       if (walker.currentNode.isSameNode(endContainer)) {
         // An end container node should not come before the start container node.
         do_check_true(foundStart);
         foundEnd = true;
@@ -349,16 +352,18 @@ function run_extract_test() {
     dump("Ensure the original nodes weren't deleted - test " + i + "\n\n");
     walker = doc.createTreeWalker(baseFrag,
                                   C_i.nsIDOMNodeFilter.SHOW_ALL,
                                   null,
                                   false);
     foundStart = false;
     foundEnd = false;
     do {
+      do_check_true(walker.currentNode instanceof C_i.nsIDOM3Node);
+
       if (walker.currentNode.isSameNode(startContainer)) {
         foundStart = true;
       }
 
       if (walker.currentNode.isSameNode(endContainer)) {
         // An end container node should not come before the start container node.
         do_check_true(foundStart);
         foundEnd = true;
--- a/content/xbl/src/nsXBLContentSink.cpp
+++ b/content/xbl/src/nsXBLContentSink.cpp
@@ -949,18 +949,17 @@ nsXBLContentSink::AddAttributesToXULProt
     nsContentUtils::SplitExpatName(aAtts[i * 2], getter_AddRefs(prefix),
                                    getter_AddRefs(localName), &nameSpaceID);
 
     if (nameSpaceID == kNameSpaceID_None) {
       attrs[i].mName.SetTo(localName);
     }
     else {
       nsCOMPtr<nsINodeInfo> ni;
-      ni = mNodeInfoManager->GetNodeInfo(localName, prefix, nameSpaceID,
-                                         nsIDOMNode::ATTRIBUTE_NODE);
+      ni = mNodeInfoManager->GetNodeInfo(localName, prefix, nameSpaceID);
       attrs[i].mName.SetTo(ni);
     }
     
     rv = aElement->SetAttrAt(i, nsDependentString(aAtts[i * 2 + 1]),
                              mDocumentURI); 
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
--- a/content/xbl/src/nsXBLService.cpp
+++ b/content/xbl/src/nsXBLService.cpp
@@ -68,16 +68,17 @@
 #include "nsIDOMNodeList.h"
 #include "nsXBLContentSink.h"
 #include "nsXBLBinding.h"
 #include "nsXBLPrototypeBinding.h"
 #include "nsXBLDocumentInfo.h"
 #include "nsCRT.h"
 #include "nsContentUtils.h"
 #include "nsSyncLoadService.h"
+#include "nsIDOM3Node.h"
 #include "nsContentPolicyUtils.h"
 #include "nsTArray.h"
 #include "nsContentErrors.h"
 
 #include "nsIPresShell.h"
 #include "nsIDocumentObserver.h"
 #include "nsFrameManager.h"
 #include "nsStyleContext.h"
@@ -945,46 +946,52 @@ nsXBLService::GetBinding(nsIContent* aBo
           extends.Cut(0, offset+1);
           display = extends;
         }
       }
 
       nsAutoString nameSpace;
 
       if (!prefix.IsEmpty()) {
-        child->LookupNamespaceURI(prefix, nameSpace);
+        nsCOMPtr<nsIAtom> prefixAtom = do_GetAtom(prefix);
+
+        nsCOMPtr<nsIDOM3Node> node(do_QueryInterface(child));
+
+        if (node) {
+          node->LookupNamespaceURI(prefix, nameSpace);
 
-        if (!nameSpace.IsEmpty()) {
-          if (!hasDisplay) {
-            // We extend some widget/frame. We don't really have a
-            // base binding.
-            protoBinding->SetHasBasePrototype(PR_FALSE);
-            //child->UnsetAttr(kNameSpaceID_None, nsGkAtoms::extends, PR_FALSE);
-          }
+          if (!nameSpace.IsEmpty()) {
+            if (!hasDisplay) {
+              // We extend some widget/frame. We don't really have a
+              // base binding.
+              protoBinding->SetHasBasePrototype(PR_FALSE);
+              //child->UnsetAttr(kNameSpaceID_None, nsGkAtoms::extends, PR_FALSE);
+            }
 
-          PRInt32 nameSpaceID =
-            nsContentUtils::NameSpaceManager()->GetNameSpaceID(nameSpace);
+            PRInt32 nameSpaceID =
+              nsContentUtils::NameSpaceManager()->GetNameSpaceID(nameSpace);
 
-          nsCOMPtr<nsIAtom> tagName = do_GetAtom(display);
-          // Check the white list
-          if (!CheckTagNameWhiteList(nameSpaceID, tagName)) {
-            const PRUnichar* params[] = { display.get() };
-            nsContentUtils::ReportToConsole(nsContentUtils::eXBL_PROPERTIES,
-                                            "InvalidExtendsBinding",
-                                            params, NS_ARRAY_LENGTH(params),
-                                            nsnull,
-                                            EmptyString(), 0, 0,
-                                            nsIScriptError::errorFlag,
-                                            "XBL", doc);
-            NS_ASSERTION(!IsChromeOrResourceURI(aURI),
-                         "Invalid extends value");
-            return NS_ERROR_ILLEGAL_VALUE;
+            nsCOMPtr<nsIAtom> tagName = do_GetAtom(display);
+            // Check the white list
+            if (!CheckTagNameWhiteList(nameSpaceID, tagName)) {
+              const PRUnichar* params[] = { display.get() };
+              nsContentUtils::ReportToConsole(nsContentUtils::eXBL_PROPERTIES,
+                                              "InvalidExtendsBinding",
+                                              params, NS_ARRAY_LENGTH(params),
+                                              nsnull,
+                                              EmptyString(), 0, 0,
+                                              nsIScriptError::errorFlag,
+                                              "XBL", doc);
+              NS_ASSERTION(!IsChromeOrResourceURI(aURI),
+                           "Invalid extends value");
+              return NS_ERROR_ILLEGAL_VALUE;
+            }
+
+            protoBinding->SetBaseTag(nameSpaceID, tagName);
           }
-
-          protoBinding->SetBaseTag(nameSpaceID, tagName);
         }
       }
 
       if (hasExtends && (hasDisplay || nameSpace.IsEmpty())) {
         // Look up the prefix.
         // We have a base class binding. Load it right now.
         nsCOMPtr<nsIURI> bindingURI;
         rv = NS_NewURI(getter_AddRefs(bindingURI), value,
--- a/content/xml/content/src/nsXMLCDATASection.cpp
+++ b/content/xml/content/src/nsXMLCDATASection.cpp
@@ -48,33 +48,30 @@ class nsXMLCDATASection : public nsGener
 public:
   nsXMLCDATASection(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~nsXMLCDATASection();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE(nsGenericDOMDataNode::)
+  NS_IMPL_NSIDOMNODE_USING_GENERIC_DOM_DATA
 
   // nsIDOMCharacterData
   NS_FORWARD_NSIDOMCHARACTERDATA(nsGenericDOMDataNode::)
 
   // nsIDOMText
   NS_FORWARD_NSIDOMTEXT(nsGenericDOMDataNode::)
 
   // nsIDOMCDATASection
   // Empty interface
 
-  // nsINode
+  // nsIContent
   virtual PRBool IsNodeOfType(PRUint32 aFlags) const;
 
-  virtual nsGenericDOMDataNode* CloneDataNode(nsINodeInfo *aNodeInfo,
-                                              PRBool aCloneText) const;
-
   virtual nsXPCClassInfo* GetClassInfo();
 #ifdef DEBUG
   virtual void List(FILE* out, PRInt32 aIndent) const;
   virtual void DumpContent(FILE* out, PRInt32 aIndent,PRBool aDumpAll) const;
 #endif
 };
 
 nsresult
@@ -82,35 +79,32 @@ NS_NewXMLCDATASection(nsIContent** aInst
                       nsNodeInfoManager *aNodeInfoManager)
 {
   NS_PRECONDITION(aNodeInfoManager, "Missing nodeinfo manager");
 
   *aInstancePtrResult = nsnull;
 
   nsCOMPtr<nsINodeInfo> ni;
   ni = aNodeInfoManager->GetNodeInfo(nsGkAtoms::cdataTagName,
-                                     nsnull, kNameSpaceID_None,
-                                     nsIDOMNode::CDATA_SECTION_NODE);
+                                     nsnull, kNameSpaceID_None);
   NS_ENSURE_TRUE(ni, NS_ERROR_OUT_OF_MEMORY);
 
   nsXMLCDATASection *instance = new nsXMLCDATASection(ni.forget());
   if (!instance) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   NS_ADDREF(*aInstancePtrResult = instance);
 
   return NS_OK;
 }
 
 nsXMLCDATASection::nsXMLCDATASection(already_AddRefed<nsINodeInfo> aNodeInfo)
   : nsGenericDOMDataNode(aNodeInfo)
 {
-  NS_ABORT_IF_FALSE(mNodeInfo->NodeType() == nsIDOMNode::CDATA_SECTION_NODE,
-                    "Bad NodeType in aNodeInfo");
 }
 
 nsXMLCDATASection::~nsXMLCDATASection()
 {
 }
 
 
 DOMCI_NODE_DATA(CDATASection, nsXMLCDATASection)
@@ -127,16 +121,42 @@ NS_IMPL_RELEASE_INHERITED(nsXMLCDATASect
 
 
 PRBool
 nsXMLCDATASection::IsNodeOfType(PRUint32 aFlags) const
 {
   return !(aFlags & ~(eCONTENT | eTEXT | eDATA_NODE));
 }
 
+NS_IMETHODIMP
+nsXMLCDATASection::GetNodeName(nsAString& aNodeName)
+{
+  aNodeName.AssignLiteral("#cdata-section");
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsXMLCDATASection::GetNodeValue(nsAString& aNodeValue)
+{
+  return nsGenericDOMDataNode::GetNodeValue(aNodeValue);
+}
+
+NS_IMETHODIMP
+nsXMLCDATASection::SetNodeValue(const nsAString& aNodeValue)
+{
+  return nsGenericDOMDataNode::SetNodeValue(aNodeValue);
+}
+
+NS_IMETHODIMP
+nsXMLCDATASection::GetNodeType(PRUint16* aNodeType)
+{
+  *aNodeType = (PRUint16)nsIDOMNode::CDATA_SECTION_NODE;
+  return NS_OK;
+}
+
 nsGenericDOMDataNode*
 nsXMLCDATASection::CloneDataNode(nsINodeInfo *aNodeInfo, PRBool aCloneText) const
 {
   nsCOMPtr<nsINodeInfo> ni = aNodeInfo;
   nsXMLCDATASection *it = new nsXMLCDATASection(ni.forget());
   if (it && aCloneText) {
     it->mText = mText;
   }
--- a/content/xml/content/src/nsXMLProcessingInstruction.cpp
+++ b/content/xml/content/src/nsXMLProcessingInstruction.cpp
@@ -45,52 +45,45 @@
 nsresult
 NS_NewXMLProcessingInstruction(nsIContent** aInstancePtrResult,
                                nsNodeInfoManager *aNodeInfoManager,
                                const nsAString& aTarget,
                                const nsAString& aData)
 {
   NS_PRECONDITION(aNodeInfoManager, "Missing nodeinfo manager");
 
-  nsCOMPtr<nsIAtom> target = do_GetAtom(aTarget);
-  NS_ENSURE_TRUE(target, NS_ERROR_OUT_OF_MEMORY);
-
-  if (target == nsGkAtoms::xml_stylesheet) {
+  if (aTarget.EqualsLiteral("xml-stylesheet")) {
     return NS_NewXMLStylesheetProcessingInstruction(aInstancePtrResult,
                                                     aNodeInfoManager, aData);
   }
 
   *aInstancePtrResult = nsnull;
 
   nsCOMPtr<nsINodeInfo> ni;
   ni = aNodeInfoManager->GetNodeInfo(nsGkAtoms::processingInstructionTagName,
-                                     nsnull, kNameSpaceID_None,
-                                     nsIDOMNode::PROCESSING_INSTRUCTION_NODE,
-                                     target);
+                                     nsnull, kNameSpaceID_None);
   NS_ENSURE_TRUE(ni, NS_ERROR_OUT_OF_MEMORY);
 
   nsXMLProcessingInstruction *instance =
-    new nsXMLProcessingInstruction(ni.forget(), aData);
+    new nsXMLProcessingInstruction(ni.forget(), aTarget, aData);
   if (!instance) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   NS_ADDREF(*aInstancePtrResult = instance);
 
   return NS_OK;
 }
 
 nsXMLProcessingInstruction::nsXMLProcessingInstruction(already_AddRefed<nsINodeInfo> aNodeInfo,
+                                                       const nsAString& aTarget,
                                                        const nsAString& aData)
-  : nsGenericDOMDataNode(aNodeInfo)
+  : nsGenericDOMDataNode(aNodeInfo),
+    mTarget(aTarget)
 {
-  NS_ABORT_IF_FALSE(mNodeInfo->NodeType() ==
-                      nsIDOMNode::PROCESSING_INSTRUCTION_NODE,
-                    "Bad NodeType in aNodeInfo");
-
   SetTextInternal(0, mText.GetLength(),
                   aData.BeginReading(), aData.Length(),
                   PR_FALSE);  // Don't notify (bug 420429).
 }
 
 nsXMLProcessingInstruction::~nsXMLProcessingInstruction()
 {
 }
@@ -112,17 +105,17 @@ NS_INTERFACE_MAP_END_INHERITING(nsGeneri
 
 NS_IMPL_ADDREF_INHERITED(nsXMLProcessingInstruction, nsGenericDOMDataNode)
 NS_IMPL_RELEASE_INHERITED(nsXMLProcessingInstruction, nsGenericDOMDataNode)
 
 
 NS_IMETHODIMP
 nsXMLProcessingInstruction::GetTarget(nsAString& aTarget)
 {
-  aTarget = NodeName();
+  aTarget.Assign(mTarget);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXMLProcessingInstruction::SetData(const nsAString& aData)
 {
   return SetNodeValue(aData);
@@ -144,38 +137,64 @@ nsXMLProcessingInstruction::GetAttrValue
 }
 
 PRBool
 nsXMLProcessingInstruction::IsNodeOfType(PRUint32 aFlags) const
 {
   return !(aFlags & ~(eCONTENT | ePROCESSING_INSTRUCTION | eDATA_NODE));
 }
 
+NS_IMETHODIMP
+nsXMLProcessingInstruction::GetNodeName(nsAString& aNodeName)
+{
+  aNodeName.Assign(mTarget);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsXMLProcessingInstruction::GetNodeValue(nsAString& aNodeValue)
+{
+  return nsGenericDOMDataNode::GetNodeValue(aNodeValue);
+}
+
+NS_IMETHODIMP
+nsXMLProcessingInstruction::SetNodeValue(const nsAString& aNodeValue)
+{
+  return nsGenericDOMDataNode::SetNodeValue(aNodeValue);
+}
+
+NS_IMETHODIMP
+nsXMLProcessingInstruction::GetNodeType(PRUint16* aNodeType)
+{
+  *aNodeType = (PRUint16)nsIDOMNode::PROCESSING_INSTRUCTION_NODE;
+  return NS_OK;
+}
+
 nsGenericDOMDataNode*
 nsXMLProcessingInstruction::CloneDataNode(nsINodeInfo *aNodeInfo,
                                           PRBool aCloneText) const
 {
   nsAutoString data;
   nsGenericDOMDataNode::GetData(data);
   nsCOMPtr<nsINodeInfo> ni = aNodeInfo;
-  return new nsXMLProcessingInstruction(ni.forget(), data);
+  return new nsXMLProcessingInstruction(ni.forget(), mTarget, data);
 }
 
 #ifdef DEBUG
 void
 nsXMLProcessingInstruction::List(FILE* out, PRInt32 aIndent) const
 {
   PRInt32 index;
   for (index = aIndent; --index >= 0; ) fputs("  ", out);
 
   fprintf(out, "Processing instruction refcount=%d<", mRefCnt.get());
 
   nsAutoString tmp;
   ToCString(tmp, 0, mText.GetLength());
-  tmp.Insert(nsDependentAtomString(NodeInfo()->GetExtraName()).get(), 0);
+  tmp.Insert(mTarget.get(), 0);
   fputs(NS_LossyConvertUTF16toASCII(tmp).get(), out);
 
   fputs(">\n", out);
 }
 
 void
 nsXMLProcessingInstruction::DumpContent(FILE* out, PRInt32 aIndent,
                                         PRBool aDumpAll) const
--- a/content/xml/content/src/nsXMLProcessingInstruction.h
+++ b/content/xml/content/src/nsXMLProcessingInstruction.h
@@ -45,34 +45,32 @@
 #include "nsAString.h"
 
 
 class nsXMLProcessingInstruction : public nsGenericDOMDataNode,
                                    public nsIDOMProcessingInstruction
 {
 public:
   nsXMLProcessingInstruction(already_AddRefed<nsINodeInfo> aNodeInfo,
+                             const nsAString& aTarget,
                              const nsAString& aData);
   virtual ~nsXMLProcessingInstruction();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE(nsGenericDOMDataNode::)
+  NS_IMPL_NSIDOMNODE_USING_GENERIC_DOM_DATA
 
   // nsIDOMProcessingInstruction
   NS_DECL_NSIDOMPROCESSINGINSTRUCTION
 
-  // nsINode
+  // nsIContent
   virtual PRBool IsNodeOfType(PRUint32 aFlags) const;
 
-  virtual nsGenericDOMDataNode* CloneDataNode(nsINodeInfo *aNodeInfo,
-                                              PRBool aCloneText) const;
-
 #ifdef DEBUG
   virtual void List(FILE* out, PRInt32 aIndent) const;
   virtual void DumpContent(FILE* out, PRInt32 aIndent, PRBool aDumpAll) const;
 #endif
 
   virtual nsXPCClassInfo* GetClassInfo();
 protected:
   /**
@@ -81,11 +79,13 @@ protected:
    * http://www.w3.org/TR/xml-stylesheet/#NT-StyleSheetPI for the specification
    * which is used to parse the content of the PI.
    *
    * @param aName the name of the attribute to get the value for
    * @param aValue [out] the value for the attribute with name specified in
    *                     aAttribute. Empty if the attribute isn't present.
    */
   PRBool GetAttrValue(nsIAtom *aName, nsAString& aValue);
+
+  nsString mTarget;
 };
 
 #endif //nsIXMLProcessingInstruction_h___
--- a/content/xml/content/src/nsXMLStylesheetPI.cpp
+++ b/content/xml/content/src/nsXMLStylesheetPI.cpp
@@ -100,17 +100,18 @@ NS_INTERFACE_TABLE_HEAD(nsXMLStylesheetP
 NS_INTERFACE_MAP_END_INHERITING(nsXMLProcessingInstruction)
 
 NS_IMPL_ADDREF_INHERITED(nsXMLStylesheetPI, nsXMLProcessingInstruction)
 NS_IMPL_RELEASE_INHERITED(nsXMLStylesheetPI, nsXMLProcessingInstruction)
 
 
 nsXMLStylesheetPI::nsXMLStylesheetPI(already_AddRefed<nsINodeInfo> aNodeInfo,
                                      const nsAString& aData)
-  : nsXMLProcessingInstruction(aNodeInfo, aData)
+  : nsXMLProcessingInstruction(aNodeInfo, NS_LITERAL_STRING("xml-stylesheet"),
+                               aData)
 {
 }
 
 nsXMLStylesheetPI::~nsXMLStylesheetPI()
 {
 }
 
 // nsIContent
@@ -260,19 +261,17 @@ NS_NewXMLStylesheetProcessingInstruction
                                          const nsAString& aData)
 {
   NS_PRECONDITION(aNodeInfoManager, "Missing nodeinfo manager");
 
   *aInstancePtrResult = nsnull;
   
   nsCOMPtr<nsINodeInfo> ni;
   ni = aNodeInfoManager->GetNodeInfo(nsGkAtoms::processingInstructionTagName,
-                                     nsnull, kNameSpaceID_None,
-                                     nsIDOMNode::PROCESSING_INSTRUCTION_NODE,
-                                     nsGkAtoms::xml_stylesheet);
+                                     nsnull, kNameSpaceID_None);
   NS_ENSURE_TRUE(ni, NS_ERROR_OUT_OF_MEMORY);
 
   nsXMLStylesheetPI *instance = new nsXMLStylesheetPI(ni.forget(), aData);
   if (!instance) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   NS_ADDREF(*aInstancePtrResult = instance);
--- a/content/xml/document/src/nsXMLContentSink.cpp
+++ b/content/xml/document/src/nsXMLContentSink.cpp
@@ -1007,18 +1007,17 @@ nsXMLContentSink::HandleStartElement(con
   nsContentUtils::SplitExpatName(aName, getter_AddRefs(prefix),
                                  getter_AddRefs(localName), &nameSpaceID);
 
   if (!OnOpenContainer(aAtts, aAttsCount, nameSpaceID, localName, aLineNumber)) {
     return NS_OK;
   }
   
   nsCOMPtr<nsINodeInfo> nodeInfo;
-  nodeInfo = mNodeInfoManager->GetNodeInfo(localName, prefix, nameSpaceID,
-                                           nsIDOMNode::ELEMENT_NODE);
+  nodeInfo = mNodeInfoManager->GetNodeInfo(localName, prefix, nameSpaceID);
   NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
 
   result = CreateElement(aAtts, aAttsCount, nodeInfo, aLineNumber,
                          getter_AddRefs(content), &appendContent,
                          FROM_PARSER_NETWORK);
   NS_ENSURE_SUCCESS(result, result);
 
   // Have to do this before we push the new content on the stack... and have to
--- a/content/xml/document/src/nsXMLFragmentContentSink.cpp
+++ b/content/xml/document/src/nsXMLFragmentContentSink.cpp
@@ -636,27 +636,30 @@ nsXHTMLParanoidFragmentSink::AddAttribut
 
   // scrub URI attributes that point at dangerous content
   // We have to do this here, because this is where we have a base URI,
   // but we can't do all the scrubbing here, because other parts of the
   // code get the attributes before this method is called.
   nsTArray<const PRUnichar *> allowedAttrs;
   PRInt32 nameSpaceID;
   nsCOMPtr<nsIAtom> prefix, localName;
+  nsCOMPtr<nsINodeInfo> nodeInfo;
 
   if (!mNullPrincipal) {
       mNullPrincipal = do_CreateInstance(NS_NULLPRINCIPAL_CONTRACTID, &rv);
       NS_ENSURE_SUCCESS(rv, rv);
   }
 
   while (*aAtts) {
     nsContentUtils::SplitExpatName(aAtts[0], getter_AddRefs(prefix),
                                    getter_AddRefs(localName), &nameSpaceID);
+    nodeInfo = mNodeInfoManager->GetNodeInfo(localName, prefix, nameSpaceID);
+    NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
     // check the attributes we allow that contain URIs
-    if (IsAttrURI(localName)) {
+    if (IsAttrURI(nodeInfo->NameAtom())) {
       if (!aAtts[1])
         rv = NS_ERROR_FAILURE;
       if (!baseURI)
         baseURI = aContent->GetBaseURI();
       nsCOMPtr<nsIURI> attrURI;
       rv = NS_NewURI(getter_AddRefs(attrURI), nsDependentString(aAtts[1]),
                      nsnull, baseURI);
       if (NS_SUCCEEDED(rv)) {
@@ -688,37 +691,46 @@ nsXHTMLParanoidFragmentSink::HandleStart
   nsCOMPtr<nsIAtom> prefix, localName;
   nsContentUtils::SplitExpatName(aName, getter_AddRefs(prefix),
                                  getter_AddRefs(localName), &nameSpaceID);
   
   // If the element is not in the XHTML namespace, bounce it
   if (nameSpaceID != kNameSpaceID_XHTML)
     return NS_OK;
   
+  nsCOMPtr<nsINodeInfo> nodeInfo;
+  nodeInfo = mNodeInfoManager->GetNodeInfo(localName, prefix, nameSpaceID);
+  NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
+  
   // bounce it if it's not on the whitelist or we're inside
   // <script> or <style>
+  nsCOMPtr<nsIAtom> name = nodeInfo->NameAtom();
   if (mSkipLevel != 0 ||
-      localName == nsGkAtoms::script ||
-      localName == nsGkAtoms::style) {
+      name == nsGkAtoms::script ||
+      name == nsGkAtoms::style) {
     ++mSkipLevel; // track this so we don't spew script text
     return NS_OK;
   }  
   
-  if (!sAllowedTags || !sAllowedTags->GetEntry(localName))
+  if (!sAllowedTags || !sAllowedTags->GetEntry(name))
     return NS_OK;
   
   // It's an allowed element, so let's scrub the attributes
   nsTArray<const PRUnichar *> allowedAttrs;
   for (PRUint32 i = 0; i < aAttsCount; i += 2) {
     nsContentUtils::SplitExpatName(aAtts[i], getter_AddRefs(prefix),
                                    getter_AddRefs(localName), &nameSpaceID);
+    nodeInfo = mNodeInfoManager->GetNodeInfo(localName, prefix, nameSpaceID);
+    NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
+    
+    name = nodeInfo->NameAtom();
     // Add if it's xmlns, xml: or on the HTML whitelist
     if (nameSpaceID == kNameSpaceID_XMLNS ||
         nameSpaceID == kNameSpaceID_XML ||
-        (sAllowedAttributes && sAllowedAttributes->GetEntry(localName))) {
+        (sAllowedAttributes && sAllowedAttributes->GetEntry(name))) {
       allowedAttrs.AppendElement(aAtts[i]);
       allowedAttrs.AppendElement(aAtts[i + 1]);
     }
   }
   allowedAttrs.AppendElement((const PRUnichar*) nsnull);
   return
     nsXMLFragmentContentSink::HandleStartElement(aName,
                                                  allowedAttrs.Elements(),
@@ -735,22 +747,27 @@ nsXHTMLParanoidFragmentSink::HandleEndEl
   nsContentUtils::SplitExpatName(aName, getter_AddRefs(prefix),
                                  getter_AddRefs(localName), &nameSpaceID);
   
   // If the element is not in the XHTML namespace, bounce it
   if (nameSpaceID != kNameSpaceID_XHTML) {
     return NS_OK;
   }
   
+  nsCOMPtr<nsINodeInfo> nodeInfo;
+  nodeInfo = mNodeInfoManager->GetNodeInfo(localName, prefix, nameSpaceID);
+  NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
+  
+  nsCOMPtr<nsIAtom> name = nodeInfo->NameAtom();
   if (mSkipLevel != 0) {
     --mSkipLevel;
     return NS_OK;
   }
 
-  if (!sAllowedTags || !sAllowedTags->GetEntry(localName)) {
+  if (!sAllowedTags || !sAllowedTags->GetEntry(name)) {
     return NS_OK;
   }
 
   return nsXMLFragmentContentSink::HandleEndElement(aName);
 }
 
 NS_IMETHODIMP
 nsXHTMLParanoidFragmentSink::
--- a/content/xslt/src/xpath/nsXPathExpression.cpp
+++ b/content/xslt/src/xpath/nsXPathExpression.cpp
@@ -102,17 +102,20 @@ nsXPathExpression::EvaluateWithContext(n
         nsCOMPtr<nsIDOMDocument> contextDocument;
         aContextNode->GetOwnerDocument(getter_AddRefs(contextDocument));
 
         if (mDocument != contextDocument) {
             return NS_ERROR_DOM_WRONG_DOCUMENT_ERR;
         }
     }
 
-    PRUint16 nodeType = context->NodeType();
+    nsresult rv;
+    PRUint16 nodeType;
+    rv = aContextNode->GetNodeType(&nodeType);
+    NS_ENSURE_SUCCESS(rv, rv);
 
     if (nodeType == nsIDOMNode::TEXT_NODE ||
         nodeType == nsIDOMNode::CDATA_SECTION_NODE) {
         nsCOMPtr<nsIDOMCharacterData> textNode = do_QueryInterface(aContextNode);
         NS_ENSURE_TRUE(textNode, NS_ERROR_FAILURE);
 
         if (textNode) {
             PRUint32 textLength;
@@ -139,17 +142,17 @@ nsXPathExpression::EvaluateWithContext(n
     nsAutoPtr<txXPathNode> contextNode(txXPathNativeNode::createXPathNode(aContextNode));
     if (!contextNode) {
         return NS_ERROR_OUT_OF_MEMORY;
     }
 
     EvalContextImpl eContext(*contextNode, aContextPosition, aContextSize,
                              mRecycler);
     nsRefPtr<txAExprResult> exprResult;
-    nsresult rv = mExpression->evaluate(&eContext, getter_AddRefs(exprResult));
+    rv = mExpression->evaluate(&eContext, getter_AddRefs(exprResult));
     NS_ENSURE_SUCCESS(rv, rv);
 
     PRUint16 resultType = aType;
     if (aType == nsIDOMXPathResult::ANY_TYPE) {
         short exprResultType = exprResult->getResultType();
         switch (exprResultType) {
             case txAExprResult::NUMBER:
                 resultType = nsIDOMXPathResult::NUMBER_TYPE;
--- a/content/xslt/src/xpath/nsXPathNSResolver.cpp
+++ b/content/xslt/src/xpath/nsXPathNSResolver.cpp
@@ -50,18 +50,18 @@ DOMCI_DATA(XPathNSResolver, nsXPathNSRes
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsXPathNSResolver)
   NS_INTERFACE_MAP_ENTRY(nsIDOMXPathNSResolver)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMXPathNSResolver)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(XPathNSResolver)
 NS_INTERFACE_MAP_END
 
 nsXPathNSResolver::nsXPathNSResolver(nsIDOMNode* aNode)
-  : mNode(aNode)
 {
+    mNode = do_QueryInterface(aNode);
     NS_ASSERTION(mNode, "Need a node to resolve namespaces.");
 }
 
 NS_IMETHODIMP
 nsXPathNSResolver::LookupNamespaceURI(const nsAString & aPrefix,
                                       nsAString & aResult)
 {
     if (aPrefix.EqualsLiteral("xml")) {
--- a/content/xslt/src/xpath/nsXPathNSResolver.h
+++ b/content/xslt/src/xpath/nsXPathNSResolver.h
@@ -36,16 +36,17 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef nsXPathNSResolver_h__
 #define nsXPathNSResolver_h__
 
 #include "nsIDOMXPathNSResolver.h"
 #include "nsIDOMNode.h"
+#include "nsIDOM3Node.h"
 #include "nsCOMPtr.h"
 #include "nsCycleCollectionParticipant.h"
 
 /**
  * A class for evaluating an XPath expression string
  */
 class nsXPathNSResolver : public nsIDOMXPathNSResolver
 {
@@ -55,12 +56,12 @@ public:
     // nsISupports interface
     NS_DECL_CYCLE_COLLECTING_ISUPPORTS
     NS_DECL_CYCLE_COLLECTION_CLASS(nsXPathNSResolver)
 
     // nsIDOMXPathNSResolver interface
     NS_DECL_NSIDOMXPATHNSRESOLVER
 
 private:
-    nsCOMPtr<nsIDOMNode> mNode;
+    nsCOMPtr<nsIDOM3Node> mNode;
 };
 
 #endif
--- a/content/xslt/src/xpath/txMozillaXPathTreeWalker.cpp
+++ b/content/xslt/src/xpath/txMozillaXPathTreeWalker.cpp
@@ -34,16 +34,17 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "txXPathTreeWalker.h"
 #include "nsIAtom.h"
 #include "nsIAttribute.h"
+#include "nsIDOM3Node.h"
 #include "nsIDOMAttr.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOMNode.h"
 #include "nsIDOMElement.h"
 #include "nsIDOMProcessingInstruction.h"
 #include "nsINodeInfo.h"
 #include "nsPrintfCString.h"
 #include "nsReadableUtils.h"
@@ -462,30 +463,40 @@ txXPathNodeUtils::getNodeName(const txXP
 {
     if (aNode.isDocument()) {
         aName.Truncate();
 
         return;
     }
 
     if (aNode.isContent()) {
-        // Elements and PIs have a name
-        if (aNode.mNode->IsElement() ||
-            aNode.mNode->NodeType() ==
-            nsIDOMNode::PROCESSING_INSTRUCTION_NODE) {
-            aName = aNode.Content()->NodeName();
+        if (aNode.mNode->IsElement()) {
+            aName = aNode.Content()->NodeInfo()->QualifiedNameCorrectedCase();
+            return;
+        }
+
+        if (aNode.mNode->IsNodeOfType(nsINode::ePROCESSING_INSTRUCTION)) {
+            // PIs don't have a nodeinfo but do have a name
+            nsCOMPtr<nsIDOMNode> node = do_QueryInterface(aNode.mNode);
+            node->GetNodeName(aName);
+
             return;
         }
 
         aName.Truncate();
 
         return;
     }
 
     aNode.Content()->GetAttrNameAt(aNode.mIndex)->GetQualifiedName(aName);
+
+    // Check for html
+    if (aNode.Content()->IsHTML()) {
+        ToUpperCase(aName);
+    }
 }
 
 /* static */
 PRInt32
 txXPathNodeUtils::getNamespaceID(const txXPathNode& aNode)
 {
     if (aNode.isDocument()) {
         return kNameSpaceID_None;
@@ -509,17 +520,21 @@ txXPathNodeUtils::getNamespaceURI(const 
 PRUint16
 txXPathNodeUtils::getNodeType(const txXPathNode& aNode)
 {
     if (aNode.isDocument()) {
         return txXPathNodeType::DOCUMENT_NODE;
     }
 
     if (aNode.isContent()) {
-        return aNode.mNode->NodeType();
+        PRUint16 type;
+        nsCOMPtr<nsIDOMNode> node = do_QueryInterface(aNode.mNode);
+        node->GetNodeType(&type);
+
+        return type;
     }
 
     return txXPathNodeType::ATTRIBUTE_NODE;
 }
 
 /* static */
 void
 txXPathNodeUtils::appendNodeValue(const txXPathNode& aNode, nsAString& aResult)
@@ -607,17 +622,23 @@ txXPathNodeUtils::getXSLTId(const txXPat
 
     return NS_OK;
 }
 
 /* static */
 void
 txXPathNodeUtils::getBaseURI(const txXPathNode& aNode, nsAString& aURI)
 {
-    aNode.mNode->GetDOMBaseURI(aURI);
+    nsCOMPtr<nsIDOM3Node> node = do_QueryInterface(aNode.mNode);
+    if (node) {
+        node->GetBaseURI(aURI);
+    }
+    else {
+        aURI.Truncate();
+    }
 }
 
 /* static */
 PRIntn
 txXPathNodeUtils::comparePosition(const txXPathNode& aNode,
                                   const txXPathNode& aOtherNode)
 {
     // First check for equal nodes or attribute-nodes on the same element.
--- a/content/xslt/src/xslt/txMozillaTextOutput.cpp
+++ b/content/xslt/src/xslt/txMozillaTextOutput.cpp
@@ -280,14 +280,13 @@ void txMozillaTextOutput::getOutputDocum
 nsresult
 txMozillaTextOutput::createXHTMLElement(nsIAtom* aName,
                                         nsIContent** aResult)
 {
     *aResult = nsnull;
 
     nsCOMPtr<nsINodeInfo> ni;
     ni = mDocument->NodeInfoManager()->
-        GetNodeInfo(aName, nsnull, kNameSpaceID_XHTML,
-                    nsIDOMNode::ELEMENT_NODE);
+        GetNodeInfo(aName, nsnull, kNameSpaceID_XHTML);
     NS_ENSURE_TRUE(ni, NS_ERROR_OUT_OF_MEMORY);
 
     return NS_NewHTMLElement(aResult, ni.forget(), NOT_FROM_PARSER);
 }
--- a/content/xslt/src/xslt/txMozillaXMLOutput.cpp
+++ b/content/xslt/src/xslt/txMozillaXMLOutput.cpp
@@ -556,18 +556,17 @@ txMozillaXMLOutput::startElementInternal
         return NS_ERROR_OUT_OF_MEMORY;
     }
 
     mTableState = NORMAL;
     mOpenedElementIsHTML = PR_FALSE;
 
     // Create the element
     nsCOMPtr<nsINodeInfo> ni;
-    ni = mNodeInfoManager->GetNodeInfo(aLocalName, aPrefix, aNsID,
-                                       nsIDOMNode::ELEMENT_NODE);
+    ni = mNodeInfoManager->GetNodeInfo(aLocalName, aPrefix, aNsID);
     NS_ENSURE_TRUE(ni, NS_ERROR_OUT_OF_MEMORY);
 
     NS_NewElement(getter_AddRefs(mOpenedElement), aNsID, ni.forget(),
                   mCreatingNewDocument ?
                   FROM_PARSER_XSLT : FROM_PARSER_FRAGMENT);
 
     // Set up the element and adjust state
     if (!mNoFixup) {
@@ -964,18 +963,17 @@ txMozillaXMLOutput::createHTMLElement(ns
 {
     NS_ASSERTION(mOutputFormat.mMethod == eHTMLOutput,
                  "need to adjust createHTMLElement");
 
     *aResult = nsnull;
 
     nsCOMPtr<nsINodeInfo> ni;
     ni = mNodeInfoManager->GetNodeInfo(aName, nsnull,
-                                       kNameSpaceID_XHTML,
-                                       nsIDOMNode::ELEMENT_NODE);
+                                       kNameSpaceID_XHTML);
     NS_ENSURE_TRUE(ni, NS_ERROR_OUT_OF_MEMORY);
 
     return NS_NewHTMLElement(aResult, ni.forget(), mCreatingNewDocument ?
         FROM_PARSER_XSLT : FROM_PARSER_FRAGMENT);
 
 }
 
 txTransformNotifier::txTransformNotifier()
--- a/content/xtf/src/nsXTFElementWrapper.cpp
+++ b/content/xtf/src/nsXTFElementWrapper.cpp
@@ -531,19 +531,17 @@ already_AddRefed<nsINodeInfo>
 nsXTFElementWrapper::GetExistingAttrNameFromQName(const nsAString& aStr) const
 {
   nsINodeInfo* nodeInfo = nsXTFElementWrapperBase::GetExistingAttrNameFromQName(aStr).get();
 
   // Maybe this attribute is handled by our inner element:
   if (!nodeInfo) {
     nsCOMPtr<nsIAtom> nameAtom = do_GetAtom(aStr);
     if (HandledByInner(nameAtom)) 
-      nodeInfo = mNodeInfo->NodeInfoManager()->
-        GetNodeInfo(nameAtom, nsnull, kNameSpaceID_None,
-                    nsIDOMNode::ATTRIBUTE_NODE).get();
+      nodeInfo = mNodeInfo->NodeInfoManager()->GetNodeInfo(nameAtom, nsnull, kNameSpaceID_None).get();
   }
   
   return nodeInfo;
 }
 
 nsEventStates
 nsXTFElementWrapper::IntrinsicState() const
 {
--- a/content/xul/content/src/nsXULElement.cpp
+++ b/content/xul/content/src/nsXULElement.cpp
@@ -324,19 +324,19 @@ nsXULElement::Create(nsXULPrototypeEleme
 
     NS_PRECONDITION(aResult != nsnull, "null ptr");
     if (! aResult)
         return NS_ERROR_NULL_POINTER;
 
     nsCOMPtr<nsINodeInfo> nodeInfo;
     if (aDocument) {
         nsINodeInfo* ni = aPrototype->mNodeInfo;
-        nodeInfo = aDocument->NodeInfoManager()->
-          GetNodeInfo(ni->NameAtom(), ni->GetPrefixAtom(), ni->NamespaceID(),
-                      nsIDOMNode::ELEMENT_NODE);
+        nodeInfo = aDocument->NodeInfoManager()->GetNodeInfo(ni->NameAtom(),
+                                                             ni->GetPrefixAtom(),
+                                                             ni->NamespaceID());
         NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
     }
     else {
         nodeInfo = aPrototype->mNodeInfo;
     }
 
     nsRefPtr<nsXULElement> element = Create(aPrototype, nodeInfo,
                                             aIsScriptable);
@@ -2647,18 +2647,17 @@ nsXULPrototypeElement::Serialize(nsIObje
 
     nsAutoString attributeValue;
     PRUint32 i;
     for (i = 0; i < mNumAttributes; ++i) {
         nsCOMPtr<nsINodeInfo> ni;
         if (mAttributes[i].mName.IsAtom()) {
             ni = mNodeInfo->NodeInfoManager()->
                 GetNodeInfo(mAttributes[i].mName.Atom(), nsnull,
-                            kNameSpaceID_None,
-                            nsIDOMNode::ATTRIBUTE_NODE);
+                            kNameSpaceID_None);
             NS_ASSERTION(ni, "the nodeinfo should already exist");
         }
         else {
             ni = mAttributes[i].mName.NodeInfo();
         }
 
         index = aNodeInfos->IndexOf(ni);
         NS_ASSERTION(index >= 0, "unknown nsINodeInfo index");
--- a/content/xul/document/src/nsXULContentSink.cpp
+++ b/content/xul/document/src/nsXULContentSink.cpp
@@ -460,18 +460,17 @@ XULContentSinkImpl::NormalizeAttributeSt
     if (nameSpaceID == kNameSpaceID_None) {
         aName.SetTo(localName);
 
         return NS_OK;
     }
 
     nsCOMPtr<nsINodeInfo> ni;
     ni = mNodeInfoManager->GetNodeInfo(localName, prefix,
-                                       nameSpaceID,
-                                       nsIDOMNode::ATTRIBUTE_NODE);
+                                       nameSpaceID);
     NS_ENSURE_TRUE(ni, NS_ERROR_OUT_OF_MEMORY);
 
     aName.SetTo(ni);
 
     return NS_OK;
 }
 
 nsresult
@@ -514,18 +513,17 @@ XULContentSinkImpl::HandleStartElement(c
   }
 
   PRInt32 nameSpaceID;
   nsCOMPtr<nsIAtom> prefix, localName;
   nsContentUtils::SplitExpatName(aName, getter_AddRefs(prefix),
                                  getter_AddRefs(localName), &nameSpaceID);
 
   nsCOMPtr<nsINodeInfo> nodeInfo;
-  nodeInfo = mNodeInfoManager->GetNodeInfo(localName, prefix, nameSpaceID,
-                                           nsIDOMNode::ELEMENT_NODE);
+  nodeInfo = mNodeInfoManager->GetNodeInfo(localName, prefix, nameSpaceID);
   NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
   
   nsresult rv = NS_OK;
   switch (mState) {
   case eInProlog:
       // We're the root document element
       rv = OpenRoot(aAtts, aAttsCount, nodeInfo);
       break;
--- a/content/xul/document/src/nsXULDocument.cpp
+++ b/content/xul/document/src/nsXULDocument.cpp
@@ -3699,18 +3699,17 @@ nsXULDocument::CreateElementFromPrototyp
     else {
         // If it's not a XUL element, it's gonna be heavyweight no matter
         // what. So we need to copy everything out of the prototype
         // into the element.  Get a nodeinfo from our nodeinfo manager
         // for this node.
         nsCOMPtr<nsINodeInfo> newNodeInfo;
         newNodeInfo = mNodeInfoManager->GetNodeInfo(aPrototype->mNodeInfo->NameAtom(),
                                                     aPrototype->mNodeInfo->GetPrefixAtom(),
-                                                    aPrototype->mNodeInfo->NamespaceID(),
-                                                    nsIDOMNode::ELEMENT_NODE);
+                                                    aPrototype->mNodeInfo->NamespaceID());
         if (!newNodeInfo) return NS_ERROR_OUT_OF_MEMORY;
         nsCOMPtr<nsIContent> content;
         PRInt32 ns = newNodeInfo->NamespaceID();
         nsCOMPtr<nsINodeInfo> xtfNi = newNodeInfo;
         rv = NS_NewElement(getter_AddRefs(content), ns, newNodeInfo.forget(),
                            NOT_FROM_PARSER);
         if (NS_FAILED(rv))
             return rv;
--- a/content/xul/document/src/nsXULPrototypeDocument.cpp
+++ b/content/xul/document/src/nsXULPrototypeDocument.cpp
@@ -312,21 +312,17 @@ nsXULPrototypeDocument::Read(nsIObjectIn
             prefix = nsnull;
         } else {
             rv |= aStream->ReadString(prefixStr);
             prefix = do_GetAtom(prefixStr);
         }
         rv |= aStream->ReadString(localName);
 
         nsCOMPtr<nsINodeInfo> nodeInfo;
-        // Using PR_UINT16_MAX here as we don't know which nodeinfos will be
-        // used for attributes and which for elements. And that doesn't really
-        // matter.
         rv |= mNodeInfoManager->GetNodeInfo(localName, prefix, namespaceURI,
-                                            PR_UINT16_MAX,
                                             getter_AddRefs(nodeInfo));
         if (!nodeInfos.AppendObject(nodeInfo))
             rv |= NS_ERROR_OUT_OF_MEMORY;
     }
 
     // Document contents
     PRUint32 type;
     while (NS_SUCCEEDED(rv)) {
@@ -368,18 +364,17 @@ GetNodeInfos(nsXULPrototypeElement* aPro
 
     // Search attributes
     PRUint32 i;
     for (i = 0; i < aPrototype->mNumAttributes; ++i) {
         nsCOMPtr<nsINodeInfo> ni;
         nsAttrName* name = &aPrototype->mAttributes[i].mName;
         if (name->IsAtom()) {
             ni = aPrototype->mNodeInfo->NodeInfoManager()->
-                GetNodeInfo(name->Atom(), nsnull, kNameSpaceID_None,
-                            nsIDOMNode::ATTRIBUTE_NODE);
+                GetNodeInfo(name->Atom(), nsnull, kNameSpaceID_None);
             NS_ENSURE_TRUE(ni, NS_ERROR_OUT_OF_MEMORY);
         }
         else {
             ni = name->NodeInfo();
         }
 
         if (aArray.IndexOf(ni) < 0) {
             if (!aArray.AppendObject(ni)) {
--- a/content/xul/templates/src/nsXULContentBuilder.cpp
+++ b/content/xul/templates/src/nsXULContentBuilder.cpp
@@ -1396,18 +1396,17 @@ nsXULContentBuilder::CreateElement(PRInt
     NS_ASSERTION(doc != nsnull, "not initialized");
     if (! doc)
         return NS_ERROR_NOT_INITIALIZED;
 
     nsresult rv;
     nsCOMPtr<nsIContent> result;
 
     nsCOMPtr<nsINodeInfo> nodeInfo;
-    nodeInfo = doc->NodeInfoManager()->GetNodeInfo(aTag, nsnull, aNameSpaceID,
-                                                   nsIDOMNode::ELEMENT_NODE);
+    nodeInfo = doc->NodeInfoManager()->GetNodeInfo(aTag, nsnull, aNameSpaceID);
 
     rv = NS_NewElement(getter_AddRefs(result), aNameSpaceID, nodeInfo.forget(),
                        NOT_FROM_PARSER);
     if (NS_FAILED(rv))
         return rv;
 
     *aResult = result;
     NS_ADDREF(*aResult);
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -123,16 +123,17 @@
 #include "nsIDOMChromeWindow.h"
 #include "nsIDOMConstructor.h"
 #include "nsClientRect.h"
 
 // DOM core includes
 #include "nsDOMError.h"
 #include "nsIDOMDOMException.h"
 #include "nsIDOMNode.h"
+#include "nsIDOM3Node.h"
 #include "nsIDOM3Attr.h"
 #include "nsIDOMNodeList.h"
 #include "nsIDOMNamedNodeMap.h"
 #include "nsIDOMDOMStringList.h"
 #include "nsIDOMDOMTokenList.h"
 #include "nsIDOMDOMSettableTokenList.h"
 #include "nsIDOMNameList.h"
 #include "nsIDOMNSElement.h"
@@ -2309,25 +2310,27 @@ nsDOMClassInfo::RegisterExternalClasses(
                                                                               \
     d.mInterfaces = interface_list;                                           \
   }
 
 #define DOM_CLASSINFO_DOCUMENT_MAP_ENTRIES                                    \
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMDocumentXBL)                                \
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMNSEventTarget)                              \
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget)                                \
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOM3Node)                                      \
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMXPathEvaluator)                             \
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMNodeSelector)
 
 
 #define DOM_CLASSINFO_GENERIC_HTML_MAP_ENTRIES                                \
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMNSHTMLElement)                              \
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMElementCSSInlineStyle)                      \
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMNSEventTarget)                              \
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget)                                \
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOM3Node)                                      \
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMNSElement)                                  \
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMNodeSelector)
 
 #define DOM_CLASSINFO_EVENT_MAP_ENTRIES                                       \
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMEvent)                                      \
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMNSEvent)                                    \
 
 #define DOM_CLASSINFO_UI_EVENT_MAP_ENTRIES                                    \
@@ -2472,16 +2475,17 @@ nsDOMClassInfo::Init()
       DOM_CLASSINFO_DOCUMENT_MAP_ENTRIES
     DOM_CLASSINFO_MAP_END
   }
 
   DOM_CLASSINFO_MAP_BEGIN(DocumentType, nsIDOMDocumentType)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMDocumentType)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMNSEventTarget)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOM3Node)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(DOMImplementation, nsIDOMDOMImplementation)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMDOMImplementation)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(DOMException, nsIDOMDOMException)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMDOMException)
@@ -2493,58 +2497,65 @@ nsDOMClassInfo::Init()
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(DOMSettableTokenList, nsIDOMDOMSettableTokenList)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMDOMSettableTokenList)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(DocumentFragment, nsIDOMDocumentFragment)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMDocumentFragment)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOM3Node)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMNodeSelector)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMNSEventTarget)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(Element, nsIDOMElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMNSElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMNSEventTarget)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOM3Node)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMNodeSelector)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(Attr, nsIDOMAttr)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMAttr)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOM3Node)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOM3Attr)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMNSEventTarget)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(Text, nsIDOMText)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMText)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMNSEventTarget)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOM3Node)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(Comment, nsIDOMComment)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMComment)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMNSEventTarget)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOM3Node)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(CDATASection, nsIDOMCDATASection)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMCDATASection)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMNSEventTarget)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOM3Node)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(ProcessingInstruction, nsIDOMProcessingInstruction)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMProcessingInstruction)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMNSEventTarget)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOM3Node)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(NodeList, nsIDOMNodeList)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMNodeList)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(NamedNodeMap, nsIDOMNamedNodeMap)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMNamedNodeMap)
@@ -3042,16 +3053,17 @@ nsDOMClassInfo::Init()
       DOM_CLASSINFO_DOCUMENT_MAP_ENTRIES
     DOM_CLASSINFO_MAP_END  
   }
 
   DOM_CLASSINFO_MAP_BEGIN(XULElement, nsIDOMXULElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMXULElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMNSEventTarget)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOM3Node)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMNSElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMElementCSSInlineStyle)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMNodeSelector)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(XULCommandDispatcher, nsIDOMXULCommandDispatcher)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMXULCommandDispatcher)
   DOM_CLASSINFO_MAP_END
@@ -3084,16 +3096,17 @@ nsDOMClassInfo::Init()
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMCRMFObject)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(XMLStylesheetProcessingInstruction, nsIDOMProcessingInstruction)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMProcessingInstruction)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMLinkStyle)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMNSEventTarget)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOM3Node)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(ChromeWindow, nsIDOMWindow)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMWindow)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMJSWindow)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMWindowInternal)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMChromeWindow)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMNSEventTarget)
@@ -3156,16 +3169,17 @@ nsDOMClassInfo::Init()
     DOM_CLASSINFO_EVENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
 #define DOM_CLASSINFO_SVG_ELEMENT_MAP_ENTRIES    \
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMNSEventTarget) \
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget)   \
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGElement)    \
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMNSElement)     \
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOM3Node)         \
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMNodeSelector)
 
 #define DOM_CLASSINFO_SVG_GRAPHIC_ELEMENT_MAP_ENTRIES \
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGLocatable)       \
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGTransformable)   \
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGStylable)        \
     DOM_CLASSINFO_SVG_ELEMENT_MAP_ENTRIES
 
@@ -4113,16 +4127,17 @@ nsDOMClassInfo::Init()
     DOM_CLASSINFO_UI_EVENT_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(MathMLElement, nsIDOMElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMNSElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMNSEventTarget)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOM3Node)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMNodeSelector)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(Worker, nsIWorker)
     DOM_CLASSINFO_MAP_ENTRY(nsIWorker)
     DOM_CLASSINFO_MAP_ENTRY(nsIAbstractWorker)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMNSEventTarget)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget)
@@ -6284,16 +6299,24 @@ ResolvePrototype(nsIXPConnect *aXPConnec
 
     if (!ac.enter(cx, class_obj)) {
       return NS_ERROR_FAILURE;
     }
 
     rv = DefineInterfaceConstants(cx, class_obj, primary_iid);
     NS_ENSURE_SUCCESS(rv, rv);
 
+    // Special case for |Node|, which needs constants from Node3
+    // too for forwards compatibility.
+    if (primary_iid->Equals(NS_GET_IID(nsIDOMNode))) {
+      rv = DefineInterfaceConstants(cx, class_obj,
+                                    &NS_GET_IID(nsIDOM3Node));
+      NS_ENSURE_SUCCESS(rv, rv);
+    }
+
     // Special case for |Event|, Event needs constants from NSEvent
     // too for backwards compatibility.
     if (primary_iid->Equals(NS_GET_IID(nsIDOMEvent))) {
       rv = DefineInterfaceConstants(cx, class_obj,
                                     &NS_GET_IID(nsIDOMNSEvent));
       NS_ENSURE_SUCCESS(rv, rv);
     }
 
--- a/dom/base/nsFocusManager.cpp
+++ b/dom/base/nsFocusManager.cpp
@@ -1726,17 +1726,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 == nsnull) {
     mFocusedContent = aContent;
 
     nsIContent* focusedNode = aWindow->GetFocusedNode();
-    PRBool isRefocus = focusedNode && focusedNode->IsEqualTo(aContent);
+    PRBool isRefocus = focusedNode && focusedNode->IsEqual(aContent);
 
     aWindow->SetFocusedNode(aContent, focusMethod);
 
     PRBool sendFocusEvent =
       aContent && aContent->IsInDoc() && !IsNonFocusableRoot(aContent);
     nsPresContext* presContext = presShell->GetPresContext();
     if (sendFocusEvent) {
       // if the focused element changed, scroll it into view
@@ -2175,19 +2175,23 @@ nsFocusManager::GetSelectionLocation(nsI
   if (startContent) {
     startFrame = startContent->GetPrimaryFrame();
     if (isCollapsed) {
       // Next check to see if our caret is at the very end of a node
       // If so, the caret is actually sitting in front of the next
       // logical frame's primary node - so for this case we need to
       // change caretContent to that node.
 
-      if (startContent->NodeType() == nsIDOMNode::TEXT_NODE) {
+      nsCOMPtr<nsIDOMNode> domNode(do_QueryInterface(startContent));
+      PRUint16 nodeType;
+      domNode->GetNodeType(&nodeType);
+
+      if (nodeType == nsIDOMNode::TEXT_NODE) {
         nsAutoString nodeValue;
-        startContent->AppendTextTo(nodeValue);
+        domNode->GetNodeValue(nodeValue);
 
         PRBool isFormControl =
           startContent->IsNodeOfType(nsINode::eHTML_FORM_CONTROL);
 
         if (nodeValue.Length() == (PRUint32)startOffset && !isFormControl &&
             startContent != aDocument->GetRootElement()) {
           // Yes, indeed we were at the end of the last node
           nsCOMPtr<nsIFrameEnumerator> frameTraversal;
--- a/dom/interfaces/base/Makefile.in
+++ b/dom/interfaces/base/Makefile.in
@@ -74,16 +74,17 @@ XPIDLSRCS =					\
 	nsIDOMPkcs11.idl			\
 	nsIDOMPlugin.idl			\
 	nsIDOMPluginArray.idl			\
 	nsIDOMScreen.idl			\
 	nsIDOMWindowInternal.idl		\
 	nsIDOMJSWindow.idl			\
 	nsIDOMModalContentWindow.idl		\
 	nsIDOMChromeWindow.idl			\
+	nsIDOMNSFeatureFactory.idl		\
         nsIDOMClientRect.idl			\
         nsIDOMClientRectList.idl		\
 	nsIFocusManager.idl			\
 	nsIQueryContentEventResult.idl		\
 	nsITabChild.idl				\
 	nsITabParent.idl			\
 	nsIDOMGlobalPropertyInitializer.idl	\
 	nsIStructuredCloneContainer.idl		\
new file mode 100644
--- /dev/null
+++ b/dom/interfaces/base/nsIDOMNSFeatureFactory.idl
@@ -0,0 +1,64 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Olli Pettay.
+ * Portions created by the Initial Developer are Copyright (C) 2005
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Olli Pettay <Olli.Pettay@helsinki.fi> (original author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+ 
+#include "domstubs.idl"
+
+[scriptable, uuid(dc5ba787-b648-4b01-a8e7-b293ffb044ef)]
+interface nsIDOMNSFeatureFactory : nsISupports
+{
+  /**
+   * @param object: usually either nsIDOMNode or nsIDOMDOMImplementation
+   * @param feature: the name of the feature
+   * @param version: the version of the feature
+   */
+  boolean                   hasFeature(in nsISupports object,
+                                       in DOMString feature,
+                                       in DOMString version);
+  /**
+   * @param object: usually either nsIDOMNode or nsIDOMDOMImplementation
+   * @param feature: the name of the feature
+   * @param version: the version of the feature
+   */
+  nsISupports               getFeature(in nsISupports object,
+                                       in DOMString feature,
+                                       in DOMString version);
+};
+
+%{C++
+#define NS_DOMNS_FEATURE_PREFIX "MozillaDOMFeature-"
+%}
--- a/dom/interfaces/core/Makefile.in
+++ b/dom/interfaces/core/Makefile.in
@@ -59,16 +59,17 @@ SDK_XPIDLSRCS =                         
 	nsIDOMElement.idl			\
 	nsIDOMNamedNodeMap.idl			\
 	nsIDOMNode.idl				\
 	nsIDOMNodeList.idl			\
 	nsIDOMProcessingInstruction.idl		\
 	nsIDOMText.idl				\
 	$(NULL)
 XPIDLSRCS =                                     \
+	nsIDOM3Node.idl				\
 	nsIDOM3Attr.idl				\
 	nsIDOMDOMStringList.idl			\
 	nsIDOMNameList.idl			\
 	nsIDOMXMLDocument.idl			\
 	nsIDOMUserDataHandler.idl		\
 	nsIDOMNSEditableElement.idl		\
 	nsIDOMNSElement.idl			\
 	nsIDOMNodeSelector.idl			\
new file mode 100644
--- /dev/null
+++ b/dom/interfaces/core/nsIDOM3Node.idl
@@ -0,0 +1,87 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Johnny Stenback <jst@netscape.com> (original author)
+ *   Christopher A. Aillon <christopher@aillon.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "domstubs.idl"
+
+interface nsIVariant;
+interface nsIDOMUserDataHandler;
+
+
+[scriptable, uuid(29fb2a18-1dd2-11b2-8dd9-a6fd5d5ad12f)]
+interface nsIDOM3Node : nsISupports
+{
+  // Introduced in DOM Level 3:
+  readonly attribute DOMString       baseURI;
+
+  // DocumentPosition
+  const unsigned short      DOCUMENT_POSITION_DISCONNECTED = 0x01;
+  const unsigned short      DOCUMENT_POSITION_PRECEDING    = 0x02;
+  const unsigned short      DOCUMENT_POSITION_FOLLOWING    = 0x04;
+  const unsigned short      DOCUMENT_POSITION_CONTAINS     = 0x08;
+  const unsigned short      DOCUMENT_POSITION_CONTAINED_BY = 0x10;
+  const unsigned short      DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 0x20;
+
+  // Introduced in DOM Level 3:
+  unsigned short     compareDocumentPosition(in nsIDOMNode other)
+                                        raises(DOMException);
+  // Introduced in DOM Level 3:
+           attribute DOMString       textContent;
+                                        // raises(DOMException) on setting
+                                        // raises(DOMException) on retrieval
+
+  // Introduced in DOM Level 3:
+  boolean            isSameNode(in nsIDOMNode other);
+  // Introduced in DOM Level 3:
+  DOMString          lookupPrefix(in DOMString namespaceURI);
+  // Introduced in DOM Level 3:
+  boolean            isDefaultNamespace(in DOMString namespaceURI);
+  // Introduced in DOM Level 3:
+  DOMString          lookupNamespaceURI(in DOMString prefix);
+  // Introduced in DOM Level 3:
+  boolean            isEqualNode(in nsIDOMNode arg);
+  // Introduced in DOM Level 3:
+  nsISupports        getFeature(in DOMString feature, 
+                                in DOMString version);
+  // Introduced in DOM Level 3:
+  nsIVariant         setUserData(in DOMString key, 
+                                 in nsIVariant data, 
+                                 in nsIDOMUserDataHandler handler);
+  // Introduced in DOM Level 3:
+  nsIVariant         getUserData(in DOMString key);
+};
--- a/dom/interfaces/core/nsIDOMNode.idl
+++ b/dom/interfaces/core/nsIDOMNode.idl
@@ -35,29 +35,26 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "domstubs.idl"
 
-interface nsIVariant;
-interface nsIDOMUserDataHandler;
-
 /**
  * The nsIDOMNode interface is the primary datatype for the entire 
  * Document Object Model.
  * It represents a single node in the document tree.
  *
  * For more information on this interface please see 
  * http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html
  */
 
-[scriptable, uuid(29a95243-c73e-454c-a996-272f6727b03c)]
+[scriptable, uuid(817dc774-2ad2-4111-9042-1787df86c015)]
 interface nsIDOMNode : nsISupports
 {
   const unsigned short      ELEMENT_NODE       = 1;
   const unsigned short      ATTRIBUTE_NODE     = 2;
   const unsigned short      TEXT_NODE          = 3;
   const unsigned short      CDATA_SECTION_NODE = 4;
   const unsigned short      ENTITY_REFERENCE_NODE = 5;
   const unsigned short      ENTITY_NODE        = 6;
@@ -103,47 +100,9 @@ interface nsIDOMNode : nsISupports
   readonly attribute DOMString        namespaceURI;
   // Modified in DOM Core
   readonly attribute DOMString        prefix;
 
   // Introduced in DOM Level 2:
   readonly attribute DOMString        localName;
   // Introduced in DOM Level 2:
   boolean            hasAttributes();
-
-  // Introduced in DOM Level 3:
-  // This uses a binaryname to avoid warnings due to name collision with
-  // nsINode::GetBaseURI
-  [binaryname(DOMBaseURI)] readonly attribute DOMString baseURI;
-
-  // DocumentPosition
-  const unsigned short      DOCUMENT_POSITION_DISCONNECTED = 0x01;
-  const unsigned short      DOCUMENT_POSITION_PRECEDING    = 0x02;
-  const unsigned short      DOCUMENT_POSITION_FOLLOWING    = 0x04;
-  const unsigned short      DOCUMENT_POSITION_CONTAINS     = 0x08;
-  const unsigned short      DOCUMENT_POSITION_CONTAINED_BY = 0x10;
-  const unsigned short      DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 0x20;
-
-  // Introduced in DOM Level 3:
-  unsigned short     compareDocumentPosition(in nsIDOMNode other)
-                                        raises(DOMException);
-  // Introduced in DOM Level 3:
-           attribute DOMString       textContent;
-                                        // raises(DOMException) on setting
-                                        // raises(DOMException) on retrieval
-
-  // Introduced in DOM Level 3:
-  boolean            isSameNode(in nsIDOMNode other);
-  // Introduced in DOM Level 3:
-  DOMString          lookupPrefix(in DOMString namespaceURI);
-  // Introduced in DOM Level 3:
-  boolean            isDefaultNamespace(in DOMString namespaceURI);
-  // Introduced in DOM Level 3:
-  DOMString          lookupNamespaceURI(in DOMString prefix);
-  // Introduced in DOM Level 3:
-  boolean            isEqualNode(in nsIDOMNode arg);
-  // Introduced in DOM Level 3:
-  nsIVariant         setUserData(in DOMString key, 
-                                 in nsIVariant data, 
-                                 in nsIDOMUserDataHandler handler);
-  // Introduced in DOM Level 3:
-  nsIVariant         getUserData(in DOMString key);
 };
--- a/editor/libeditor/html/nsHTMLEditRules.cpp
+++ b/editor/libeditor/html/nsHTMLEditRules.cpp
@@ -73,16 +73,17 @@
 #include "nsWSRunObject.h"
 
 #include "InsertTextTxn.h"
 #include "DeleteTextTxn.h"
 #include "nsReadableUtils.h"
 #include "nsUnicharUtils.h"
 
 #include "nsFrameSelection.h"
+#include "nsIDOM3Node.h"
 #include "nsContentUtils.h"
 #include "nsTArray.h"
 #include "nsIHTMLDocument.h"
 
 //const static char* kMOZEditorBogusNodeAttr="MOZ_EDITOR_BOGUS_NODE";
 //const static char* kMOZEditorBogusNodeValue="TRUE";
 
 enum
--- a/editor/txtsvc/src/nsTextServicesDocument.cpp
+++ b/editor/txtsvc/src/nsTextServicesDocument.cpp
@@ -3980,24 +3980,41 @@ nsTextServicesDocument::PrintOffsetTable
 
   fflush(stdout);
 }
 
 void
 nsTextServicesDocument::PrintContentNode(nsIContent *aContent)
 {
   nsString tmpStr, str;
+  nsresult result;
 
   aContent->Tag()->ToString(tmpStr);
   printf("%s", NS_LossyConvertUTF16toASCII(tmpStr).get());
 
-  if (nsIDOMNode::TEXT_NODE == aContent->NodeType())
+  nsCOMPtr<nsIDOMNode> node = do_QueryInterface(aContent);
+
+  if (node)
   {
-    aContent->AppendTextTo(str);
-    printf(":  \"%s\"", NS_LossyConvertUTF16toASCII(str).get());
+    PRUint16 type;
+
+    result = node->GetNodeType(&type);
+
+    if (NS_FAILED(result))
+      return;
+
+    if (nsIDOMNode::TEXT_NODE == type)
+    {
+      result = node->GetNodeValue(str);
+
+      if (NS_FAILED(result))
+        return;
+
+      printf(":  \"%s\"", NS_LossyConvertUTF16toASCII(str).get());
+    }
   }
 
   printf("\n");
   fflush(stdout);
 }
 #endif
 
 NS_IMETHODIMP
--- a/embedding/browser/activex/src/common/IEHtmlElement.cpp
+++ b/embedding/browser/activex/src/common/IEHtmlElement.cpp
@@ -41,16 +41,17 @@
 #include "nsCOMPtr.h"
 #include "nsIDOMElement.h"
 
 #include "IEHtmlElement.h"
 #include "IEHtmlElementCollection.h"
 
 #include "nsIDOMHTMLElement.h"
 #include "nsIDOMNSHTMLElement.h"
+#include "nsIDOM3Node.h"
 #include "nsIDOMDocumentRange.h"
 #include "nsIDOMRange.h"
 #include "nsIDOMNSRange.h"
 #include "nsIDOMDocumentFragment.h"
 #include "nsIDocumentEncoder.h"
 #include "nsContentCID.h"
 
 CIEHtmlElement::CIEHtmlElement()
@@ -611,37 +612,39 @@ HRESULT STDMETHODCALLTYPE CIEHtmlElement
 
     USES_CONVERSION;
     *p = SysAllocString(W2COLE(innerHTML.get()));
     return S_OK;
 }
 
 HRESULT STDMETHODCALLTYPE CIEHtmlElement::put_innerText(BSTR v)
 {
-    if (!mDOMNode)
+    nsCOMPtr<nsIDOM3Node> node = do_QueryInterface(mDOMNode);
+    if (!node)
     {
         return E_UNEXPECTED;
     }
 
     USES_CONVERSION;
     nsAutoString innerText(OLE2W(v));
-    mDOMNode->SetTextContent(innerText);
+    node->SetTextContent(innerText);
 
     return S_OK;
 }
 
 HRESULT STDMETHODCALLTYPE CIEHtmlElement::get_innerText(BSTR __RPC_FAR *p)
 {
-    if (!mDOMNode)
+    nsCOMPtr<nsIDOM3Node> node = do_QueryInterface(mDOMNode);
+    if (!node)
     {
         return E_UNEXPECTED;
     }
 
     nsAutoString innerText;
-    mDOMNode->GetTextContent(innerText);
+    node->GetTextContent(innerText);
 
     USES_CONVERSION;
     *p = SysAllocString(W2COLE(innerText.get()));
     return S_OK;
 }
 
 HRESULT STDMETHODCALLTYPE CIEHtmlElement::put_outerHTML(BSTR v)
 {
--- a/embedding/browser/webBrowser/nsDocShellTreeOwner.cpp
+++ b/embedding/browser/webBrowser/nsDocShellTreeOwner.cpp
@@ -1163,17 +1163,18 @@ DefaultTooltipTextProvider::GetNodeText(
                 aNode->GetChildNodes(getter_AddRefs(childNodes));
                 PRUint32 childNodeCount;
                 childNodes->GetLength(&childNodeCount);
                 for (PRUint32 i = 0; i < childNodeCount; i++) {
                   nsCOMPtr<nsIDOMNode>childNode;
                   childNodes->Item(i, getter_AddRefs(childNode));
                   nsCOMPtr<nsIDOMSVGTitleElement> titleElement(do_QueryInterface(childNode));
                   if (titleElement) {
-                    titleElement->GetTextContent(outText);
+                    nsCOMPtr<nsIDOM3Node> titleContent(do_QueryInterface(titleElement));
+                    titleContent->GetTextContent(outText);
                     if ( outText.Length() )
                       found = PR_TRUE;
                     break;
                   }
                 }
               }
             }
           }
--- a/embedding/components/webbrowserpersist/src/nsWebBrowserPersist.cpp
+++ b/embedding/components/webbrowserpersist/src/nsWebBrowserPersist.cpp
@@ -78,16 +78,17 @@
 #include "nsIDOMNamedNodeMap.h"
 #include "nsIDOMNodeList.h"
 #include "nsIWebProgressListener.h"
 #include "nsIAuthPrompt.h"
 #include "nsIPrompt.h"
 #include "nsISHEntry.h"
 #include "nsIWebPageDescriptor.h"
 #include "nsIFormControl.h"
+#include "nsIDOM3Node.h"
 
 #include "nsIDOMNodeFilter.h"
 #include "nsIDOMProcessingInstruction.h"
 #include "nsIDOMHTMLBodyElement.h"
 #include "nsIDOMHTMLTableElement.h"
 #include "nsIDOMHTMLTableRowElement.h"
 #include "nsIDOMHTMLTableCellElement.h"
 #include "nsIDOMHTMLAnchorElement.h"
@@ -3348,17 +3349,18 @@ nsWebBrowserPersist::CloneNodeWithFixedU
         if (NS_SUCCEEDED(rv) && *aNodeOut)
         {
             // Tell the document encoder to serialize the text child we create below
             *aSerializeCloneKids = PR_TRUE;
 
             nsAutoString valueStr;
             nodeAsTextArea->GetValue(valueStr);
             
-            (*aNodeOut)->SetTextContent(valueStr);
+            nsCOMPtr<nsIDOM3Node> out = do_QueryInterface(*aNodeOut);
+            out->SetTextContent(valueStr);
         }
         return rv;
     }
 
     nsCOMPtr<nsIDOMHTMLOptionElement> nodeAsOption = do_QueryInterface(aNodeIn);
     if (nodeAsOption)
     {
         rv = GetNodeToFixup(aNodeIn, aNodeOut);
--- a/js/src/tests/js1_5/extensions/regress-375344.js
+++ b/js/src/tests/js1_5/extensions/regress-375344.js
@@ -41,20 +41,20 @@ var summary = 'accessing prototype of DO
 var actual = '';
 var expect = '';
 
 printBugNumber(BUGNUMBER);
 printStatus (summary);
 
 if (typeof HTMLElement != 'undefined')
 {
-  expect = /Exception/;
+  expect = /Exception... "Illegal operation on WrappedNative prototype object"/;
   try 
   {
-    print(HTMLElement.prototype.nodeName);
+    print(HTMLElement.prototype.nodeName );
   }
   catch(ex) 
   {
     actual = ex + '';
     print(actual);
   }
   reportMatch(expect, actual, summary);
 }
--- a/js/src/xpconnect/src/dom_quickstubs.qsconf
+++ b/js/src/xpconnect/src/dom_quickstubs.qsconf
@@ -130,21 +130,43 @@ members = [
     'nsIDOMElement.getElementsByTagNameNS',
     'nsIDOMElement.hasAttributeNS',
     'nsIDOMElement.tagName',
     'nsIDOMElement.setAttributeNS',
     'nsIDOMElement.hasAttribute',
     'nsIDOMElement.getAttributeNS',
     'nsIDOMNamedNodeMap.item',
     'nsIDOMNamedNodeMap.length',
-    'nsIDOMNode.*',
+    'nsIDOMNode.appendChild',
+    'nsIDOMNode.nextSibling',
+    'nsIDOMNode.cloneNode',
+    'nsIDOMNode.firstChild',
+    'nsIDOMNode.prefix',
+    'nsIDOMNode.nodeValue',
+    'nsIDOMNode.childNodes',
+    'nsIDOMNode.normalize',
+    'nsIDOMNode.nodeName',
+    'nsIDOMNode.namespaceURI',
+    'nsIDOMNode.hasChildNodes',
+    'nsIDOMNode.previousSibling',
+    'nsIDOMNode.nodeType',
+    'nsIDOMNode.insertBefore',
+    'nsIDOMNode.replaceChild',
+    'nsIDOMNode.localName',
+    'nsIDOMNode.lastChild',
+    'nsIDOMNode.ownerDocument',
+    'nsIDOMNode.parentNode',
+    'nsIDOMNode.removeChild',
+    'nsIDOMNode.hasAttributes',
+    'nsIDOMNode.attributes',
     'nsIDOMNodeList.*',
     'nsIDOMNodeSelector.querySelector',
     'nsIDOMNodeSelector.querySelectorAll',
     'nsIDOMText.splitText',
+    'nsIDOM3Node.*',
     'nsIDOMDOMImplementation.*',
     'nsIDOMDOMStringList.*',
     'nsIDOMDOMTokenList.*',
     'nsIDOMDOMSettableTokenList.*',
     'nsIDOMNameList.getName',
     'nsIDOMNameList.contains',
     'nsIDOMNameList.containsNS',
     'nsIDOMNameList.length',
@@ -611,27 +633,16 @@ customMethodCalls = {
         'thisType': 'nsINode',
         'arg0Type': 'nsINode',
         'code': '    nsINode *result = self->AppendChild(arg0, &rv);\n'
                 '    if(NS_FAILED(rv))\n'
                 '        result = nsnull;'
         },
     'nsIDOMNode_GetNodeType': {
         'thisType': 'nsINode',
-        'code': 'PRUint16 result = self->NodeType();',
-        'canFail': False
-        },
-    'nsIDOMNode_GetNodeName': {
-        'thisType': 'nsINode',
-        'code': 'nsString result = self->NodeName();',
-        'canFail': False
-        },
-    'nsIDOMNode_GetLocalName': {
-        'thisType': 'nsINode',
-        'code': 'nsString result = self->LocalName();',
         'canFail': False
         },
     'nsIDOMNodeList_Item': {
         'thisType': 'nsINodeList',
         'code': '    nsINode *result = self->GetNodeAt(arg0);',
         'canFail': False
         },
     'nsIDOMHTMLDocument_': {
@@ -775,57 +786,59 @@ customMethodCalls = {
                 'nsGenericElement::doQuerySelector(self, arg0, &rv);'
         },
     'nsIDOMNodeSelector_QuerySelectorAll': {
         'thisType': 'nsINode',
         'code': '    nsCOMPtr<nsIDOMNodeList> result;\n'
                 '    rv = nsGenericElement::doQuerySelectorAll(self, '
                 'arg0, getter_AddRefs(result));'
         },
-    'nsIDOMNode_GetBaseURI': {
+    'nsIDOM3Node_': {
+        'thisType': 'nsINode'
+        },
+    'nsIDOM3Node_GetBaseURI': {
         'thisType': 'nsINode',
         'canFail': False
         },
-    'nsIDOMNode_CompareDocumentPosition': {
+    'nsIDOM3Node_CompareDocumentPosition': {
         'thisType': 'nsINode',
-        'arg0Type': 'nsINode',
-        'code': '    PRUint16 result;\n'
-                '    rv = self->CompareDocPosition(arg0, &result);',
-        'canFail': True
+        'arg0Type': 'nsINode'
         },
-    'nsIDOMNode_GetTextContent': {
+    'nsIDOM3Node_GetTextContent': {
         'thisType': 'nsINode',
         'canFail': False
         },
     'nsIDOM3Node_IsSameNode': {
         'thisType': 'nsINode',
         'arg0Type': 'nsINode',
-        'code': '    PRBool result = self == arg0;',
+        'code': '    PRBool result = self->IsSameNode(arg0);',
         'canFail': False
         },
-    'nsIDOMNode_LookupPrefix': {
-        'thisType': 'nsINode',
-        'canFail': False
-        },
-    'nsIDOMNode_IsDefaultNamespace': {
+    'nsIDOM3Node_LookupPrefix': {
         'thisType': 'nsINode',
         'canFail': False
         },
-    'nsIDOMNode_LookupNamespaceURI': {
+    'nsIDOM3Node_IsDefaultNamespace': {
+        'thisType': 'nsINode',
+        'code': '    PRBool result = self->IsDefaultNamespace(arg0);',
+        'canFail': False
+        },
+    'nsIDOM3Node_LookupNamespaceURI': {
         'thisType': 'nsINode',
         'canFail': False
         },
-    'nsIDOMNode_IsEqualNode': {
+    'nsIDOM3Node_IsEqualNode': {
         'thisType': 'nsINode',
         'arg0Type': 'nsINode',
-        'code': '    PRBool result = self->IsEqualTo(arg0);',
+        'code': '    PRBool result = self->IsEqualNode(arg0);',
         'canFail': False
         },
-    'nsIDOMNode_GetUserData': {
+    'nsIDOM3Node_GetUserData': {
         'thisType': 'nsINode',
+        'code': '    nsIVariant *result = self->GetUserData(arg0);',
         'canFail': False
         },
     'nsIDOMNSHTMLElement_': {
         'thisType': 'nsGenericHTMLElement'
         },
     'nsIDOMHTMLElement_': {
         'thisType': 'nsGenericHTMLElement'
         },
@@ -861,21 +874,16 @@ customMethodCalls = {
         'thisType': 'nsDocument',
         'code': '    nsRefPtr<nsContentList> result ='
                 'self->GetElementsByTagNameNS(arg0, arg1);',
         'canFail': False
         },
     'nsIDOMElement_': {
         'thisType': 'nsGenericElement'
         },
-    'nsIDOMElement_GetTagName': {
-        'thisType': 'nsINode',
-        'code': 'nsString result = self->NodeName();',
-        'canFail': False
-        },
     'nsIDOMDocument_CreateElement': {
         'thisType': 'nsDocument',
         'code': '    nsCOMPtr<nsIContent> result;\n'
                 '    rv = self->CreateElement(arg0, getter_AddRefs(result));'
     },
     'nsIDOMDocument_CreateElementNS': {
         'thisType': 'nsDocument',
         'code': '    nsCOMPtr<nsIContent> result;\n'
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -1530,19 +1530,18 @@ nsCSSFrameConstructor::CreateGeneratedCo
       // image object
       return nsnull;
     }
     
     // Create an image content object and pass it the image request.
     // XXX Check if it's an image type we can handle...
 
     nsCOMPtr<nsINodeInfo> nodeInfo;
-    nodeInfo = mDocument->NodeInfoManager()->
-      GetNodeInfo(nsGkAtoms::mozgeneratedcontentimage, nsnull,
-                  kNameSpaceID_XHTML, nsIDOMNode::ELEMENT_NODE);
+    nodeInfo = mDocument->NodeInfoManager()->GetNodeInfo(nsGkAtoms::mozgeneratedcontentimage, nsnull,
+                                                         kNameSpaceID_XHTML);
 
     nsCOMPtr<nsIContent> content;
     NS_NewGenConImageContent(getter_AddRefs(content), nodeInfo.forget(),
                              data.mContent.mImage);
     return content.forget();
   }
 
   switch (type) {
@@ -1708,18 +1707,17 @@ nsCSSFrameConstructor::CreateGeneratedCo
   if (!pseudoStyleContext)
     return;
   // |ProbePseudoStyleFor| checked the 'display' property and the
   // |ContentCount()| of the 'content' property for us.
   nsCOMPtr<nsINodeInfo> nodeInfo;
   nsIAtom* elemName = aPseudoElement == nsCSSPseudoElements::ePseudo_before ?
     nsGkAtoms::mozgeneratedcontentbefore : nsGkAtoms::mozgeneratedcontentafter;
   nodeInfo = mDocument->NodeInfoManager()->GetNodeInfo(elemName, nsnull,
-                                                       kNameSpaceID_None,
-                                                       nsIDOMNode::ELEMENT_NODE);
+                                                       kNameSpaceID_None);
   nsCOMPtr<nsIContent> container;
   nsresult rv = NS_NewXMLElement(getter_AddRefs(container), nodeInfo.forget());
   if (NS_FAILED(rv))
     return;
   container->SetNativeAnonymous();
 
   rv = container->BindToTree(mDocument, aParentContent, aParentContent, PR_TRUE);
   if (NS_FAILED(rv)) {
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -91,16 +91,17 @@
 #include "nsISelection.h"
 #include "nsISelectionController.h"
 #include "nsISelectionPrivate.h"
 #include "nsLayoutCID.h"
 #include "nsGkAtoms.h"
 #include "nsIDOMRange.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOMNode.h"
+#include "nsIDOM3Node.h"
 #include "nsIDOMNodeList.h"
 #include "nsIDOMElement.h"
 #include "nsRange.h"
 #include "nsCSSPseudoElements.h"
 #include "nsCOMPtr.h"
 #include "nsAutoPtr.h"
 #include "nsReadableUtils.h"
 #include "nsUnicharUtils.h"
@@ -4397,19 +4398,28 @@ nsresult PresShell::GetLinkLocation(nsID
         if (element) {
           NS_NAMED_LITERAL_STRING(xlinkNS,"http://www.w3.org/1999/xlink");
           element->GetAttributeNS(xlinkNS,NS_LITERAL_STRING("type"),xlinkType);
           if (xlinkType.EqualsLiteral("simple")) {
             element->GetAttributeNS(xlinkNS,NS_LITERAL_STRING("href"),anchorText);
             if (!anchorText.IsEmpty()) {
               // Resolve the full URI using baseURI property
 
-              nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
-              NS_ENSURE_TRUE(node, NS_ERROR_UNEXPECTED);
-              nsCOMPtr<nsIURI> baseURI = node->GetBaseURI();
+              nsAutoString base;
+              nsCOMPtr<nsIDOM3Node> node(do_QueryInterface(aNode,&rv));
+              NS_ENSURE_SUCCESS(rv, rv);
+              node->GetBaseURI(base);
+
+              nsCOMPtr<nsIIOService>
+                ios(do_GetService("@mozilla.org/network/io-service;1", &rv));
+              NS_ENSURE_SUCCESS(rv, rv);
+
+              nsCOMPtr<nsIURI> baseURI;
+              rv = ios->NewURI(NS_ConvertUTF16toUTF8(base),nsnull,nsnull,getter_AddRefs(baseURI));
+              NS_ENSURE_SUCCESS(rv, rv);
 
               nsCAutoString spec;
               rv = baseURI->Resolve(NS_ConvertUTF16toUTF8(anchorText),spec);
               NS_ENSURE_SUCCESS(rv, rv);
 
               CopyUTF8toUTF16(spec, anchorText);
             }
           }
--- a/layout/build/nsContentDLF.cpp
+++ b/layout/build/nsContentDLF.cpp
@@ -373,30 +373,27 @@ nsContentDLF::CreateBlankDocument(nsILoa
   if (NS_SUCCEEDED(rv)) {
     rv = NS_ERROR_FAILURE;
 
     nsNodeInfoManager *nim = blankDoc->NodeInfoManager();
 
     nsCOMPtr<nsINodeInfo> htmlNodeInfo;
 
     // generate an html html element
-    htmlNodeInfo = nim->GetNodeInfo(nsGkAtoms::html, 0, kNameSpaceID_XHTML,
-                                    nsIDOMNode::ELEMENT_NODE);
+    htmlNodeInfo = nim->GetNodeInfo(nsGkAtoms::html, 0, kNameSpaceID_XHTML);
     nsCOMPtr<nsIContent> htmlElement =
       NS_NewHTMLHtmlElement(htmlNodeInfo.forget());
 
     // generate an html head element
-    htmlNodeInfo = nim->GetNodeInfo(nsGkAtoms::head, 0, kNameSpaceID_XHTML,
-                                    nsIDOMNode::ELEMENT_NODE);
+    htmlNodeInfo = nim->GetNodeInfo(nsGkAtoms::head, 0, kNameSpaceID_XHTML);
     nsCOMPtr<nsIContent> headElement =
       NS_NewHTMLHeadElement(htmlNodeInfo.forget());
 
     // generate an html body elemment
-    htmlNodeInfo = nim->GetNodeInfo(nsGkAtoms::body, 0, kNameSpaceID_XHTML,
-                                    nsIDOMNode::ELEMENT_NODE);
+    htmlNodeInfo = nim->GetNodeInfo(nsGkAtoms::body, 0, kNameSpaceID_XHTML);
     nsCOMPtr<nsIContent> bodyElement =
       NS_NewHTMLBodyElement(htmlNodeInfo.forget());
 
     // blat in the structure
     if (htmlElement && headElement && bodyElement) {
       NS_ASSERTION(blankDoc->GetChildCount() == 0,
                    "Shouldn't have children");
       rv = blankDoc->AppendChildTo(htmlElement, PR_FALSE);
--- a/layout/forms/nsComboboxControlFrame.cpp
+++ b/layout/forms/nsComboboxControlFrame.cpp
@@ -1024,18 +1024,17 @@ nsComboboxControlFrame::CreateAnonymousC
     mListControlFrame->GetOptionText(mDisplayedIndex, mDisplayedOptionText);
   }
   ActuallyDisplayText(PR_FALSE);
 
   if (!aElements.AppendElement(mDisplayContent))
     return NS_ERROR_OUT_OF_MEMORY;
 
   nsCOMPtr<nsINodeInfo> nodeInfo;
-  nodeInfo = nimgr->GetNodeInfo(nsGkAtoms::button, nsnull, kNameSpaceID_XHTML,
-                                nsIDOMNode::ELEMENT_NODE);
+  nodeInfo = nimgr->GetNodeInfo(nsGkAtoms::button, nsnull, kNameSpaceID_XHTML);
 
   // create button which drops the list down
   NS_NewHTMLElement(getter_AddRefs(mButtonContent), nodeInfo.forget(),
                     dom::NOT_FROM_PARSER);
   if (!mButtonContent)
     return NS_ERROR_OUT_OF_MEMORY;
 
   // make someone to listen to the button. If its pressed by someone like Accessibility
--- a/layout/forms/nsFileControlFrame.cpp
+++ b/layout/forms/nsFileControlFrame.cpp
@@ -232,18 +232,17 @@ PRBool CapturePickerAcceptCallback(const
 nsresult
 nsFileControlFrame::CreateAnonymousContent(nsTArray<ContentInfo>& aElements)
 {
   // Get the NodeInfoManager and tag necessary to create input elements
   nsCOMPtr<nsIDocument> doc = mContent->GetDocument();
 
   nsCOMPtr<nsINodeInfo> nodeInfo;
   nodeInfo = doc->NodeInfoManager()->GetNodeInfo(nsGkAtoms::input, nsnull,
-                                                 kNameSpaceID_XHTML,
-                                                 nsIDOMNode::ELEMENT_NODE);
+                                                 kNameSpaceID_XHTML);
 
   // Create the text content
   NS_NewHTMLElement(getter_AddRefs(mTextContent), nodeInfo.forget(),
                     dom::NOT_FROM_PARSER);
   if (!mTextContent)
     return NS_ERROR_OUT_OF_MEMORY;
 
   // Mark the element to be native anonymous before setting any attributes.
@@ -287,18 +286,17 @@ nsFileControlFrame::CreateAnonymousConte
   NS_ENSURE_STATE(dom3TextContent);
   // Register as an event listener of the textbox
   // to open file dialog on mouse click
   dom3TextContent->AddGroupedEventListener(click, mMouseListener, PR_FALSE,
                                            systemGroup);
 
   // Create the browse button
   nodeInfo = doc->NodeInfoManager()->GetNodeInfo(nsGkAtoms::input, nsnull,
-                                                 kNameSpaceID_XHTML,
-                                                 nsIDOMNode::ELEMENT_NODE);
+                                                 kNameSpaceID_XHTML);
   NS_NewHTMLElement(getter_AddRefs(mBrowse), nodeInfo.forget(),
                     dom::NOT_FROM_PARSER);
   if (!mBrowse)
     return NS_ERROR_OUT_OF_MEMORY;
 
   // Mark the element to be native anonymous before setting any attributes.
   mBrowse->SetNativeAnonymous();
 
@@ -314,18 +312,17 @@ nsFileControlFrame::CreateAnonymousConte
     CaptureCallbackData data;
     data.picker = capturePicker;
     data.mode = &mode;
     ParseAcceptAttribute(&CapturePickerAcceptCallback, (void*)&data);
 
     if (mode != 0) {
       mCaptureMouseListener->mMode = mode;
       nodeInfo = doc->NodeInfoManager()->GetNodeInfo(nsGkAtoms::input, nsnull,
-                                                     kNameSpaceID_XHTML,
-                                                     nsIDOMNode::ELEMENT_NODE);
+                                                     kNameSpaceID_XHTML);
       NS_NewHTMLElement(getter_AddRefs(mCapture), nodeInfo.forget(),
                         dom::NOT_FROM_PARSER);
       if (!mCapture)
         return NS_ERROR_OUT_OF_MEMORY;
 
       // Mark the element to be native anonymous before setting any attributes.
       mCapture->SetNativeAnonymous();
 
--- a/layout/forms/nsIsIndexFrame.cpp
+++ b/layout/forms/nsIsIndexFrame.cpp
@@ -190,18 +190,17 @@ nsresult
 nsIsIndexFrame::CreateAnonymousContent(nsTArray<ContentInfo>& aElements)
 {
   // Get the node info manager (used to create hr's and input's)
   nsCOMPtr<nsIDocument> doc = mContent->GetDocument();
   nsNodeInfoManager *nimgr = doc->NodeInfoManager();
 
   // Create an hr
   nsCOMPtr<nsINodeInfo> hrInfo;
-  hrInfo = nimgr->GetNodeInfo(nsGkAtoms::hr, nsnull, kNameSpaceID_XHTML,
-                              nsIDOMNode::ELEMENT_NODE);
+  hrInfo = nimgr->GetNodeInfo(nsGkAtoms::hr, nsnull, kNameSpaceID_XHTML);
 
   NS_NewHTMLElement(getter_AddRefs(mPreHr), hrInfo.forget(),
                     dom::NOT_FROM_PARSER);
   if (!mPreHr || !aElements.AppendElement(mPreHr))
     return NS_ERROR_OUT_OF_MEMORY;
 
   // Add a child text content node for the label
   NS_NewTextNode(getter_AddRefs(mTextContent), nimgr);
@@ -210,18 +209,17 @@ nsIsIndexFrame::CreateAnonymousContent(n
 
   // set the value of the text node and add it to the child list
   UpdatePromptLabel(PR_FALSE);
   if (!aElements.AppendElement(mTextContent))
     return NS_ERROR_OUT_OF_MEMORY;
 
   // Create text input field
   nsCOMPtr<nsINodeInfo> inputInfo;
-  inputInfo = nimgr->GetNodeInfo(nsGkAtoms::input, nsnull, kNameSpaceID_XHTML,
-                                 nsIDOMNode::ELEMENT_NODE);
+  inputInfo = nimgr->GetNodeInfo(nsGkAtoms::input, nsnull, kNameSpaceID_XHTML);
 
   NS_NewHTMLElement(getter_AddRefs(mInputContent), inputInfo.forget(),
                     dom::NOT_FROM_PARSER);
   if (!mInputContent)
     return NS_ERROR_OUT_OF_MEMORY;
 
   mInputContent->SetAttr(kNameSpaceID_None, nsGkAtoms::type,
                          NS_LITERAL_STRING("text"), PR_FALSE);
@@ -229,18 +227,17 @@ nsIsIndexFrame::CreateAnonymousContent(n
   if (!aElements.AppendElement(mInputContent))
     return NS_ERROR_OUT_OF_MEMORY;
 
   // Register as an event listener to submit on Enter press
   mListener = new nsIsIndexFrame::KeyListener(this);
   mInputContent->AddEventListenerByIID(mListener, NS_GET_IID(nsIDOMKeyListener));
 
   // Create an hr
-  hrInfo = nimgr->GetNodeInfo(nsGkAtoms::hr, nsnull, kNameSpaceID_XHTML,
-                              nsIDOMNode::ELEMENT_NODE);
+  hrInfo = nimgr->GetNodeInfo(nsGkAtoms::hr, nsnull, kNameSpaceID_XHTML);
   NS_NewHTMLElement(getter_AddRefs(mPostHr), hrInfo.forget(),
                     dom::NOT_FROM_PARSER);
   if (!mPostHr || !aElements.AppendElement(mPostHr))
     return NS_ERROR_OUT_OF_MEMORY;
 
   return NS_OK;
 }
 
--- a/layout/forms/nsProgressFrame.cpp
+++ b/layout/forms/nsProgressFrame.cpp
@@ -85,18 +85,17 @@ nsProgressFrame::DestroyFrom(nsIFrame* a
 nsresult
 nsProgressFrame::CreateAnonymousContent(nsTArray<ContentInfo>& aElements)
 {
   // Get the NodeInfoManager and tag necessary to create the progress bar div.
   nsCOMPtr<nsIDocument> doc = mContent->GetDocument();
 
   nsCOMPtr<nsINodeInfo> nodeInfo;
   nodeInfo = doc->NodeInfoManager()->GetNodeInfo(nsGkAtoms::div, nsnull,
-                                                 kNameSpaceID_XHTML,
-                                                 nsIDOMNode::ELEMENT_NODE);
+                                                 kNameSpaceID_XHTML);
   NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
 
   // Create the div.
   nsresult rv = NS_NewHTMLElement(getter_AddRefs(mBarDiv), nodeInfo.forget(),
                                   mozilla::dom::NOT_FROM_PARSER);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Associate ::-moz-progress-bar pseudo-element to the anonymous child.
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -2432,18 +2432,17 @@ nsGfxScrollFrameInner::CreateAnonymousCo
       return NS_OK;
     }
   }
 
   nsNodeInfoManager *nodeInfoManager =
     presContext->Document()->NodeInfoManager();
   nsCOMPtr<nsINodeInfo> nodeInfo;
   nodeInfo = nodeInfoManager->GetNodeInfo(nsGkAtoms::scrollbar, nsnull,
-                                          kNameSpaceID_XUL,
-                                          nsIDOMNode::ELEMENT_NODE);
+                                          kNameSpaceID_XUL);
   NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
 
   if (canHaveHorizontal) {
     nsCOMPtr<nsINodeInfo> ni = nodeInfo;
     NS_TrustedNewXULElement(getter_AddRefs(mHScrollbarContent), ni.forget());
     mHScrollbarContent->SetAttr(kNameSpaceID_None, nsGkAtoms::orient,
                                 NS_LITERAL_STRING("horizontal"), PR_FALSE);
     mHScrollbarContent->SetAttr(kNameSpaceID_None, nsGkAtoms::clickthrough,
@@ -2461,18 +2460,17 @@ nsGfxScrollFrameInner::CreateAnonymousCo
                                 NS_LITERAL_STRING("always"), PR_FALSE);
     if (!aElements.AppendElement(mVScrollbarContent))
       return NS_ERROR_OUT_OF_MEMORY;
   }
 
   if (isResizable) {
     nsCOMPtr<nsINodeInfo> nodeInfo;
     nodeInfo = nodeInfoManager->GetNodeInfo(nsGkAtoms::resizer, nsnull,
-                                            kNameSpaceID_XUL,
-                                            nsIDOMNode::ELEMENT_NODE);
+                                            kNameSpaceID_XUL);
     NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
 
     NS_TrustedNewXULElement(getter_AddRefs(mResizerContent), nodeInfo.forget());
 
     nsAutoString dir;
     switch (resizeStyle) {
       case NS_STYLE_RESIZE_HORIZONTAL:
         if (IsScrollbarOnRight()) {
@@ -2507,18 +2505,17 @@ nsGfxScrollFrameInner::CreateAnonymousCo
                                   NS_LITERAL_STRING("always"), PR_FALSE);
 
     if (!aElements.AppendElement(mResizerContent))
       return NS_ERROR_OUT_OF_MEMORY;
   }
 
   if (canHaveHorizontal && canHaveVertical) {
     nodeInfo = nodeInfoManager->GetNodeInfo(nsGkAtoms::scrollcorner, nsnull,
-                                            kNameSpaceID_XUL,
-                                            nsIDOMNode::ELEMENT_NODE);
+                                            kNameSpaceID_XUL);
     NS_TrustedNewXULElement(getter_AddRefs(mScrollCornerContent), nodeInfo.forget());
     if (!aElements.AppendElement(mScrollCornerContent))
       return NS_ERROR_OUT_OF_MEMORY;
   }
 
   return NS_OK;
 }
 
--- a/layout/generic/nsVideoFrame.cpp
+++ b/layout/generic/nsVideoFrame.cpp
@@ -95,18 +95,17 @@ nsVideoFrame::CreateAnonymousContent(nsT
   nsNodeInfoManager *nodeInfoManager = GetContent()->GetCurrentDoc()->NodeInfoManager();
   nsCOMPtr<nsINodeInfo> nodeInfo;
   if (HasVideoElement()) {
     // Create an anonymous image element as a child to hold the poster
     // image. We may not have a poster image now, but one could be added
     // before we load, or on a subsequent load.
     nodeInfo = nodeInfoManager->GetNodeInfo(nsGkAtoms::img,
                                             nsnull,
-                                            kNameSpaceID_XHTML,
-                                            nsIDOMNode::ELEMENT_NODE);
+                                            kNameSpaceID_XHTML);
     NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
     Element* element = NS_NewHTMLImageElement(nodeInfo.forget());
     mPosterImage = element;
     NS_ENSURE_TRUE(mPosterImage, NS_ERROR_OUT_OF_MEMORY);
 
     // Push a null JSContext on the stack so that code that runs
     // within the below code doesn't think it's being called by
     // JS. See bug 604262.
@@ -130,18 +129,17 @@ nsVideoFrame::CreateAnonymousContent(nsT
     if (!aElements.AppendElement(mPosterImage))
       return NS_ERROR_OUT_OF_MEMORY;
   }
 
   // Set up "videocontrols" XUL element which will be XBL-bound to the
   // actual controls.
   nodeInfo = nodeInfoManager->GetNodeInfo(nsGkAtoms::videocontrols,
                                           nsnull,
-                                          kNameSpaceID_XUL,
-                                          nsIDOMNode::ELEMENT_NODE);
+                                          kNameSpaceID_XUL);
   NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
 
   NS_TrustedNewXULElement(getter_AddRefs(mVideoControls), nodeInfo.forget());
   if (!aElements.AppendElement(mVideoControls))
     return NS_ERROR_OUT_OF_MEMORY;
 
   return NS_OK;
 }
--- a/layout/inspector/src/inCSSValueSearch.cpp
+++ b/layout/inspector/src/inCSSValueSearch.cpp
@@ -37,16 +37,17 @@
 
 #include "inCSSValueSearch.h"
 
 #include "nsIComponentManager.h"
 #include "nsIServiceManager.h"
 #include "nsVoidArray.h"
 #include "nsReadableUtils.h"
 #include "nsIDOMDocument.h"
+#include "nsIDOM3Node.h"
 #include "nsIDOMStyleSheetList.h"
 #include "nsIDOMCSSStyleSheet.h"
 #include "nsIDOMCSSRuleList.h"
 #include "nsIDOMCSSStyleRule.h"
 #include "nsIDOMCSSStyleDeclaration.h"
 #include "nsIDOMCSSImportRule.h"
 #include "nsIDOMCSSMediaRule.h"
 #include "nsIURI.h"
@@ -107,38 +108,40 @@ inCSSValueSearch::SetHoldResults(PRBool 
   return NS_OK;
 }
 
 NS_IMETHODIMP 
 inCSSValueSearch::SearchSync()
 {
   InitSearch();
 
-  if (!mDocument) {
-    return NS_OK;
+  nsCOMPtr<nsIURI> baseURL;
+  nsCOMPtr<nsIDOM3Node> dom3Node = do_QueryInterface(mDocument);
+  if (dom3Node) {
+    nsAutoString uri;
+    dom3Node->GetBaseURI(uri);
+    NS_NewURI(getter_AddRefs(baseURL), uri);
   }
 
-  nsCOMPtr<nsIURI> baseURI;
-  nsCOMPtr<nsIDocument> idoc = do_QueryInterface(mDocument);
-  if (idoc) {
-    baseURI = idoc->GetBaseURI();
+  if (!mDocument) {
+    return NS_OK;
   }
 
   nsCOMPtr<nsIDOMStyleSheetList> sheets;
   nsresult rv = mDocument->GetStyleSheets(getter_AddRefs(sheets));
   NS_ENSURE_SUCCESS(rv, NS_OK);
 
   PRUint32 length;
   sheets->GetLength(&length);
   for (PRUint32 i = 0; i < length; ++i) {
     nsCOMPtr<nsIDOMStyleSheet> sheet;
     sheets->Item(i, getter_AddRefs(sheet));
     nsCOMPtr<nsIDOMCSSStyleSheet> cssSheet = do_QueryInterface(sheet);
     if (cssSheet)
-      SearchStyleSheet(cssSheet, baseURI);
+      SearchStyleSheet(cssSheet, baseURL);
   }
 
   // XXX would be nice to search inline style as well.
 
   return NS_OK;
 }
 
 NS_IMETHODIMP 
--- a/layout/style/Loader.cpp
+++ b/layout/style/Loader.cpp
@@ -69,16 +69,17 @@
 #include "nsCRT.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsContentPolicyUtils.h"
 #include "nsITimelineService.h"
 #include "nsIHttpChannel.h"
 #include "nsIScriptError.h"
 #include "nsMimeTypes.h"
 #include "nsIAtom.h"
+#include "nsIDOM3Node.h"
 #include "nsCSSStyleSheet.h"
 #include "nsIStyleSheetLinkingElement.h"
 #include "nsICSSLoaderObserver.h"
 #include "nsCSSParser.h"
 #include "mozilla/css/ImportRule.h"
 #include "nsThreadUtils.h"
 #include "nsGkAtoms.h"
 #include "nsDocShellCID.h"
--- a/layout/xul/base/src/nsDocElementBoxFrame.cpp
+++ b/layout/xul/base/src/nsDocElementBoxFrame.cpp
@@ -117,31 +117,29 @@ nsDocElementBoxFrame::CreateAnonymousCon
     // The page is currently being torn down.  Why bother.
     return NS_ERROR_FAILURE;
   }
   nsNodeInfoManager *nodeInfoManager = doc->NodeInfoManager();
 
   // create the top-secret popupgroup node. shhhhh!
   nsCOMPtr<nsINodeInfo> nodeInfo;
   nodeInfo = nodeInfoManager->GetNodeInfo(nsGkAtoms::popupgroup,
-                                          nsnull, kNameSpaceID_XUL,
-                                          nsIDOMNode::ELEMENT_NODE);
+                                          nsnull, kNameSpaceID_XUL);
   NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
 
   nsresult rv = NS_NewXULElement(getter_AddRefs(mPopupgroupContent),
                                  nodeInfo.forget());
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (!aElements.AppendElement(mPopupgroupContent))
     return NS_ERROR_OUT_OF_MEMORY;
 
   // create the top-secret default tooltip node. shhhhh!
   nodeInfo = nodeInfoManager->GetNodeInfo(nsGkAtoms::tooltip, nsnull,
-                                          kNameSpaceID_XUL,
-                                          nsIDOMNode::ELEMENT_NODE);
+                                          kNameSpaceID_XUL);
   NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
 
   rv = NS_NewXULElement(getter_AddRefs(mTooltipContent), nodeInfo.forget());
   NS_ENSURE_SUCCESS(rv, rv);
 
   mTooltipContent->SetAttr(nsnull, nsGkAtoms::_default,
                            NS_LITERAL_STRING("true"), PR_FALSE);
 
--- a/netwerk/test/httpserver/test/test_default_index_handler.js
+++ b/netwerk/test/httpserver/test/test_default_index_handler.js
@@ -144,17 +144,17 @@ function hiddenDataCheck(bytes, uri, pat
   do_check_eq(body.length, 1);
   body = body.item(0);
 
   // header
   var header = body.QueryInterface(Ci.nsIDOMElement)
                    .getElementsByTagName("h1");
   do_check_eq(header.length, 1);
 
-  do_check_eq(header.item(0).QueryInterface(Ci.nsIDOMNode).textContent, path);
+  do_check_eq(header.item(0).QueryInterface(Ci.nsIDOM3Node).textContent, path);
 
   // files
   var lst = body.getElementsByTagName("ol");
   do_check_eq(lst.length, 1);
   var items = lst.item(0).QueryInterface(Ci.nsIDOMElement)
                          .getElementsByTagName("li");
 
   var ios = Cc["@mozilla.org/network/io-service;1"]
@@ -166,17 +166,17 @@ function hiddenDataCheck(bytes, uri, pat
   var dirEntries = [{name: "file.txt", isDirectory: false},
                     {name: "SHOULD_SEE_THIS.txt^", isDirectory: false}];
 
   for (var i = 0; i < items.length; i++)
   {
     var link = items.item(i)
                     .childNodes
                     .item(0)
-                    .QueryInterface(Ci.nsIDOMNode)
+                    .QueryInterface(Ci.nsIDOM3Node)
                     .QueryInterface(Ci.nsIDOMElement);
     var f = dirEntries[i];
 
     var sep = f.isDirectory ? "/" : "";
 
     do_check_eq(link.textContent, f.name + sep);
 
     uri = ios.newURI(link.getAttribute("href"), null, top);
@@ -228,17 +228,17 @@ function dataCheck(bytes, uri, path, dir
   do_check_eq(body.length, 1);
   body = body.item(0);
 
   // header
   var header = body.QueryInterface(Ci.nsIDOMElement)
                    .getElementsByTagName("h1");
   do_check_eq(header.length, 1);
 
-  do_check_eq(header.item(0).QueryInterface(Ci.nsIDOMNode).textContent, path);
+  do_check_eq(header.item(0).QueryInterface(Ci.nsIDOM3Node).textContent, path);
 
   // files
   var lst = body.getElementsByTagName("ol");
   do_check_eq(lst.length, 1);
   var items = lst.item(0).QueryInterface(Ci.nsIDOMElement)
                          .getElementsByTagName("li");
 
   var ios = Cc["@mozilla.org/network/io-service;1"]
@@ -246,17 +246,17 @@ function dataCheck(bytes, uri, path, dir
 
   var dirURI = ios.newURI(uri, null, null);
 
   for (var i = 0; i < items.length; i++)
   {
     var link = items.item(i)
                     .childNodes
                     .item(0)
-                    .QueryInterface(Ci.nsIDOMNode)
+                    .QueryInterface(Ci.nsIDOM3Node)
                     .QueryInterface(Ci.nsIDOMElement);
     var f = dirEntries[i];
 
     var sep = f.isDirectory ? "/" : "";
 
     do_check_eq(link.textContent, f.name + sep);
 
     uri = ios.newURI(link.getAttribute("href"), null, top);
--- a/parser/html/nsHtml5TreeOperation.cpp
+++ b/parser/html/nsHtml5TreeOperation.cpp
@@ -372,18 +372,17 @@ nsHtml5TreeOperation::Perform(nsHtml5Tre
       nsHtml5HtmlAttributes* attributes = mThree.attributes;
       
       PRBool isKeygen = (name == nsHtml5Atoms::keygen && ns == kNameSpaceID_XHTML);
       if (NS_UNLIKELY(isKeygen)) {
         name = nsHtml5Atoms::select;
       }
       
       nsCOMPtr<nsIContent> newContent;
-      nsCOMPtr<nsINodeInfo> nodeInfo = aBuilder->GetNodeInfoManager()->
-        GetNodeInfo(name, nsnull, ns, nsIDOMNode::ELEMENT_NODE);
+      nsCOMPtr<nsINodeInfo> nodeInfo = aBuilder->GetNodeInfoManager()->GetNodeInfo(name, nsnull, ns);
       NS_ASSERTION(nodeInfo, "Got null nodeinfo.");
       NS_NewElement(getter_AddRefs(newContent),
                     ns, nodeInfo.forget(),
                     (mOpCode == eTreeOpCreateElementNetwork ?
                      dom::FROM_PARSER_NETWORK
                      : (aBuilder->IsFragmentMode() ?
                         dom::FROM_PARSER_FRAGMENT :
                         dom::FROM_PARSER_DOCUMENT_WRITE)));
@@ -414,18 +413,17 @@ nsHtml5TreeOperation::Perform(nsHtml5Tre
                             nsGkAtoms::moztype, 
                             nsnull, 
                             theAttribute,
                             PR_FALSE);
 
         nsCOMPtr<nsINodeInfo> optionNodeInfo = 
           aBuilder->GetNodeInfoManager()->GetNodeInfo(nsHtml5Atoms::option, 
                                                       nsnull, 
-                                                      kNameSpaceID_XHTML,
-                                                      nsIDOMNode::ELEMENT_NODE);
+                                                      kNameSpaceID_XHTML);
                                                       
         for (PRUint32 i = 0; i < theContent.Length(); ++i) {
           nsCOMPtr<nsIContent> optionElt;
           nsCOMPtr<nsINodeInfo> ni = optionNodeInfo;
           NS_NewElement(getter_AddRefs(optionElt), 
                         optionNodeInfo->NamespaceID(), 
                         ni.forget(),
                         (mOpCode == eTreeOpCreateElementNetwork ?
--- a/widget/src/xpwidgets/GfxInfoBase.cpp
+++ b/widget/src/xpwidgets/GfxInfoBase.cpp
@@ -45,16 +45,17 @@
 #include "nsCOMArray.h"
 #include "nsAutoPtr.h"
 #include "nsString.h"
 #include "mozilla/Services.h"
 #include "nsIObserver.h"
 #include "nsIObserverService.h"
 #include "nsIDOMElement.h"
 #include "nsIDOMNode.h"
+#include "nsIDOM3Node.h"
 #include "nsIDOMNodeList.h"
 #include "nsTArray.h"
 #include "mozilla/Preferences.h"
 
 #if defined(MOZ_CRASHREPORTER)
 #include "nsExceptionHandler.h"
 #endif
 
@@ -211,18 +212,22 @@ RemovePrefForDriverVersion()
 {
   Preferences::ClearUser(SUGGESTED_VERSION_PREF);
 }
 
 // <foo>Hello</foo> - "Hello" is stored as a child text node of the foo node.
 static bool
 BlacklistNodeToTextValue(nsIDOMNode *aBlacklistNode, nsAString& aValue)
 {
+  nsCOMPtr<nsIDOM3Node> dom3 = do_QueryInterface(aBlacklistNode);
+  if (!dom3)
+    return false;
+
   nsAutoString value;
-  if (NS_FAILED(aBlacklistNode->GetTextContent(value)))
+  if (NS_FAILED(dom3->GetTextContent(value)))
     return false;
 
   value.Trim(" \t\r\n");
   aValue = value;
 
   return true;
 }