Merge mozilla-central into the "branch" for but 568691. The omnijar XPT/component/chrome registration was removed during this merge, and will be re-added to the component manager shortly.
authorBenjamin Smedberg <benjamin@smedbergs.us>
Mon, 21 Jun 2010 11:41:42 -0400
changeset 47008 79ae7224e6273199d0db9638043e531942bc10fd
parent 47007 6f1e1300abcd96e3b5f7fd5bbab69fd836c1c2bf (current diff)
parent 43888 abb7ee444c3186da1e4c5cbe4056462ee2ad6e6f (diff)
child 47009 34a044089fae65c9c51d83bfbb058bf12a792e46
push idunknown
push userunknown
push dateunknown
bugs568691
milestone1.9.3a6pre
Merge mozilla-central into the "branch" for but 568691. The omnijar XPT/component/chrome registration was removed during this merge, and will be re-added to the component manager shortly.
accessible/src/base/nsAccIterator.cpp
accessible/src/base/nsAccIterator.h
accessible/tests/mochitest/test_invalidate_accessnode.html
browser/installer/windows/msi/firefox.mm
browser/installer/windows/msi/firefox.ver
browser/installer/windows/msi/make-msi.pl
chrome/public/Makefile.in
chrome/public/nsIChromeRegistry.idl
chrome/src/nsChromeRegistry.cpp
chrome/src/nsChromeRegistry.h
content/base/public/Makefile.in
content/base/public/nsIChromeRegistry.idl
content/base/src/nsContentUtils.cpp
content/html/content/src/nsHTMLMediaElement.cpp
content/html/content/test/test_bug559284.html
content/xul/templates/src/nsXULContentBuilder.cpp
content/xul/templates/src/nsXULTreeBuilder.cpp
dom/locales/en-US/chrome/prompts.properties
editor/composer/src/nsComposerRegistration.cpp
embedding/components/build/nsEmbeddingModule.cpp
embedding/components/windowwatcher/public/nsIAuthPromptWrapper.idl
embedding/components/windowwatcher/src/nsPrompt.cpp
embedding/components/windowwatcher/src/nsPrompt.h
embedding/components/windowwatcher/src/nsPromptService.cpp
embedding/components/windowwatcher/src/nsPromptService.h
embedding/components/windowwatcher/src/nsWindowWatcher.cpp
extensions/gnomevfs/nsGnomeVFSProtocolHandler.cpp
extensions/spellcheck/locales/en-US/hunspell/README.txt
extensions/spellcheck/locales/en-US/hunspell/mozilla_words.diff
gfx/public/nsITheme.h
intl/build/nsI18nModule.cpp
intl/unicharutil/public/nsHankakuToZenkakuCID.h
intl/unicharutil/src/nsHankakuToZenkaku.cpp
intl/unicharutil/src/nsTextTransformFactory.h
intl/unicharutil/src/nsUcharUtilConstructors.h
js/src/xpconnect/loader/mozJSComponentLoader.cpp
js/src/xpconnect/loader/mozJSComponentLoader.h
layout/base/tests/region_lib.js
layout/base/tests/scrolling_helper.html
layout/base/tests/test_scrolling.html
layout/build/nsLayoutModule.cpp
layout/build/nsLayoutStatics.cpp
layout/reftests/bugs/240536-resizer-ltr.xul
layout/reftests/bugs/240536-resizer-rtl.xul
layout/reftests/image-rect/background-zoom-ref.html
layout/reftests/image-rect/background-zoom.html
layout/svg/base/src/nsSVGUtils.cpp
media/libvorbis/bug498855.patch
netwerk/base/src/nsProtocolProxyService.cpp
netwerk/build/nsNetModule.cpp
netwerk/protocol/gopher/Makefile.in
netwerk/protocol/gopher/nsGopherChannel.cpp
netwerk/protocol/gopher/nsGopherChannel.h
netwerk/protocol/gopher/nsGopherHandler.cpp
netwerk/protocol/gopher/nsGopherHandler.h
netwerk/streamconv/converters/nsGopherDirListingConv.cpp
netwerk/streamconv/converters/nsGopherDirListingConv.h
netwerk/streamconv/converters/nsIndexedToHTML.cpp
toolkit/components/places/src/nsNavHistory.cpp
toolkit/components/viewconfig/content/configIntValue.xul
toolkit/content/commonDialog.css
toolkit/content/commonDialog.js
toolkit/content/commonDialog.xul
toolkit/content/selectDialog.js
toolkit/content/selectDialog.xul
toolkit/library/libxul-config.mk
toolkit/mozapps/extensions/nsAddonRepository.js
toolkit/mozapps/extensions/nsIAddonRepository.idl
toolkit/mozapps/extensions/test/browser/browser_installssl.xpi
toolkit/themes/gnomestripe/mozapps/xpinstall/xpinstallItemGeneric.png
toolkit/themes/pinstripe/mozapps/xpinstall/xpinstallItemGeneric.png
toolkit/themes/winstripe/mozapps/xpinstall/xpinstallItemGeneric-aero.png
toolkit/themes/winstripe/mozapps/xpinstall/xpinstallItemGeneric.png
toolkit/xre/nsAppRunner.cpp
toolkit/xre/nsXREDirProvider.cpp
widget/src/windows/nsNativeThemeWin.cpp
xpcom/build/Makefile.in
xpcom/build/nsXPComInit.cpp
xpcom/components/Makefile.in
xpcom/components/ManifestParser.cpp
xpcom/components/ModuleLoader.h
xpcom/components/nsComponentManager.cpp
xpcom/components/nsComponentManager.h
xpcom/components/nsIModuleLoader.idl
xpcom/components/nsNativeComponentLoader.cpp
xpcom/components/nsNativeComponentLoader.h
xpcom/glue/nsVersionComparator.h
xpcom/reflect/xptinfo/src/xptiInterfaceInfoManager.cpp
xpcom/reflect/xptinfo/src/xptiTypelibGuts.cpp
--- a/accessible/public/nsIAccessNode.idl
+++ b/accessible/public/nsIAccessNode.idl
@@ -51,64 +51,25 @@ interface nsIDOMCSSPrimitiveValue;
  * The nsIAccessNode implementations are instantiated lazily.
  * The nsIAccessNode tree for a given dom window
  * has a one to one relationship to the DOM tree.
  * If the DOM node for this access node is "accessible",
  * then a QueryInterface to nsIAccessible will succeed.
  *
  * @status UNDER_REVIEW
  */
-[scriptable, uuid(bd458843-1895-42c6-b7f9-f0ca88eeab6b)]
+[scriptable, uuid(ef16ff42-0256-4b48-ae87-b18a95b7f7d6)]
 interface nsIAccessNode : nsISupports
 {
   /**
    * The DOM node this nsIAccessNode is associated with.
    */
   readonly attribute nsIDOMNode DOMNode;
 
   /**
-   * The number of DOM children for the DOM node, which
-   * matches the number of nsIAccessNode children for this
-   * nsIAccessNode.
-   */
-  readonly attribute long numChildren;
-  
-  /**
-   * Get the nth child of this node
-   * @param childNum Zero-based child index
-   * @return The nth nsIAccessNode child
-   */
-  nsIAccessNode getChildNodeAt(in long childNum);
-  
-  /**
-   * The parent nsIAccessNode
-   */
-  readonly attribute nsIAccessNode parentNode;
-
-  /**
-   * The first nsIAccessNode child
-   */
-  readonly attribute nsIAccessNode firstChildNode;
-
-  /**
-   * The last nsIAccessNode child
-   */
-  readonly attribute nsIAccessNode lastChildNode;
-  
-  /**
-   * The previous nsIAccessNode sibling
-   */
-  readonly attribute nsIAccessNode previousSiblingNode;
-
-  /**
-   * The next nsIAccessNode sibling
-   */
-  readonly attribute nsIAccessNode nextSiblingNode;
-
-  /**
    * The document accessible that this access node resides in.
    */
   readonly attribute nsIAccessibleDocument document;
 
   /**
    * The root document accessible that this access node resides in.
    */
   readonly attribute nsIAccessibleDocument rootDocument;
--- a/accessible/public/nsIAccessibilityService.h
+++ b/accessible/public/nsIAccessibilityService.h
@@ -46,20 +46,20 @@
 
 class nsAccessible;
 class nsIContent;
 class nsIDocument;
 class nsIFrame;
 class nsIPresShell;
 class nsObjectFrame;
 
-// 9f43b315-53c6-4d46-9818-9c8593e91984
+// 10ff6dca-b219-4b64-9a4c-67a62b86edce
 #define NS_IACCESSIBILITYSERVICE_IID \
-{0x9f43b315, 0x53c6, 0x4d46,         \
-  {0x98, 0x18, 0x9c, 0x85, 0x93, 0xe9, 0x19, 0x84} }
+{ 0x10ff6dca, 0xb219, 0x4b64, \
+ { 0x9a, 0x4c, 0x67, 0xa6, 0x2b, 0x86, 0xed, 0xce } }
 
 class nsIAccessibilityService : public nsIAccessibleRetrieval
 {
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_IACCESSIBILITYSERVICE_IID)
 
   /**
    * Return an accessible object for a DOM node in the given pres shell.
@@ -162,16 +162,22 @@ public:
 
   /**
    * Notify accessibility that anchor jump has been accomplished to the given
    * target. Used by layout.
    */
   virtual void NotifyOfAnchorJumpTo(nsIContent *aTarget) = 0;
 
   /**
+   * Notify the accessibility service that the given presshell is
+   * being destroyed.
+   */
+  virtual void PresShellDestroyed(nsIPresShell *aPresShell) = 0;
+
+  /**
    * Fire accessible event of the given type for the given target.
    *
    * @param aEvent   [in] accessible event type
    * @param aTarget  [in] target of accessible event
    */
   virtual nsresult FireAccessibleEvent(PRUint32 aEvent,
                                        nsIAccessible *aTarget) = 0;
 };
--- a/accessible/public/nsIAccessibleHyperText.idl
+++ b/accessible/public/nsIAccessibleHyperText.idl
@@ -39,41 +39,51 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsISupports.idl"
 #include "nsIAccessibleHyperLink.idl"
 
 /**
  * A cross-platform interface that deals with text which contains hyperlinks.
+ * Each link is an embedded object representing exactly 1 character within
+ * the hypertext.
+ *
+ * Current implementation assumes every embedded object is a link.
  */
 
-[scriptable, uuid(d56bd454-8ff3-4edc-b266-baeada00267b)]
+[scriptable, uuid(b33684e2-090c-4e1d-a3d9-f4b46f4237b9)]
 interface nsIAccessibleHyperText : nsISupports
 {
   /**
-   * Returns the number of links contained within this hypertext object.
+   * Return the number of links contained within this hypertext object.
    */
   readonly attribute long linkCount;
 
-  /*
-   * Returns the link index at the given character index.
-   * Each link is an embedded object representing exactly 1 character within
-   * the hypertext.
+  /**
+   * Return link accessible at the given index.
    *
-   * @param charIndex  the 0-based character index.
+   * @param index  [in] 0-based index of the link that is to be retrieved
    *
-   * @returns long  0-based link's index.
-   * A return value of -1 indicates no link is present at that index.
+   * @return       link accessible or null if there is no link at that index
    */
-  long getLinkIndex(in long charIndex);
+  nsIAccessibleHyperLink getLinkAt(in long index);
 
   /**
-   * Retrieves the nsIAccessibleHyperLink object at the given link index.
+   * Return index of the given link.
    *
-   * @param linkIndex  0-based index of the link that is to be retrieved.
-   * This can be retrieved via getLinkIndex (see above).
+   * @param link  [in] link accessible the index is requested for
    *
-   * @returns nsIAccessibleHyperLink  Object representing the link properties
-   * or NS_ERROR_INVALID_ARG if there is no link at that index.
+   * @return      index of the given link or null if there's no link within
+   *                hypertext accessible
    */
-  nsIAccessibleHyperLink getLink(in long linkIndex);
+  long getLinkIndex(in nsIAccessibleHyperLink link);
+
+  /*
+   * Return link index at the given offset within hypertext accessible.
+   *
+   * @param offset  [in] the 0-based character index
+   *
+   * @return        0-based link's index or -1 if no link is present at that
+   *                  offset
+   */
+  long getLinkIndexAtOffset(in long offset);
 };
--- a/accessible/public/nsIAccessibleRetrieval.idl
+++ b/accessible/public/nsIAccessibleRetrieval.idl
@@ -51,17 +51,17 @@ interface nsIDOMDOMStringList;
  * An interface for in-process accessibility clients
  * wishing to get an nsIAccessible or nsIAccessNode for
  * a given DOM node.
  * More documentation at:
  *   http://www.mozilla.org/projects/ui/accessibility
  *
  * @status UNDER_REVIEW
  */
-[scriptable, uuid(3e5cbd5c-dbab-4ea3-b82b-4cd6201d6fe0)]
+[scriptable, uuid(420f0f49-27c1-4ac1-b509-5aba4353909b)]
 interface nsIAccessibleRetrieval : nsISupports
 {
   /**
    * Return application accessible.
    */
   nsIAccessible getApplicationAccessible();
 
   /**
@@ -123,16 +123,26 @@ interface nsIAccessibleRetrieval : nsISu
 
   /**
    * Get the type of accessible relation as a string.
    *
    * @param aRelationType - the accessible relation type constant
    * @return - accessible relation type presented as human readable string
    */
   AString getStringRelationType(in unsigned long aRelationType);
+
+  /**
+   * Return an accessible for the given DOM node from the cache.
+   * @note  the method is intended for testing purposes
+   *
+   * @param aNode  [in] the DOM node to get an accessible for
+   *
+   * @return       cached accessible for the given DOM node if any
+   */
+  nsIAccessible getAccessibleFromCache(in nsIDOMNode aNode);
 };
 
 
 %{ C++
 
 // for component registration
 // {663CA4A8-D219-4000-925D-D8F66406B626}
 #define NS_ACCESSIBLE_RETRIEVAL_CID \
--- a/accessible/src/atk/nsAccessNodeWrap.cpp
+++ b/accessible/src/atk/nsAccessNodeWrap.cpp
@@ -39,26 +39,27 @@
 #include "nsAccessNodeWrap.h"
 #include "nsApplicationAccessibleWrap.h"
 
 /* For documentation of the accessibility architecture, 
  * see http://lxr.mozilla.org/seamonkey/source/accessible/accessible-docs.html
  */
 
 
-/*
- * Class nsAccessNodeWrap
- */
+////////////////////////////////////////////////////////////////////////////////
+// nsAccessNodeWrap
+////////////////////////////////////////////////////////////////////////////////
 
 //-----------------------------------------------------
 // construction 
 //-----------------------------------------------------
 
-nsAccessNodeWrap::nsAccessNodeWrap(nsIDOMNode *aNode, nsIWeakReference* aShell): 
-  nsAccessNode(aNode, aShell)
+nsAccessNodeWrap::
+    nsAccessNodeWrap(nsIContent *aContent, nsIWeakReference *aShell) :
+    nsAccessNode(aContent, aShell)
 {
 }
 
 //-----------------------------------------------------
 // destruction
 //-----------------------------------------------------
 nsAccessNodeWrap::~nsAccessNodeWrap()
 {
--- a/accessible/src/atk/nsAccessNodeWrap.h
+++ b/accessible/src/atk/nsAccessNodeWrap.h
@@ -43,16 +43,16 @@
 #ifndef _nsAccessNodeWrap_H_
 #define _nsAccessNodeWrap_H_
 
 #include "nsAccessNode.h"
 
 class nsAccessNodeWrap :  public nsAccessNode
 {
 public: // construction, destruction
-    nsAccessNodeWrap(nsIDOMNode *aNode, nsIWeakReference* aShell);
+    nsAccessNodeWrap(nsIContent *aContent, nsIWeakReference *aShell);
     virtual ~nsAccessNodeWrap();
 
     static void InitAccessibility();
     static void ShutdownAccessibility();
 };
 
 #endif
--- a/accessible/src/atk/nsAccessibleWrap.cpp
+++ b/accessible/src/atk/nsAccessibleWrap.cpp
@@ -265,20 +265,19 @@ mai_atk_object_get_type(void)
     return type;
 }
 
 #ifdef MAI_LOGGING
 PRInt32 nsAccessibleWrap::mAccWrapCreated = 0;
 PRInt32 nsAccessibleWrap::mAccWrapDeleted = 0;
 #endif
 
-nsAccessibleWrap::nsAccessibleWrap(nsIDOMNode* aNode,
-                                   nsIWeakReference *aShell)
-    : nsAccessible(aNode, aShell),
-      mAtkObject(nsnull)
+nsAccessibleWrap::
+    nsAccessibleWrap(nsIContent *aContent, nsIWeakReference *aShell) :
+    nsAccessible(aContent, aShell), mAtkObject(nsnull)
 {
 #ifdef MAI_LOGGING
     ++mAccWrapCreated;
 #endif
     MAI_LOG_DEBUG(("==nsAccessibleWrap creating: this=%p,total=%d left=%d\n",
                    (void*)this, mAccWrapCreated,
                   (mAccWrapCreated-mAccWrapDeleted)));
 }
@@ -302,21 +301,21 @@ void nsAccessibleWrap::ShutdownAtkObject
             MAI_ATK_OBJECT(mAtkObject)->accWrap = nsnull;
         }
         SetMaiHyperlink(nsnull);
         g_object_unref(mAtkObject);
         mAtkObject = nsnull;
     }
 }
 
-nsresult
+void
 nsAccessibleWrap::Shutdown()
 {
     ShutdownAtkObject();
-    return nsAccessible::Shutdown();
+    nsAccessible::Shutdown();
 }
 
 MaiHyperlink* nsAccessibleWrap::GetMaiHyperlink(PRBool aCreate /* = PR_TRUE */)
 {
     // make sure mAtkObject is created
     GetAtkObject();
 
     NS_ASSERTION(quark_mai_hyperlink, "quark_mai_hyperlink not initialized");
@@ -557,17 +556,17 @@ GetUniqueMaiAtkTypeName(PRUint16 interfa
     MAI_LOG_DEBUG(("MaiWidget::LastedTypeName=%s\n", name));
 
     return name;
 }
 
 PRBool nsAccessibleWrap::IsValidObject()
 {
     // to ensure we are not shut down
-    return (mDOMNode != nsnull);
+    return !IsDefunct();
 }
 
 /* static functions for ATK callbacks */
 void
 classInitCB(AtkObjectClass *aClass)
 {
     GObjectClass *gobject_class = G_OBJECT_CLASS(aClass);
 
@@ -864,65 +863,42 @@ getParentCB(AtkObject *aAtkObj)
 gint
 getChildCountCB(AtkObject *aAtkObj)
 {
     nsAccessibleWrap *accWrap = GetAccessibleWrap(aAtkObj);
     if (!accWrap || nsAccUtils::MustPrune(accWrap)) {
         return 0;
     }
 
-    PRInt32 count = 0;
-    nsCOMPtr<nsIAccessibleHyperText> hyperText;
-    accWrap->QueryInterface(NS_GET_IID(nsIAccessibleHyperText), getter_AddRefs(hyperText));
-    if (hyperText) {
-        // If HyperText, then number of links matches number of children
-        hyperText->GetLinkCount(&count);
-    }
-    else {
-        nsCOMPtr<nsIAccessibleText> accText;
-        accWrap->QueryInterface(NS_GET_IID(nsIAccessibleText), getter_AddRefs(accText));
-        if (!accText) {    // Accessible text that is not a HyperText has no children
-            accWrap->GetChildCount(&count);
-        }
-    }
-    return count;
+    // Links within hypertext accessible play role of accessible children in
+    // ATK since every embedded object is a link and text accessibles are
+    // ignored.
+    nsRefPtr<nsHyperTextAccessible> hyperText = do_QueryObject(accWrap);
+    return hyperText ? hyperText->GetLinkCount() : accWrap->GetChildCount();
 }
 
 AtkObject *
 refChildCB(AtkObject *aAtkObj, gint aChildIndex)
 {
     // aChildIndex should not be less than zero
     if (aChildIndex < 0) {
       return nsnull;
     }
 
     nsAccessibleWrap *accWrap = GetAccessibleWrap(aAtkObj);
     if (!accWrap || nsAccUtils::MustPrune(accWrap)) {
         return nsnull;
     }
 
-    nsCOMPtr<nsIAccessible> accChild;
-    nsCOMPtr<nsIAccessibleHyperText> hyperText;
-    accWrap->QueryInterface(NS_GET_IID(nsIAccessibleHyperText), getter_AddRefs(hyperText));
-    if (hyperText) {
-        // If HyperText, then number of links matches number of children.
-        // XXX Fix this so it is not O(n^2) to walk through the children
-        // (bug 566328).
-        nsCOMPtr<nsIAccessibleHyperLink> hyperLink;
-        hyperText->GetLink(aChildIndex, getter_AddRefs(hyperLink));
-        accChild = do_QueryInterface(hyperLink);
-    }
-    else {
-        nsCOMPtr<nsIAccessibleText> accText;
-        accWrap->QueryInterface(NS_GET_IID(nsIAccessibleText), getter_AddRefs(accText));
-        if (!accText) {  // Accessible Text that is not HyperText has no children
-            accWrap->GetChildAt(aChildIndex, getter_AddRefs(accChild));
-        }
-    }
-
+    // Links within hypertext accessible play role of accessible children in
+    // ATK since every embedded object is a link and text accessibles are
+    // ignored.
+    nsRefPtr<nsHyperTextAccessible> hyperText = do_QueryObject(accWrap);
+    nsAccessible* accChild = hyperText ? hyperText->GetLinkAt(aChildIndex) :
+                                         accWrap->GetChildAt(aChildIndex);
     if (!accChild)
         return nsnull;
 
     AtkObject* childAtkObj = nsAccessibleWrap::GetAtkObject(accChild);
 
     NS_ASSERTION(childAtkObj, "Fail to get AtkObj");
     if (!childAtkObj)
         return nsnull;
@@ -943,31 +919,22 @@ getIndexInParentCB(AtkObject *aAtkObj)
         return -1;
     }
 
     nsAccessible *parent = accWrap->GetParent();
     if (!parent) {
         return -1; // No parent
     }
 
-    PRInt32 currentIndex = 0;
-
-    PRInt32 childCount = parent->GetChildCount();
-    for (PRInt32 idx = 0; idx < childCount; idx++) {
-      nsAccessible *sibling = parent->GetChildAt(idx);
-      if (sibling == accWrap) {
-          return currentIndex;
-      }
-
-      if (nsAccUtils::IsEmbeddedObject(sibling)) {
-          ++ currentIndex;
-      }
-    }
-
-    return -1;
+    // Links within hypertext accessible play role of accessible children in
+    // ATK since every embedded object is a link and text accessibles are
+    // ignored.
+    nsRefPtr<nsHyperTextAccessible> hyperTextParent(do_QueryObject(parent));
+    return hyperTextParent ?
+        hyperTextParent->GetLinkIndex(accWrap) : parent->GetIndexOf(accWrap);
 }
 
 static void TranslateStates(PRUint32 aState, const AtkStateMap *aStateMap,
                             AtkStateSet *aStateSet)
 {
   NS_ASSERTION(aStateSet, "Can't pass in null state set");
 
   // Convert every state to an entry in AtkStateMap
@@ -1104,18 +1071,17 @@ nsAccessibleWrap::HandleAccEvent(nsAccEv
     NS_ENSURE_SUCCESS(rv, rv);
 
     return FirePlatformEvent(aEvent);
 }
 
 nsresult
 nsAccessibleWrap::FirePlatformEvent(nsAccEvent *aEvent)
 {
-    nsCOMPtr<nsIAccessible> accessible;
-    aEvent->GetAccessible(getter_AddRefs(accessible));
+    nsAccessible *accessible = aEvent->GetAccessible();
     NS_ENSURE_TRUE(accessible, NS_ERROR_FAILURE);
 
     PRUint32 type = aEvent->GetEventType();
 
     AtkObject *atkObj = nsAccessibleWrap::GetAtkObject(accessible);
 
     // We don't create ATK objects for nsIAccessible plain text leaves,
     // just return NS_OK in such case
@@ -1152,17 +1118,17 @@ nsAccessibleWrap::FirePlatformEvent(nsAc
                                         PR_FALSE, PR_TRUE);
             return FireAtkStateChangeEvent(stateChangeEvent, atkObj);
         }
       } break;
 
     case nsIAccessibleEvent::EVENT_VALUE_CHANGE:
       {
         MAI_LOG_DEBUG(("\n\nReceived: EVENT_VALUE_CHANGE\n"));
-        nsCOMPtr<nsIAccessibleValue> value(do_QueryInterface(accessible));
+        nsCOMPtr<nsIAccessibleValue> value(do_QueryObject(accessible));
         if (value) {    // Make sure this is a numeric value
             // Don't fire for MSAA string value changes (e.g. text editing)
             // ATK values are always numeric
             g_object_notify( (GObject*)atkObj, "accessible-value" );
         }
       } break;
 
     case nsIAccessibleEvent::EVENT_SELECTION_CHANGED:
@@ -1174,23 +1140,22 @@ nsAccessibleWrap::FirePlatformEvent(nsAc
         MAI_LOG_DEBUG(("\n\nReceived: EVENT_TEXT_SELECTION_CHANGED\n"));
         g_signal_emit_by_name(atkObj, "text_selection_changed");
         break;
 
     case nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED:
       {
         MAI_LOG_DEBUG(("\n\nReceived: EVENT_TEXT_CARET_MOVED\n"));
 
-        nsCOMPtr<nsIAccessibleCaretMoveEvent> caretMoveEvent(do_QueryInterface(aEvent));
+        nsAccCaretMoveEvent *caretMoveEvent = downcast_accEvent(aEvent);
         NS_ASSERTION(caretMoveEvent, "Event needs event data");
         if (!caretMoveEvent)
             break;
 
-        PRInt32 caretOffset = -1;
-        caretMoveEvent->GetCaretOffset(&caretOffset);
+        PRInt32 caretOffset = caretMoveEvent->GetCaretOffset();
 
         MAI_LOG_DEBUG(("\n\nCaret postion: %d", caretOffset));
         g_signal_emit_by_name(atkObj,
                               "text_caret_moved",
                               // Curent caret position
                               caretOffset);
       } break;
 
@@ -1204,40 +1169,38 @@ nsAccessibleWrap::FirePlatformEvent(nsAc
     case nsIAccessibleEvent::EVENT_TABLE_MODEL_CHANGED:
         MAI_LOG_DEBUG(("\n\nReceived: EVENT_TABLE_MODEL_CHANGED\n"));
         g_signal_emit_by_name(atkObj, "model_changed");
         break;
 
     case nsIAccessibleEvent::EVENT_TABLE_ROW_INSERT:
       {
         MAI_LOG_DEBUG(("\n\nReceived: EVENT_TABLE_ROW_INSERT\n"));
-        nsCOMPtr<nsIAccessibleTableChangeEvent> tableEvent = do_QueryInterface(aEvent);
+        nsAccTableChangeEvent *tableEvent = downcast_accEvent(aEvent);
         NS_ENSURE_TRUE(tableEvent, NS_ERROR_FAILURE);
 
-        PRInt32 rowIndex, numRows;
-        tableEvent->GetRowOrColIndex(&rowIndex);
-        tableEvent->GetNumRowsOrCols(&numRows);
+        PRInt32 rowIndex = tableEvent->GetIndex();
+        PRInt32 numRows = tableEvent->GetCount();
 
         g_signal_emit_by_name(atkObj,
                               "row_inserted",
                               // After which the rows are inserted
                               rowIndex,
                               // The number of the inserted
                               numRows);
      } break;
 
    case nsIAccessibleEvent::EVENT_TABLE_ROW_DELETE:
      {
         MAI_LOG_DEBUG(("\n\nReceived: EVENT_TABLE_ROW_DELETE\n"));
-        nsCOMPtr<nsIAccessibleTableChangeEvent> tableEvent = do_QueryInterface(aEvent);
+        nsAccTableChangeEvent *tableEvent = downcast_accEvent(aEvent);
         NS_ENSURE_TRUE(tableEvent, NS_ERROR_FAILURE);
 
-        PRInt32 rowIndex, numRows;
-        tableEvent->GetRowOrColIndex(&rowIndex);
-        tableEvent->GetNumRowsOrCols(&numRows);
+        PRInt32 rowIndex = tableEvent->GetIndex();
+        PRInt32 numRows = tableEvent->GetCount();
 
         g_signal_emit_by_name(atkObj,
                               "row_deleted",
                               // After which the rows are deleted
                               rowIndex,
                               // The number of the deleted
                               numRows);
       } break;
@@ -1247,40 +1210,38 @@ nsAccessibleWrap::FirePlatformEvent(nsAc
         MAI_LOG_DEBUG(("\n\nReceived: EVENT_TABLE_ROW_REORDER\n"));
         g_signal_emit_by_name(atkObj, "row_reordered");
         break;
       }
 
     case nsIAccessibleEvent::EVENT_TABLE_COLUMN_INSERT:
       {
         MAI_LOG_DEBUG(("\n\nReceived: EVENT_TABLE_COLUMN_INSERT\n"));
-        nsCOMPtr<nsIAccessibleTableChangeEvent> tableEvent = do_QueryInterface(aEvent);
+        nsAccTableChangeEvent *tableEvent = downcast_accEvent(aEvent);
         NS_ENSURE_TRUE(tableEvent, NS_ERROR_FAILURE);
 
-        PRInt32 colIndex, numCols;
-        tableEvent->GetRowOrColIndex(&colIndex);
-        tableEvent->GetNumRowsOrCols(&numCols);
+        PRInt32 colIndex = tableEvent->GetIndex();
+        PRInt32 numCols = tableEvent->GetCount();
 
         g_signal_emit_by_name(atkObj,
                               "column_inserted",
                               // After which the columns are inserted
                               colIndex,
                               // The number of the inserted
                               numCols);
       } break;
 
     case nsIAccessibleEvent::EVENT_TABLE_COLUMN_DELETE:
       {
         MAI_LOG_DEBUG(("\n\nReceived: EVENT_TABLE_COLUMN_DELETE\n"));
-        nsCOMPtr<nsIAccessibleTableChangeEvent> tableEvent = do_QueryInterface(aEvent);
+        nsAccTableChangeEvent *tableEvent = downcast_accEvent(aEvent);
         NS_ENSURE_TRUE(tableEvent, NS_ERROR_FAILURE);
 
-        PRInt32 colIndex, numCols;
-        tableEvent->GetRowOrColIndex(&colIndex);
-        tableEvent->GetNumRowsOrCols(&numCols);
+        PRInt32 colIndex = tableEvent->GetIndex();
+        PRInt32 numCols = tableEvent->GetCount();
 
         g_signal_emit_by_name(atkObj,
                               "column_deleted",
                               // After which the columns are deleted
                               colIndex,
                               // The number of the deleted
                               numCols);
       } break;
@@ -1314,30 +1275,30 @@ nsAccessibleWrap::FirePlatformEvent(nsAc
     case nsIAccessibleEvent::EVENT_MENU_END:
         MAI_LOG_DEBUG(("\n\nReceived: EVENT_MENU_END\n"));
         break;
 
     case nsIAccessibleEvent::EVENT_WINDOW_ACTIVATE:
       {
         MAI_LOG_DEBUG(("\n\nReceived: EVENT_WINDOW_ACTIVATED\n"));
         nsRootAccessible *rootAcc =
-          static_cast<nsRootAccessible *>(accessible.get());
+          static_cast<nsRootAccessible *>(accessible);
         rootAcc->mActivated = PR_TRUE;
         guint id = g_signal_lookup ("activate", MAI_TYPE_ATK_OBJECT);
         g_signal_emit(atkObj, id, 0);
 
         // Always fire a current focus event after activation.
         rootAcc->FireCurrentFocusEvent();
       } break;
 
     case nsIAccessibleEvent::EVENT_WINDOW_DEACTIVATE:
       {
         MAI_LOG_DEBUG(("\n\nReceived: EVENT_WINDOW_DEACTIVATED\n"));
         nsRootAccessible *rootAcc =
-          static_cast<nsRootAccessible *>(accessible.get());
+          static_cast<nsRootAccessible *>(accessible);
         rootAcc->mActivated = PR_FALSE;
         guint id = g_signal_lookup ("deactivate", MAI_TYPE_ATK_OBJECT);
         g_signal_emit(atkObj, id, 0);
       } break;
 
     case nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE:
       {
         MAI_LOG_DEBUG(("\n\nReceived: EVENT_DOCUMENT_LOAD_COMPLETE\n"));
@@ -1374,28 +1335,22 @@ nsAccessibleWrap::FirePlatformEvent(nsAc
 }
 
 nsresult
 nsAccessibleWrap::FireAtkStateChangeEvent(nsAccEvent *aEvent,
                                           AtkObject *aObject)
 {
     MAI_LOG_DEBUG(("\n\nReceived: EVENT_STATE_CHANGE\n"));
 
-    nsCOMPtr<nsIAccessibleStateChangeEvent> event =
-        do_QueryInterface(aEvent);
+    nsAccStateChangeEvent *event = downcast_accEvent(aEvent);
     NS_ENSURE_TRUE(event, NS_ERROR_FAILURE);
 
-    PRUint32 state = 0;
-    event->GetState(&state);
-
-    PRBool isExtra;
-    event->IsExtraState(&isExtra);
-
-    PRBool isEnabled;
-    event->IsEnabled(&isEnabled);
+    PRUint32 state = event->GetState();
+    PRBool isExtra = event->IsExtraState();
+    PRBool isEnabled = event->IsStateEnabled();
 
     PRInt32 stateIndex = AtkStateMap::GetStateIndexFor(state);
     if (stateIndex >= 0) {
         const AtkStateMap *atkStateMap = isExtra ? gAtkStateMapExt : gAtkStateMap;
         NS_ASSERTION(atkStateMap[stateIndex].stateMapEntryType != kNoSuchState,
                      "No such state");
 
         if (atkStateMap[stateIndex].atkState != kNone) {
@@ -1416,28 +1371,22 @@ nsAccessibleWrap::FireAtkStateChangeEven
 }
 
 nsresult
 nsAccessibleWrap::FireAtkTextChangedEvent(nsAccEvent *aEvent,
                                           AtkObject *aObject)
 {
     MAI_LOG_DEBUG(("\n\nReceived: EVENT_TEXT_REMOVED/INSERTED\n"));
 
-    nsCOMPtr<nsIAccessibleTextChangeEvent> event =
-        do_QueryInterface(aEvent);
+    nsAccTextChangeEvent *event = downcast_accEvent(aEvent);
     NS_ENSURE_TRUE(event, NS_ERROR_FAILURE);
 
-    PRInt32 start = 0;
-    event->GetStart(&start);
-
-    PRUint32 length = 0;
-    event->GetLength(&length);
-
-    PRBool isInserted;
-    event->IsInserted(&isInserted);
+    PRInt32 start = event->GetStartOffset();
+    PRUint32 length = event->GetLength();
+    PRBool isInserted = event->IsTextInserted();
 
     PRBool isFromUserInput = aEvent->IsFromUserInput();
 
     char *signal_name = g_strconcat(isInserted ? "text_changed::insert" : "text_changed::delete",
                                     isFromUserInput ? "" : kNonUserInputEvent, NULL);
     g_signal_emit_by_name(aObject, signal_name, start, length);
     g_free (signal_name);
 
--- a/accessible/src/atk/nsAccessibleWrap.h
+++ b/accessible/src/atk/nsAccessibleWrap.h
@@ -80,22 +80,22 @@ class MaiHyperlink;
 
 /**
  * nsAccessibleWrap, and its descendents in atk directory provide the
  * implementation of AtkObject.
  */
 class nsAccessibleWrap: public nsAccessible
 {
 public:
-    nsAccessibleWrap(nsIDOMNode*, nsIWeakReference *aShell);
+    nsAccessibleWrap(nsIContent *aContent, nsIWeakReference *aShell);
     virtual ~nsAccessibleWrap();
     void ShutdownAtkObject();
 
     // nsAccessNode
-    virtual nsresult Shutdown();
+    virtual void Shutdown();
 
 #ifdef MAI_LOGGING
     virtual void DumpnsAccessibleWrapInfo(int aDepth) {}
     static PRInt32 mAccWrapCreated;
     static PRInt32 mAccWrapDeleted;
 #endif
 
     // return the atk object for this nsAccessibleWrap
--- a/accessible/src/atk/nsApplicationAccessibleWrap.cpp
+++ b/accessible/src/atk/nsApplicationAccessibleWrap.cpp
@@ -527,17 +527,17 @@ nsApplicationAccessibleWrap::nsApplicati
 }
 
 nsApplicationAccessibleWrap::~nsApplicationAccessibleWrap()
 {
     MAI_LOG_DEBUG(("======Destory AppRootAcc=%p\n", (void*)this));
     nsAccessibleWrap::ShutdownAtkObject();
 }
 
-nsresult
+PRBool
 nsApplicationAccessibleWrap::Init()
 {
     // XXX following code is copied from widget/src/gtk2/nsWindow.cpp
     // we should put it to somewhere that can be used from both modules
     // see bug 390761
 
     // check if accessibility enabled/disabled by environment variable
     PRBool isGnomeATEnabled = PR_FALSE;
--- a/accessible/src/atk/nsApplicationAccessibleWrap.h
+++ b/accessible/src/atk/nsApplicationAccessibleWrap.h
@@ -50,17 +50,17 @@ public:
     static void Unload();
     static void PreCreate();
 
 public:
     nsApplicationAccessibleWrap();
     virtual ~nsApplicationAccessibleWrap();
 
     // nsAccessNode
-    virtual nsresult Init();
+    virtual PRBool Init();
 
     // return the atk object for app root accessible
     NS_IMETHOD GetNativeInterface(void **aOutAccessible);
 
     // nsApplicationAccessible
     virtual nsresult AddRootAccessible(nsIAccessible *aRootAccWrap);
     virtual nsresult RemoveRootAccessible(nsIAccessible *aRootAccWrap);
 };
--- a/accessible/src/atk/nsDocAccessibleWrap.cpp
+++ b/accessible/src/atk/nsDocAccessibleWrap.cpp
@@ -38,20 +38,23 @@
  * 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 "nsMai.h"
 #include "nsDocAccessibleWrap.h"
 
-//----- nsDocAccessibleWrap -----
+////////////////////////////////////////////////////////////////////////////////
+// nsDocAccessibleWrap
+////////////////////////////////////////////////////////////////////////////////
 
-nsDocAccessibleWrap::nsDocAccessibleWrap(nsIDOMNode *aDOMNode,
-                                         nsIWeakReference *aShell): 
-  nsDocAccessible(aDOMNode, aShell), mActivated(PR_FALSE)
+nsDocAccessibleWrap::
+    nsDocAccessibleWrap(nsIDocument *aDocument, nsIContent *aRootContent,
+                        nsIWeakReference *aShell) :
+    nsDocAccessible(aDocument, aRootContent, aShell), mActivated(PR_FALSE)
 {
 }
 
 nsDocAccessibleWrap::~nsDocAccessibleWrap()
 {
 }
 
--- a/accessible/src/atk/nsDocAccessibleWrap.h
+++ b/accessible/src/atk/nsDocAccessibleWrap.h
@@ -46,15 +46,16 @@
 #ifndef _nsDocAccessibleWrap_H_
 #define _nsDocAccessibleWrap_H_
 
 #include "nsDocAccessible.h"
 
 class nsDocAccessibleWrap: public nsDocAccessible
 {
 public:
-  nsDocAccessibleWrap(nsIDOMNode *aNode, nsIWeakReference *aShell);
+  nsDocAccessibleWrap(nsIDocument *aDocument, nsIContent *aRootContent,
+                      nsIWeakReference *aShell);
   virtual ~nsDocAccessibleWrap();
 
   PRBool mActivated;
 };
 
 #endif
--- a/accessible/src/atk/nsMaiInterfaceComponent.cpp
+++ b/accessible/src/atk/nsMaiInterfaceComponent.cpp
@@ -73,19 +73,18 @@ refAccessibleAtPointCB(AtkComponent *aCo
                        AtkCoordType aCoordType)
 {
     nsAccessibleWrap *accWrap = GetAccessibleWrap(ATK_OBJECT(aComponent));
     if (!accWrap || nsAccUtils::MustPrune(accWrap))
         return nsnull;
 
     // nsIAccessible getChildAtPoint (x,y) is in screen pixels.
     if (aCoordType == ATK_XY_WINDOW) {
-        nsCOMPtr<nsIDOMNode> domNode;
-        accWrap->GetDOMNode(getter_AddRefs(domNode));
-        nsIntPoint winCoords = nsCoreUtils::GetScreenCoordsForWindow(domNode);
+        nsIntPoint winCoords =
+          nsCoreUtils::GetScreenCoordsForWindow(accWrap->GetNode());
         aAccX += winCoords.x;
         aAccY += winCoords.y;
     }
 
     nsCOMPtr<nsIAccessible> pointAcc;
     accWrap->GetChildAtPoint(aAccX, aAccY, getter_AddRefs(pointAcc));
     if (!pointAcc) {
         return nsnull;
@@ -114,19 +113,18 @@ getExtentsCB(AtkComponent *aComponent,
 
     PRInt32 nsAccX, nsAccY, nsAccWidth, nsAccHeight;
     // Returned in screen coordinates
     nsresult rv = accWrap->GetBounds(&nsAccX, &nsAccY,
                                      &nsAccWidth, &nsAccHeight);
     if (NS_FAILED(rv))
         return;
     if (aCoordType == ATK_XY_WINDOW) {
-        nsCOMPtr<nsIDOMNode> domNode;
-        accWrap->GetDOMNode(getter_AddRefs(domNode));
-        nsIntPoint winCoords = nsCoreUtils::GetScreenCoordsForWindow(domNode);
+        nsIntPoint winCoords =
+          nsCoreUtils::GetScreenCoordsForWindow(accWrap->GetNode());
         nsAccX -= winCoords.x;
         nsAccY -= winCoords.y;
     }
 
     *aAccX = nsAccX;
     *aAccY = nsAccY;
     *aAccWidth = nsAccWidth;
     *aAccHeight = nsAccHeight;
--- a/accessible/src/atk/nsMaiInterfaceHypertext.cpp
+++ b/accessible/src/atk/nsMaiInterfaceHypertext.cpp
@@ -35,17 +35,17 @@
  * 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 "nsMaiInterfaceHypertext.h"
 #include "nsIAccessibleDocument.h"
-#include "nsAccessNode.h"
+#include "nsHyperTextAccessible.h"
 
 void
 hypertextInterfaceInitCB(AtkHypertextIface *aIface)
 {
     g_return_if_fail(aIface != NULL);
 
     aIface->get_link = getLinkCB;
     aIface->get_n_links = getLinkCountCB;
@@ -54,65 +54,53 @@ hypertextInterfaceInitCB(AtkHypertextIfa
 
 AtkHyperlink *
 getLinkCB(AtkHypertext *aText, gint aLinkIndex)
 {
     nsAccessibleWrap *accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
     if (!accWrap)
         return nsnull;
 
-    nsCOMPtr<nsIAccessibleHyperText> hyperText;
-    accWrap->QueryInterface(NS_GET_IID(nsIAccessibleHyperText),
-                            getter_AddRefs(hyperText));
+    nsRefPtr<nsHyperTextAccessible> hyperText = do_QueryObject(accWrap);
     NS_ENSURE_TRUE(hyperText, nsnull);
 
-    nsCOMPtr<nsIAccessibleHyperLink> hyperLink;
-    nsresult rv = hyperText->GetLink(aLinkIndex, getter_AddRefs(hyperLink));
-    if (NS_FAILED(rv) || !hyperLink)
+    nsAccessible* hyperLink = hyperText->GetLinkAt(aLinkIndex);
+    if (!hyperLink)
         return nsnull;
 
-    nsCOMPtr<nsIAccessible> hyperLinkAcc(do_QueryInterface(hyperLink));
-    AtkObject *hyperLinkAtkObj = nsAccessibleWrap::GetAtkObject(hyperLinkAcc);
+    AtkObject* hyperLinkAtkObj = nsAccessibleWrap::GetAtkObject(hyperLink);
     nsAccessibleWrap *accChild = GetAccessibleWrap(hyperLinkAtkObj);
     NS_ENSURE_TRUE(accChild, nsnull);
 
     MaiHyperlink *maiHyperlink = accChild->GetMaiHyperlink();
     NS_ENSURE_TRUE(maiHyperlink, nsnull);
     return maiHyperlink->GetAtkHyperlink();
 }
 
 gint
 getLinkCountCB(AtkHypertext *aText)
 {
     nsAccessibleWrap *accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
     if (!accWrap)
         return -1;
 
-    nsCOMPtr<nsIAccessibleHyperText> hyperText;
-    accWrap->QueryInterface(NS_GET_IID(nsIAccessibleHyperText),
-                            getter_AddRefs(hyperText));
+    nsRefPtr<nsHyperTextAccessible> hyperText = do_QueryObject(accWrap);
     NS_ENSURE_TRUE(hyperText, -1);
 
-    PRInt32 count = -1;
-    nsresult rv = hyperText->GetLinkCount(&count);
-    NS_ENSURE_SUCCESS(rv, -1);
-
-    return count;
+    return hyperText->GetLinkCount();
 }
 
 gint
 getLinkIndexCB(AtkHypertext *aText, gint aCharIndex)
 {
     nsAccessibleWrap *accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
     if (!accWrap)
         return -1;
 
-    nsCOMPtr<nsIAccessibleHyperText> hyperText;
-    accWrap->QueryInterface(NS_GET_IID(nsIAccessibleHyperText),
-                            getter_AddRefs(hyperText));
+    nsRefPtr<nsHyperTextAccessible> hyperText = do_QueryObject(accWrap);
     NS_ENSURE_TRUE(hyperText, -1);
 
     PRInt32 index = -1;
-    nsresult rv = hyperText->GetLinkIndex(aCharIndex, &index);
+    nsresult rv = hyperText->GetLinkIndexAtOffset(aCharIndex, &index);
     NS_ENSURE_SUCCESS(rv, -1);
 
     return index;
 }
--- a/accessible/src/atk/nsRootAccessibleWrap.cpp
+++ b/accessible/src/atk/nsRootAccessibleWrap.cpp
@@ -38,17 +38,17 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsMai.h"
 #include "nsRootAccessibleWrap.h"
 
 nsNativeRootAccessibleWrap::nsNativeRootAccessibleWrap(AtkObject *aAccessible):
-    nsRootAccessible(nsnull, nsnull)
+    nsRootAccessible(nsnull, nsnull, nsnull)
 {
     g_object_ref(aAccessible);
     mAtkObject = aAccessible;
 }
 
 nsNativeRootAccessibleWrap::~nsNativeRootAccessibleWrap()
 {
     g_object_unref(mAtkObject);
new file mode 100644
--- /dev/null
+++ b/accessible/src/base/AccCollector.cpp
@@ -0,0 +1,118 @@
+/* ***** 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
+ * Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *  Alexander Surkov <surkov.alexander@gmail.com> (original author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either 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 "AccCollector.h"
+
+#include "nsAccessible.h"
+
+////////////////////////////////////////////////////////////////////////////////
+// nsAccCollector
+////////////////////////////////////////////////////////////////////////////////
+
+AccCollector::
+  AccCollector(nsAccessible* aRoot, filters::FilterFuncPtr aFilterFunc) :
+  mFilterFunc(aFilterFunc), mRoot(aRoot), mRootChildIdx(0)
+{
+}
+
+AccCollector::~AccCollector()
+{
+}
+
+PRUint32
+AccCollector::Count()
+{
+  EnsureNGetIndex(nsnull);
+  return mObjects.Length();
+}
+
+nsAccessible*
+AccCollector::GetAccessibleAt(PRUint32 aIndex)
+{
+  nsAccessible *accessible = mObjects.SafeElementAt(aIndex, nsnull);
+  if (accessible)
+    return accessible;
+
+  return EnsureNGetObject(aIndex);
+}
+
+PRInt32
+AccCollector::GetIndexAt(nsAccessible *aAccessible)
+{
+  PRInt32 index = mObjects.IndexOf(aAccessible);
+  if (index != -1)
+    return index;
+
+  return EnsureNGetIndex(aAccessible);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// nsAccCollector protected
+
+nsAccessible*
+AccCollector::EnsureNGetObject(PRUint32 aIndex)
+{
+  PRInt32 childCount = mRoot->GetChildCount();
+  while (mRootChildIdx < childCount) {
+    nsAccessible* child = mRoot->GetChildAt(mRootChildIdx++);
+    if (!mFilterFunc(child))
+      continue;
+
+    mObjects.AppendElement(child);
+    if (mObjects.Length() - 1 == aIndex)
+      return mObjects[aIndex];
+  }
+
+  return nsnull;
+}
+
+PRInt32
+AccCollector::EnsureNGetIndex(nsAccessible* aAccessible)
+{
+  PRInt32 childCount = mRoot->GetChildCount();
+  while (mRootChildIdx < childCount) {
+    nsAccessible* child = mRoot->GetChildAt(mRootChildIdx++);
+    if (!mFilterFunc(child))
+      continue;
+
+    mObjects.AppendElement(child);
+    if (child == aAccessible)
+      return mObjects.Length() - 1;
+  }
+
+  return -1;
+}
new file mode 100644
--- /dev/null
+++ b/accessible/src/base/AccCollector.h
@@ -0,0 +1,94 @@
+/* ***** 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
+ * Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *  Alexander Surkov <surkov.alexander@gmail.com> (original author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either 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 ***** */
+
+#ifndef AccCollector_h_
+#define AccCollector_h_
+
+#include "filters.h"
+
+#include "nscore.h"
+#include "nsTArray.h"
+
+/**
+ * Collect accessible children complying with filter function. Provides quick
+ * access to accessible by index.
+ */
+class AccCollector
+{
+public:
+  AccCollector(nsAccessible* aRoot, filters::FilterFuncPtr aFilterFunc);
+  virtual ~AccCollector();
+
+  /**
+   * Return accessible count within the collection.
+   */
+  PRUint32 Count();
+
+  /**
+   * Return an accessible from the collection at the given index.
+   */
+  nsAccessible* GetAccessibleAt(PRUint32 aIndex);
+
+  /**
+   * Return index of the given accessible within the collection.
+   */
+  PRInt32 GetIndexAt(nsAccessible* aAccessible);
+
+protected:
+  /**
+   * Ensure accessible at the given index is stored and return it.
+   */
+  nsAccessible* EnsureNGetObject(PRUint32 aIndex);
+
+  /**
+   * Ensure index for the given accessible is stored and return it.
+   */
+  PRInt32 EnsureNGetIndex(nsAccessible* aAccessible);
+
+  filters::FilterFuncPtr mFilterFunc;
+  nsAccessible* mRoot;
+  PRInt32 mRootChildIdx;
+
+  nsTArray<nsAccessible*> mObjects;
+
+private:
+  AccCollector();
+  AccCollector(const AccCollector&);
+  AccCollector& operator =(const AccCollector&);
+};
+
+#endif
rename from accessible/src/base/nsAccIterator.cpp
rename to accessible/src/base/AccIterator.cpp
--- a/accessible/src/base/nsAccIterator.cpp
+++ b/accessible/src/base/AccIterator.cpp
@@ -30,40 +30,42 @@
  * 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 "nsAccIterator.h"
+#include "AccIterator.h"
+
+#include "nsAccessible.h"
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccIterator
 
-nsAccIterator::nsAccIterator(nsAccessible *aAccessible,
-                             AccIteratorFilterFuncPtr aFilterFunc,
-                             IterationType aIterationType) :
+AccIterator::AccIterator(nsAccessible *aAccessible,
+                         filters::FilterFuncPtr aFilterFunc,
+                         IterationType aIterationType) :
   mFilterFunc(aFilterFunc), mIsDeep(aIterationType != eFlatNav)
 {
   mState = new IteratorState(aAccessible);
 }
 
-nsAccIterator::~nsAccIterator()
+AccIterator::~AccIterator()
 {
   while (mState) {
     IteratorState *tmp = mState;
     mState = tmp->mParentState;
     delete tmp;
   }
 }
 
 nsAccessible*
-nsAccIterator::GetNext()
+AccIterator::GetNext()
 {
   while (mState) {
     nsAccessible *child = mState->mParent->GetChildAt(mState->mIndex++);
     if (!child) {
       IteratorState *tmp = mState;
       mState = mState->mParentState;
       delete tmp;
 
@@ -81,13 +83,13 @@ nsAccIterator::GetNext()
   }
 
   return nsnull;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccIterator::IteratorState
 
-nsAccIterator::IteratorState::IteratorState(nsAccessible *aParent,
-                                            IteratorState *mParentState) :
+AccIterator::IteratorState::IteratorState(nsAccessible *aParent,
+                                          IteratorState *mParentState) :
   mParent(aParent), mIndex(0), mParentState(mParentState)
 {
 }
rename from accessible/src/base/nsAccIterator.h
rename to accessible/src/base/AccIterator.h
--- a/accessible/src/base/nsAccIterator.h
+++ b/accessible/src/base/AccIterator.h
@@ -33,29 +33,24 @@
  * 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 ***** */
 
 #ifndef nsAccIterator_h_
 #define nsAccIterator_h_
 
-#include "nsAccessible.h"
-#include "nsAccUtils.h"
-
-/**
- * Return true if the traversed accessible complies with filter.
- */
-typedef PRBool (*AccIteratorFilterFuncPtr) (nsAccessible *);
+#include "filters.h"
+#include "nscore.h"
 
 /**
  * Allows to iterate through accessible children or subtree complying with
  * filter function.
  */
-class nsAccIterator
+class AccIterator
 {
 public:
   /**
    * Used to define iteration type.
    */
   enum IterationType {
     /**
      * Navigation happens through direct children.
@@ -64,61 +59,38 @@ public:
 
     /**
      * Navigation through subtree excluding iterator root; if the accessible
      * complies with filter, iterator ignores its children.
      */
     eTreeNav
   };
 
-  nsAccIterator(nsAccessible *aRoot, AccIteratorFilterFuncPtr aFilterFunc,
-                IterationType aIterationType = eFlatNav);
-  ~nsAccIterator();
+  AccIterator(nsAccessible* aRoot, filters::FilterFuncPtr aFilterFunc,
+              IterationType aIterationType = eFlatNav);
+  ~AccIterator();
 
   /**
    * Return next accessible complying with filter function. Return the first
    * accessible for the first time.
    */
   nsAccessible *GetNext();
 
-  /**
-   * Predefined filters.
-   */
-  static PRBool GetSelected(nsAccessible *aAccessible)
-  {
-    return nsAccUtils::State(aAccessible) & nsIAccessibleStates::STATE_SELECTED;
-  }
-  static PRBool GetSelectable(nsAccessible *aAccessible)
-  {
-    return nsAccUtils::State(aAccessible) & nsIAccessibleStates::STATE_SELECTABLE;
-  }
-  static PRBool GetRow(nsAccessible *aAccessible)
-  {
-    return nsAccUtils::Role(aAccessible) == nsIAccessibleRole::ROLE_ROW;
-  }
-  static PRBool GetCell(nsAccessible *aAccessible)
-  {
-    PRUint32 role = nsAccUtils::Role(aAccessible);
-    return role == nsIAccessibleRole::ROLE_GRID_CELL ||
-           role == nsIAccessibleRole::ROLE_ROWHEADER ||
-           role == nsIAccessibleRole::ROLE_COLUMNHEADER;
-  }
-
 private:
-  nsAccIterator();
-  nsAccIterator(const nsAccIterator&);
-  nsAccIterator& operator =(const nsAccIterator&);
+  AccIterator();
+  AccIterator(const AccIterator&);
+  AccIterator& operator =(const AccIterator&);
 
   struct IteratorState
   {
     IteratorState(nsAccessible *aParent, IteratorState *mParentState = nsnull);
 
     nsAccessible *mParent;
     PRInt32 mIndex;
     IteratorState *mParentState;
   };
 
-  AccIteratorFilterFuncPtr mFilterFunc;
+  filters::FilterFuncPtr mFilterFunc;
   PRBool mIsDeep;
   IteratorState *mState;
 };
 
 #endif
--- a/accessible/src/base/Makefile.in
+++ b/accessible/src/base/Makefile.in
@@ -43,20 +43,22 @@ VPATH = @srcdir@
 include $(DEPTH)/config/autoconf.mk
 
 MODULE = accessibility
 LIBRARY_NAME = accessibility_base_s
 LIBXUL_LIBRARY = 1
 
 
 CPPSRCS = \
+  AccCollector.cpp \
+  AccIterator.cpp \
+  filters.cpp \
   nsAccDocManager.cpp \
   nsAccessNode.cpp \
   nsAccEvent.cpp \
-  nsAccIterator.cpp \
   nsARIAGridAccessible.cpp \
   nsARIAMap.cpp \
   nsDocAccessible.cpp \
   nsOuterDocAccessible.cpp \
   nsAccessibilityAtoms.cpp \
   nsCoreUtils.cpp \
   nsAccUtils.cpp \
   nsRelUtils.cpp \
new file mode 100644
--- /dev/null
+++ b/accessible/src/base/filters.cpp
@@ -0,0 +1,74 @@
+/* ***** 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
+ * Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *  Alexander Surkov <surkov.alexander@gmail.com> (original author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either 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 "filters.h"
+
+#include "nsAccessible.h"
+#include "nsAccUtils.h"
+
+bool
+filters::GetSelected(nsAccessible* aAccessible)
+{
+  return nsAccUtils::State(aAccessible) & nsIAccessibleStates::STATE_SELECTED;
+}
+
+bool
+filters::GetSelectable(nsAccessible* aAccessible)
+{
+  return nsAccUtils::State(aAccessible) & nsIAccessibleStates::STATE_SELECTABLE;
+}
+
+bool
+filters::GetRow(nsAccessible* aAccessible)
+{
+  return nsAccUtils::Role(aAccessible) == nsIAccessibleRole::ROLE_ROW;
+}
+
+bool
+filters::GetCell(nsAccessible* aAccessible)
+{
+  PRUint32 role = nsAccUtils::Role(aAccessible);
+  return role == nsIAccessibleRole::ROLE_GRID_CELL ||
+      role == nsIAccessibleRole::ROLE_ROWHEADER ||
+      role == nsIAccessibleRole::ROLE_COLUMNHEADER;
+}
+
+bool
+filters::GetEmbeddedObject(nsAccessible* aAccessible)
+{
+  return nsAccUtils::IsEmbeddedObject(aAccessible);
+}
new file mode 100644
--- /dev/null
+++ b/accessible/src/base/filters.h
@@ -0,0 +1,60 @@
+/* ***** 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
+ * Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *  Alexander Surkov <surkov.alexander@gmail.com> (original author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either 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 ***** */
+
+#ifndef a11yFilters_h_
+#define a11yFilters_h_
+
+class nsAccessible;
+
+/**
+ * Predefined filters used for nsAccIterator and nsAccCollector.
+ */
+namespace filters {
+
+  /**
+   * Return true if the traversed accessible complies with filter.
+   */
+  typedef bool (*FilterFuncPtr) (nsAccessible*);
+
+  bool GetSelected(nsAccessible* aAccessible);
+  bool GetSelectable(nsAccessible* aAccessible);
+  bool GetRow(nsAccessible* aAccessible);
+  bool GetCell(nsAccessible* aAccessible);
+  bool GetEmbeddedObject(nsAccessible* aAccessible);
+}
+
+#endif
--- a/accessible/src/base/nsARIAGridAccessible.cpp
+++ b/accessible/src/base/nsARIAGridAccessible.cpp
@@ -33,32 +33,33 @@
  * 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 "nsARIAGridAccessible.h"
 
-#include "nsAccIterator.h"
+#include "AccIterator.h"
+#include "nsAccUtils.h"
 
 #include "nsIMutableArray.h"
 #include "nsComponentManagerUtils.h"
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsARIAGridAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
 
 ////////////////////////////////////////////////////////////////////////////////
 // Constructor
 
-nsARIAGridAccessible::nsARIAGridAccessible(nsIDOMNode* aDomNode,
-                                           nsIWeakReference* aShell) :
-  nsAccessibleWrap(aDomNode, aShell)
+nsARIAGridAccessible::
+  nsARIAGridAccessible(nsIContent *aContent, nsIWeakReference *aShell) :
+  nsAccessibleWrap(aContent, aShell)
 {
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsISupports
 
 NS_IMPL_ISUPPORTS_INHERITED1(nsARIAGridAccessible,
                              nsAccessible,
@@ -96,20 +97,20 @@ NS_IMETHODIMP
 nsARIAGridAccessible::GetColumnCount(PRInt32 *acolumnCount)
 {
   NS_ENSURE_ARG_POINTER(acolumnCount);
   *acolumnCount = 0;
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
-  nsAccIterator rowIter(this, nsAccIterator::GetRow);
+  AccIterator rowIter(this, filters::GetRow);
   nsAccessible *row = rowIter.GetNext();
 
-  nsAccIterator cellIter(row, nsAccIterator::GetCell);
+  AccIterator cellIter(row, filters::GetCell);
   nsAccessible *cell = nsnull;
 
   while ((cell = cellIter.GetNext()))
     (*acolumnCount)++;
 
   return NS_OK;
 }
 
@@ -117,17 +118,17 @@ NS_IMETHODIMP
 nsARIAGridAccessible::GetRowCount(PRInt32 *arowCount)
 {
   NS_ENSURE_ARG_POINTER(arowCount);
   *arowCount = 0;
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
-  nsAccIterator rowIter(this, nsAccIterator::GetRow);
+  AccIterator rowIter(this, filters::GetRow);
   while (rowIter.GetNext())
     (*arowCount)++;
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsARIAGridAccessible::GetCellAt(PRInt32 aRowIndex, PRInt32 aColumnIndex,
@@ -287,17 +288,17 @@ nsARIAGridAccessible::IsColumnSelected(P
   NS_ENSURE_ARG_POINTER(aIsSelected);
   *aIsSelected = PR_FALSE;
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
   NS_ENSURE_ARG(IsValidColumn(aColumn));
 
-  nsAccIterator rowIter(this, nsAccIterator::GetRow);
+  AccIterator rowIter(this, filters::GetRow);
   nsAccessible *row = rowIter.GetNext();
   if (!row)
     return NS_OK;
 
   do {
     if (!nsAccUtils::IsARIASelected(row)) {
       nsAccessible *cell = GetCellInRowAt(row, aColumn);
       if (!cell) // Do not fail due to wrong markup
@@ -320,17 +321,17 @@ nsARIAGridAccessible::IsRowSelected(PRIn
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
   nsAccessible *row = GetRowAt(aRow);
   NS_ENSURE_ARG(row);
 
   if (!nsAccUtils::IsARIASelected(row)) {
-    nsAccIterator cellIter(row, nsAccIterator::GetCell);
+    AccIterator cellIter(row, filters::GetCell);
     nsAccessible *cell = nsnull;
     while ((cell = cellIter.GetNext())) {
       if (!nsAccUtils::IsARIASelected(cell))
         return NS_OK;
     }
   }
 
   *aIsSelected = PR_TRUE;
@@ -369,26 +370,26 @@ nsARIAGridAccessible::GetSelectedCellCou
   *aCount = 0;
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
   PRInt32 colCount = 0;
   GetColumnCount(&colCount);
 
-  nsAccIterator rowIter(this, nsAccIterator::GetRow);
+  AccIterator rowIter(this, filters::GetRow);
 
   nsAccessible *row = nsnull;
   while ((row = rowIter.GetNext())) {
     if (nsAccUtils::IsARIASelected(row)) {
       (*aCount) += colCount;
       continue;
     }
 
-    nsAccIterator cellIter(row, nsAccIterator::GetCell);
+    AccIterator cellIter(row, filters::GetCell);
     nsAccessible *cell = nsnull;
 
     while ((cell = cellIter.GetNext())) {
       if (nsAccUtils::IsARIASelected(cell))
         (*aCount)++;
     }
   }
 
@@ -405,26 +406,26 @@ NS_IMETHODIMP
 nsARIAGridAccessible::GetSelectedRowCount(PRUint32* aCount)
 {
   NS_ENSURE_ARG_POINTER(aCount);
   *aCount = 0;
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
-  nsAccIterator rowIter(this, nsAccIterator::GetRow);
+  AccIterator rowIter(this, filters::GetRow);
 
   nsAccessible *row = nsnull;
   while ((row = rowIter.GetNext())) {
     if (nsAccUtils::IsARIASelected(row)) {
       (*aCount)++;
       continue;
     }
 
-    nsAccIterator cellIter(row, nsAccIterator::GetCell);
+    AccIterator cellIter(row, filters::GetCell);
     nsAccessible *cell = cellIter.GetNext();
     if (!cell)
       continue;
 
     PRBool isRowSelected = PR_TRUE;
     do {
       if (!nsAccUtils::IsARIASelected(cell)) {
         isRowSelected = PR_FALSE;
@@ -448,33 +449,33 @@ nsARIAGridAccessible::GetSelectedCells(n
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
   nsresult rv = NS_OK;
   nsCOMPtr<nsIMutableArray> selCells =
     do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  nsAccIterator rowIter(this, nsAccIterator::GetRow);
+  AccIterator rowIter(this, filters::GetRow);
 
   nsAccessible *row = nsnull;
   while (row = rowIter.GetNext()) {
-    nsAccIterator cellIter(row, nsAccIterator::GetCell);
-    nsIAccessible *cell = nsnull;
+    AccIterator cellIter(row, filters::GetCell);
+    nsAccessible *cell = nsnull;
 
     if (nsAccUtils::IsARIASelected(row)) {
       while (cell = cellIter.GetNext())
-        selCells->AppendElement(cell, PR_FALSE);
+        selCells->AppendElement(static_cast<nsIAccessible *>(cell), PR_FALSE);
 
       continue;
     }
 
     while (cell = cellIter.GetNext()) {
       if (nsAccUtils::IsARIASelected(cell))
-        selCells->AppendElement(cell, PR_FALSE);
+        selCells->AppendElement(static_cast<nsIAccessible *>(cell), PR_FALSE);
     }
   }
 
   NS_ADDREF(*aCells = selCells);
   return NS_OK;
 }
 
 NS_IMETHODIMP
@@ -492,28 +493,28 @@ nsARIAGridAccessible::GetSelectedCellInd
   PRInt32 rowCount = 0;
   GetRowCount(&rowCount);
 
   PRInt32 colCount = 0;
   GetColumnCount(&colCount);
 
   nsTArray<PRInt32> selCells(rowCount * colCount);
 
-  nsAccIterator rowIter(this, nsAccIterator::GetRow);
+  AccIterator rowIter(this, filters::GetRow);
 
   nsAccessible *row = nsnull;
   for (PRInt32 rowIdx = 0; row = rowIter.GetNext(); rowIdx++) {
     if (nsAccUtils::IsARIASelected(row)) {
       for (PRInt32 colIdx = 0; colIdx < colCount; colIdx++)
         selCells.AppendElement(rowIdx * colCount + colIdx);
 
       continue;
     }
 
-    nsAccIterator cellIter(row, nsAccIterator::GetCell);
+    AccIterator cellIter(row, filters::GetCell);
     nsAccessible *cell = nsnull;
 
     for (PRInt32 colIdx = 0; cell = cellIter.GetNext(); colIdx++) {
       if (nsAccUtils::IsARIASelected(cell))
         selCells.AppendElement(rowIdx * colCount + colIdx);
     }
   }
 
@@ -552,26 +553,26 @@ nsARIAGridAccessible::GetSelectedRowIndi
 
   PRInt32 rowCount = 0;
   GetRowCount(&rowCount);
   if (!rowCount)
     return NS_OK;
 
   nsTArray<PRInt32> selRows(rowCount);
 
-  nsAccIterator rowIter(this, nsAccIterator::GetRow);
+  AccIterator rowIter(this, filters::GetRow);
 
   nsAccessible *row = nsnull;
   for (PRInt32 rowIdx = 0; row = rowIter.GetNext(); rowIdx++) {
     if (nsAccUtils::IsARIASelected(row)) {
       selRows.AppendElement(rowIdx);
       continue;
     }
 
-    nsAccIterator cellIter(row, nsAccIterator::GetCell);
+    AccIterator cellIter(row, filters::GetCell);
     nsAccessible *cell = cellIter.GetNext();
     if (!cell)
       continue;
 
     PRBool isRowSelected = PR_TRUE;
     do {
       if (!nsAccUtils::IsARIASelected(cell)) {
         isRowSelected = PR_FALSE;
@@ -598,17 +599,17 @@ nsARIAGridAccessible::GetSelectedRowIndi
 NS_IMETHODIMP
 nsARIAGridAccessible::SelectRow(PRInt32 aRow)
 {
   NS_ENSURE_ARG(IsValidRow(aRow));
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
-  nsAccIterator rowIter(this, nsAccIterator::GetRow);
+  AccIterator rowIter(this, filters::GetRow);
 
   nsAccessible *row = nsnull;
   for (PRInt32 rowIdx = 0; row = rowIter.GetNext(); rowIdx++) {
     nsresult rv = SetARIASelected(row, rowIdx == aRow);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   return NS_OK;
@@ -617,17 +618,17 @@ nsARIAGridAccessible::SelectRow(PRInt32 
 NS_IMETHODIMP
 nsARIAGridAccessible::SelectColumn(PRInt32 aColumn)
 {
   NS_ENSURE_ARG(IsValidColumn(aColumn));
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
-  nsAccIterator rowIter(this, nsAccIterator::GetRow);
+  AccIterator rowIter(this, filters::GetRow);
 
   nsAccessible *row = nsnull;
   while ((row = rowIter.GetNext())) {
     // Unselect all cells in the row.
     nsresult rv = SetARIASelected(row, PR_FALSE);
     NS_ENSURE_SUCCESS(rv, rv);
 
     // Select cell at the column index.
@@ -656,17 +657,17 @@ nsARIAGridAccessible::UnselectRow(PRInt3
 NS_IMETHODIMP
 nsARIAGridAccessible::UnselectColumn(PRInt32 aColumn)
 {
   NS_ENSURE_ARG(IsValidColumn(aColumn));
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
-  nsAccIterator rowIter(this, nsAccIterator::GetRow);
+  AccIterator rowIter(this, filters::GetRow);
 
   nsAccessible *row = nsnull;
   while ((row = rowIter.GetNext())) {
     nsAccessible *cell = GetCellInRowAt(row, aColumn);
     if (cell) {
       nsresult rv = SetARIASelected(cell, PR_FALSE);
       NS_ENSURE_SUCCESS(rv, rv);
     }
@@ -725,43 +726,43 @@ nsARIAGridAccessible::IsValidRowNColumn(
   return aColumn < colCount;
 }
 
 nsAccessible*
 nsARIAGridAccessible::GetRowAt(PRInt32 aRow)
 {
   PRInt32 rowIdx = aRow;
 
-  nsAccIterator rowIter(this, nsAccIterator::GetRow);
+  AccIterator rowIter(this, filters::GetRow);
 
   nsAccessible *row = rowIter.GetNext();
   while (rowIdx != 0 && (row = rowIter.GetNext()))
     rowIdx--;
 
   return row;
 }
 
 nsAccessible*
 nsARIAGridAccessible::GetCellInRowAt(nsAccessible *aRow, PRInt32 aColumn)
 {
   PRInt32 colIdx = aColumn;
 
-  nsAccIterator cellIter(aRow, nsAccIterator::GetCell);
+  AccIterator cellIter(aRow, filters::GetCell);
   nsAccessible *cell = cellIter.GetNext();
   while (colIdx != 0 && (cell = cellIter.GetNext()))
     colIdx--;
 
   return cell;
 }
 
 nsresult
 nsARIAGridAccessible::SetARIASelected(nsAccessible *aAccessible,
                                       PRBool aIsSelected, PRBool aNotify)
 {
-  nsCOMPtr<nsIContent> content(do_QueryInterface(aAccessible->GetDOMNode()));
+  nsIContent *content = aAccessible->GetContent();
   NS_ENSURE_STATE(content);
 
   nsresult rv = NS_OK;
   if (aIsSelected)
     rv = content->SetAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_selected,
                           NS_LITERAL_STRING("true"), aNotify);
   else
     rv = content->UnsetAttr(kNameSpaceID_None,
@@ -779,17 +780,17 @@ nsARIAGridAccessible::SetARIASelected(ns
   if (aIsSelected)
     return NS_OK;
 
   PRUint32 role = nsAccUtils::Role(aAccessible);
 
   // If the given accessible is row that was unselected then remove
   // aria-selected from cell accessible.
   if (role == nsIAccessibleRole::ROLE_ROW) {
-    nsAccIterator cellIter(aAccessible, nsAccIterator::GetCell);
+    AccIterator cellIter(aAccessible, filters::GetCell);
     nsAccessible *cell = nsnull;
 
     while ((cell = cellIter.GetNext())) {
       rv = SetARIASelected(cell, PR_FALSE, PR_FALSE);
       NS_ENSURE_SUCCESS(rv, rv);
     }
     return NS_OK;
   }
@@ -802,17 +803,17 @@ nsARIAGridAccessible::SetARIASelected(ns
       role == nsIAccessibleRole::ROLE_COLUMNHEADER) {
     nsAccessible *row = aAccessible->GetParent();
 
     if (nsAccUtils::Role(row) == nsIAccessibleRole::ROLE_ROW &&
         nsAccUtils::IsARIASelected(row)) {
       rv = SetARIASelected(row, PR_FALSE, PR_FALSE);
       NS_ENSURE_SUCCESS(rv, rv);
 
-      nsAccIterator cellIter(row, nsAccIterator::GetCell);
+      AccIterator cellIter(row, filters::GetCell);
       nsAccessible *cell = nsnull;
       while ((cell = cellIter.GetNext())) {
         if (cell != aAccessible) {
           rv = SetARIASelected(cell, PR_TRUE, PR_FALSE);
           NS_ENSURE_SUCCESS(rv, rv);
         }
       }
     }
@@ -828,17 +829,17 @@ nsARIAGridAccessible::GetSelectedColumns
   NS_ENSURE_ARG_POINTER(acolumnCount);
   *acolumnCount = 0;
   if (aColumns)
     *aColumns = nsnull;
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
-  nsAccIterator rowIter(this, nsAccIterator::GetRow);
+  AccIterator rowIter(this, filters::GetRow);
   nsAccessible *row = rowIter.GetNext();
   if (!row)
     return NS_OK;
 
   PRInt32 colCount = 0;
   GetColumnCount(&colCount);
   if (!colCount)
     return NS_OK;
@@ -851,17 +852,17 @@ nsARIAGridAccessible::GetSelectedColumns
     isColSelArray[i] = PR_TRUE;
 
   do {
     if (nsAccUtils::IsARIASelected(row))
       continue;
 
     PRInt32 colIdx = 0;
 
-    nsAccIterator cellIter(row, nsAccIterator::GetCell);
+    AccIterator cellIter(row, filters::GetCell);
     nsAccessible *cell = nsnull;
     for (colIdx = 0; cell = cellIter.GetNext(); colIdx++) {
       if (isColSelArray.SafeElementAt(colIdx, PR_FALSE) &&
           !nsAccUtils::IsARIASelected(cell)) {
         isColSelArray[colIdx] = PR_FALSE;
         selColCount--;
       }
     }
@@ -892,19 +893,19 @@ nsARIAGridAccessible::GetSelectedColumns
 ////////////////////////////////////////////////////////////////////////////////
 // nsARIAGridCellAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
 
 ////////////////////////////////////////////////////////////////////////////////
 // Constructor
 
-nsARIAGridCellAccessible::nsARIAGridCellAccessible(nsIDOMNode* aDomNode,
-                                                   nsIWeakReference* aShell) :
-  nsHyperTextAccessibleWrap(aDomNode, aShell)
+nsARIAGridCellAccessible::
+  nsARIAGridCellAccessible(nsIContent *aContent, nsIWeakReference *aShell) :
+  nsHyperTextAccessibleWrap(aContent, aShell)
 {
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsISupports
 
 NS_IMPL_ISUPPORTS_INHERITED1(nsARIAGridCellAccessible,
                              nsHyperTextAccessible,
@@ -1053,18 +1054,17 @@ NS_IMETHODIMP
 nsARIAGridCellAccessible::IsSelected(PRBool *aIsSelected)
 {
   NS_ENSURE_ARG_POINTER(aIsSelected);
   *aIsSelected = PR_FALSE;
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
-  nsCOMPtr<nsIAccessible> row;
-  GetParent(getter_AddRefs(row));
+  nsAccessible *row = GetParent();
   if (nsAccUtils::Role(row) != nsIAccessibleRole::ROLE_ROW)
     return NS_OK;
 
   if (!nsAccUtils::IsARIASelected(row) && !nsAccUtils::IsARIASelected(this))
     return NS_OK;
 
   *aIsSelected = PR_TRUE;
   return NS_OK;
@@ -1079,27 +1079,21 @@ nsARIAGridCellAccessible::GetARIAState(P
   nsresult rv = nsHyperTextAccessibleWrap::GetARIAState(aState, aExtraState);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Return if the gridcell has aria-selected="true".
   if (*aState & nsIAccessibleStates::STATE_SELECTED)
     return NS_OK;
 
   // Check aria-selected="true" on the row.
-  nsCOMPtr<nsIAccessible> row;
-  GetParent(getter_AddRefs(row));
+  nsAccessible *row = GetParent();
   if (nsAccUtils::Role(row) != nsIAccessibleRole::ROLE_ROW)
     return NS_OK;
 
-  nsRefPtr<nsAccessible> acc = do_QueryObject(row);
-  nsCOMPtr<nsIDOMNode> rowNode;
-  acc->GetDOMNode(getter_AddRefs(rowNode));
-  NS_ENSURE_STATE(rowNode);
-
-  nsCOMPtr<nsIContent> rowContent(do_QueryInterface(rowNode));
+  nsIContent *rowContent = row->GetContent();
   if (nsAccUtils::HasDefinedARIAToken(rowContent,
                                       nsAccessibilityAtoms::aria_selected) &&
       !rowContent->AttrValueIs(kNameSpaceID_None,
                                nsAccessibilityAtoms::aria_selected,
                                nsAccessibilityAtoms::_false, eCaseMatters)) {
 
     *aState |= nsIAccessibleStates::STATE_SELECTABLE |
       nsIAccessibleStates::STATE_SELECTED;
--- a/accessible/src/base/nsARIAGridAccessible.h
+++ b/accessible/src/base/nsARIAGridAccessible.h
@@ -45,17 +45,17 @@
 
 /**
  * Accessible for ARIA grid and treegrid.
  */
 class nsARIAGridAccessible : public nsAccessibleWrap,
                              public nsIAccessibleTable
 {
 public:
-  nsARIAGridAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell);
+  nsARIAGridAccessible(nsIContent *aContent, nsIWeakReference *aShell);
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIAccessibleTable
   NS_DECL_NSIACCESSIBLETABLE
 
 protected:
@@ -105,17 +105,17 @@ protected:
 
 /**
  * Accessible for ARIA gridcell and rowheader/columnheader.
  */
 class nsARIAGridCellAccessible : public nsHyperTextAccessibleWrap,
                                  public nsIAccessibleTableCell
 {
 public:
-  nsARIAGridCellAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell);
+  nsARIAGridCellAccessible(nsIContent *aContent, nsIWeakReference *aShell);
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIAccessibleTableCell
   NS_DECL_NSIACCESSIBLETABLECELL
 
   // nsAccessible
--- a/accessible/src/base/nsAccCache.h
+++ b/accessible/src/base/nsAccCache.h
@@ -37,32 +37,32 @@
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef _nsAccCache_H_
 #define _nsAccCache_H_
 
 #include "nsRefPtrHashtable.h"
 #include "nsCycleCollectionParticipant.h"
 
-class nsIAccessNode;
+class nsIAccessible;
 
 ////////////////////////////////////////////////////////////////////////////////
 // Accessible cache utils
 ////////////////////////////////////////////////////////////////////////////////
 
 /**
  * Shutdown and removes the accessible from cache.
  */
 template <class T>
 static PLDHashOperator
-ClearCacheEntry(const void* aKey, nsRefPtr<T>& aAccessNode, void* aUserArg)
+ClearCacheEntry(const void* aKey, nsRefPtr<T>& aAccessible, void* aUserArg)
 {
-  NS_ASSERTION(aAccessNode, "Calling ClearCacheEntry with a NULL pointer!");
-  if (aAccessNode)
-    aAccessNode->Shutdown();
+  NS_ASSERTION(aAccessible, "Calling ClearCacheEntry with a NULL pointer!");
+  if (aAccessible)
+    aAccessible->Shutdown();
 
   return PL_DHASH_REMOVE;
 }
 
 /**
  * Clear the cache and shutdown the accessibles.
  */
 template <class T>
@@ -72,25 +72,25 @@ ClearCache(nsRefPtrHashtable<nsVoidPtrHa
   aCache.Enumerate(ClearCacheEntry<T>, nsnull);
 }
 
 /**
  * Traverse the accessible cache entry for cycle collector.
  */
 template <class T>
 static PLDHashOperator
-CycleCollectorTraverseCacheEntry(const void *aKey, T *aAccessNode,
+CycleCollectorTraverseCacheEntry(const void *aKey, T *aAccessible,
                                  void *aUserArg)
 {
   nsCycleCollectionTraversalCallback *cb =
     static_cast<nsCycleCollectionTraversalCallback*>(aUserArg);
 
   NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(*cb, "accessible cache entry");
 
-  nsISupports *supports = static_cast<nsIAccessNode*>(aAccessNode);
+  nsISupports *supports = static_cast<nsIAccessible*>(aAccessible);
   cb->NoteXPCOMChild(supports);
   return PL_DHASH_NEXT;
 }
 
 /**
  * Traverse the accessible cache for cycle collector.
  */
 template <class T>
--- a/accessible/src/base/nsAccDocManager.cpp
+++ b/accessible/src/base/nsAccDocManager.cpp
@@ -1,8 +1,9 @@
+/* -*- 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/
  *
@@ -90,16 +91,17 @@ nsAccDocManager::FindAccessibleInCache(v
 void
 nsAccDocManager::ShutdownDocAccessiblesInTree(nsIDocument *aDocument)
 {
   nsCOMPtr<nsISupports> container = aDocument->GetContainer();
   nsCOMPtr<nsIDocShellTreeItem> treeItem = do_QueryInterface(container);
   ShutdownDocAccessiblesInTree(treeItem, aDocument);
 }
 
+
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccDocManager protected
 
 PRBool
 nsAccDocManager::Init()
 {
   mDocAccessibleCache.Init(4);
 
@@ -122,16 +124,32 @@ nsAccDocManager::Shutdown()
     do_GetService(NS_DOCUMENTLOADER_SERVICE_CONTRACTID);
 
   if (progress)
     progress->RemoveProgressListener(static_cast<nsIWebProgressListener*>(this));
 
   ClearDocCache();
 }
 
+void
+nsAccDocManager::ShutdownDocAccessible(nsIDocument *aDocument)
+{
+  nsDocAccessible* docAccessible =
+    mDocAccessibleCache.GetWeak(static_cast<void*>(aDocument));
+  if (!docAccessible)
+    return;
+
+  // We're allowed to not remove listeners when accessible document is shutdown
+  // since we don't keep strong reference on chrome event target and listeners
+  // are removed automatically when chrome event target goes away.
+
+  docAccessible->Shutdown();
+  mDocAccessibleCache.Remove(static_cast<void*>(aDocument));
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // nsISupports
 
 NS_IMPL_THREADSAFE_ISUPPORTS3(nsAccDocManager,
                               nsIWebProgressListener,
                               nsIDOMEventListener,
                               nsISupportsWeakReference)
 
@@ -197,18 +215,16 @@ nsAccDocManager::OnStateChange(nsIWebPro
     mDocAccessibleCache.GetWeak(static_cast<void*>(document));
   if (!docAcc)
     return NS_OK;
 
   nsCOMPtr<nsIWebNavigation> webNav(do_GetInterface(DOMWindow));
   nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(webNav));
   NS_ENSURE_STATE(docShell);
 
-  nsCOMPtr<nsIDOMNode> DOMNode = do_QueryInterface(document);
-
   // Fire reload and state busy events on existing document accessible while
   // event from user input flag can be calculated properly and accessible
   // is alive. When new document gets loaded then this one is destroyed.
   PRUint32 loadType;
   docShell->GetLoadType(&loadType);
   if (loadType == LOAD_RELOAD_NORMAL ||
       loadType == LOAD_RELOAD_BYPASS_CACHE ||
       loadType == LOAD_RELOAD_BYPASS_PROXY ||
@@ -218,17 +234,17 @@ nsAccDocManager::OnStateChange(nsIWebPro
     nsRefPtr<nsAccEvent> reloadEvent =
       new nsAccEvent(nsIAccessibleEvent::EVENT_DOCUMENT_RELOAD, docAcc);
     nsEventShell::FireEvent(reloadEvent);
   }
 
   // Fire state busy change event. Use delayed event since we don't care
   // actually if event isn't delivered when the document goes away like a shot.
   nsRefPtr<nsAccEvent> stateEvent =
-    new nsAccStateChangeEvent(DOMNode, nsIAccessibleStates::STATE_BUSY,
+    new nsAccStateChangeEvent(document, nsIAccessibleStates::STATE_BUSY,
                               PR_FALSE, PR_TRUE);
   docAcc->FireDelayedAccessibleEvent(stateEvent);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsAccDocManager::OnProgressChange(nsIWebProgress *aWebProgress,
@@ -352,25 +368,24 @@ nsAccDocManager::HandleDOMDocumentLoad(n
     if (!nsCoreUtils::IsRootDocument(aDocument)) {
       docAcc->InvalidateCacheSubtree(nsnull,
                                      nsIAccessibilityService::NODE_SIGNIFICANT_CHANGE);
     }
     return;
   }
 
   // Fire complete/load stopped if the load event type is given.
-  nsCOMPtr<nsIDOMNode> DOMNode = do_QueryInterface(aDocument);
   if (aLoadEventType) {
-    nsRefPtr<nsAccEvent> loadEvent = new nsAccEvent(aLoadEventType, DOMNode);
+    nsRefPtr<nsAccEvent> loadEvent = new nsAccEvent(aLoadEventType, aDocument);
     docAcc->FireDelayedAccessibleEvent(loadEvent);
   }
 
   // Fire busy state change event.
   nsRefPtr<nsAccEvent> stateEvent =
-    new nsAccStateChangeEvent(DOMNode, nsIAccessibleStates::STATE_BUSY,
+    new nsAccStateChangeEvent(aDocument, nsIAccessibleStates::STATE_BUSY,
                               PR_FALSE, PR_FALSE);
   docAcc->FireDelayedAccessibleEvent(stateEvent);
 }
 
 PRBool
 nsAccDocManager::IsEventTargetDocument(nsIDocument *aDocument) const
 {
   nsCOMPtr<nsISupports> container = aDocument->GetContainer();
@@ -410,201 +425,154 @@ nsAccDocManager::AddListeners(nsIDocumen
 
   if (aAddDOMContentLoadedListener) {
     elm->AddEventListenerByType(this, NS_LITERAL_STRING("DOMContentLoaded"),
                                 NS_EVENT_FLAG_CAPTURE, nsnull);
     NS_LOG_ACCDOCCREATE_TEXT("  added 'DOMContentLoaded' listener")
   }
 }
 
-void
-nsAccDocManager::RemoveListeners(nsIDocument *aDocument)
-{
-  // Document has no window when application shuts down. The document can still
-  // exist because we didn't receive a "pagehide" event.
-  nsPIDOMWindow *window = aDocument->GetWindow();
-  if (!window)
-    return;
-
-  nsPIDOMEventTarget *target = window->GetChromeEventHandler();
-  nsIEventListenerManager* elm = target->GetListenerManager(PR_TRUE);
-  elm->RemoveEventListenerByType(this, NS_LITERAL_STRING("pagehide"),
-                                 NS_EVENT_FLAG_CAPTURE, nsnull);
-
-  NS_LOG_ACCDOCDESTROY("removed 'pagehide' listener", aDocument)
-
-  if (nsCoreUtils::IsRootDocument(aDocument)) {
-    elm->RemoveEventListenerByType(this, NS_LITERAL_STRING("DOMContentLoaded"),
-                                     NS_EVENT_FLAG_CAPTURE, nsnull);
-
-    NS_LOG_ACCDOCDESTROY("removed 'DOMContentLoaded' listener", aDocument)
-  }
-}
-
 nsDocAccessible*
 nsAccDocManager::CreateDocOrRootAccessible(nsIDocument *aDocument)
 {
-  // Ignore temporary and hiding documents.
-  if (aDocument->IsInitialDocument() || !aDocument->IsVisible())
+  // Ignore temporary, hiding and svg resource documents.
+  if (aDocument->IsInitialDocument() || !aDocument->IsVisible() ||
+      aDocument->GetDisplayDocument())
     return nsnull;
 
   // Ignore documents without presshell.
   nsIPresShell *presShell = aDocument->GetPrimaryShell();
   if (!presShell)
     return nsnull;
 
   // Do not create document accessible until role content is loaded, otherwise
   // we get accessible document with wrong role.
-  nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(aDocument));
-  if (!nsCoreUtils::GetRoleContent(DOMNode))
-    return NS_OK;
+  nsIContent *rootElm = nsCoreUtils::GetRoleContent(aDocument);
+  if (!rootElm)
+    return nsnull;
 
   PRBool isRootDoc = nsCoreUtils::IsRootDocument(aDocument);
 
   // Ensure the document container node is accessible, otherwise do not create
   // document accessible.
   nsAccessible *outerDocAcc = nsnull;
   if (!isRootDoc) {
     nsIDocument* parentDoc = aDocument->GetParentDocument();
     if (!parentDoc)
       return nsnull;
 
     nsIContent* ownerContent = parentDoc->FindContentForSubDocument(aDocument);
-    nsCOMPtr<nsIDOMNode> ownerNode(do_QueryInterface(ownerContent));
-    if (!ownerNode)
+    if (!ownerContent)
       return nsnull;
 
     // XXXaaronl: ideally we would traverse the presshell chain. Since there's
     // no easy way to do that, we cheat and use the document hierarchy.
     // GetAccessible() is bad because it doesn't support our concept of multiple
     // presshells per doc. It should be changed to use
     // GetAccessibleInWeakShell().
-    outerDocAcc = GetAccService()->GetAccessible(ownerNode);
+    outerDocAcc = GetAccService()->GetAccessible(ownerContent);
     if (!outerDocAcc)
       return nsnull;
   }
 
   nsCOMPtr<nsIWeakReference> weakShell(do_GetWeakReference(presShell));
 
   // We only create root accessibles for the true root, otherwise create a
   // doc accessible.
   nsDocAccessible *docAcc = isRootDoc ?
-    new nsRootAccessibleWrap(DOMNode, weakShell) :
-    new nsDocAccessibleWrap(DOMNode, weakShell);
+    new nsRootAccessibleWrap(aDocument, rootElm, weakShell) :
+    new nsDocAccessibleWrap(aDocument, rootElm, weakShell);
 
   if (!docAcc)
     return nsnull;
 
   // Cache and addref document accessible.
   if (!mDocAccessibleCache.Put(static_cast<void*>(aDocument), docAcc)) {
     delete docAcc;
     return nsnull;
   }
 
   // XXX: ideally we should initialize an accessible and then put it into tree,
   // also this code should be shared between doc and root accessibles.
   if (outerDocAcc) {
     // Root document accessible doesn't have associated outerdoc accessible, it
     // adds itself to application accessible instead.
-    NS_LOG_ACCDOCCREATE("append document to outerdoc", aDocument)
     outerDocAcc->AppendChild(docAcc);
   }
 
   if (!GetAccService()->InitAccessible(docAcc,
-                                       nsAccUtils::GetRoleMapEntry(DOMNode))) {
+                                       nsAccUtils::GetRoleMapEntry(aDocument))) {
     mDocAccessibleCache.Remove(static_cast<void*>(aDocument));
     return nsnull;
   }
 
-  NS_LOG_ACCDOCCREATE("document created", aDocument)
+  NS_LOG_ACCDOCCREATE("document creation finished", aDocument)
 
   AddListeners(aDocument, isRootDoc);
   return docAcc;
 }
 
 void
 nsAccDocManager::ShutdownDocAccessiblesInTree(nsIDocShellTreeItem *aTreeItem,
                                               nsIDocument *aDocument)
 {
   nsCOMPtr<nsIDocShellTreeNode> treeNode(do_QueryInterface(aTreeItem));
-  if (!treeNode)
-    return;
 
-  PRInt32 subDocumentsCount = 0;
-  treeNode->GetChildCount(&subDocumentsCount);
-  for (PRInt32 idx = 0; idx < subDocumentsCount; idx++) {
-    nsCOMPtr<nsIDocShellTreeItem> treeItemChild;
-    treeNode->GetChildAt(idx, getter_AddRefs(treeItemChild));
-    NS_ASSERTION(treeItemChild, "No tree item when there should be");
-    if (!treeItemChild)
-      continue;
+  if (treeNode) {
+    PRInt32 subDocumentsCount = 0;
+    treeNode->GetChildCount(&subDocumentsCount);
+    for (PRInt32 idx = 0; idx < subDocumentsCount; idx++) {
+      nsCOMPtr<nsIDocShellTreeItem> treeItemChild;
+      treeNode->GetChildAt(idx, getter_AddRefs(treeItemChild));
+      NS_ASSERTION(treeItemChild, "No tree item when there should be");
+      if (!treeItemChild)
+        continue;
 
-    nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(treeItemChild));
-    nsCOMPtr<nsIContentViewer> contentViewer;
-    docShell->GetContentViewer(getter_AddRefs(contentViewer));
-    if (!contentViewer)
-      continue;
+      nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(treeItemChild));
+      nsCOMPtr<nsIContentViewer> contentViewer;
+      docShell->GetContentViewer(getter_AddRefs(contentViewer));
+      if (!contentViewer)
+        continue;
 
-    ShutdownDocAccessiblesInTree(treeItemChild, contentViewer->GetDocument());
+      ShutdownDocAccessiblesInTree(treeItemChild, contentViewer->GetDocument());
+    }
   }
 
   ShutdownDocAccessible(aDocument);
 }
 
-void
-nsAccDocManager::ShutdownDocAccessible(nsIDocument *aDocument)
-{
-  RemoveListeners(aDocument);
-
-  nsDocAccessible *docAccessible =
-    mDocAccessibleCache.GetWeak(static_cast<void*>(aDocument));
-  if (docAccessible)
-    docAccessible->Shutdown();
-
-  mDocAccessibleCache.Remove(static_cast<void*>(aDocument));
-}
-
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccDocManager static
 
 PLDHashOperator
 nsAccDocManager::ClearDocCacheEntry(const void* aKey,
                                     nsRefPtr<nsDocAccessible>& aDocAccessible,
                                     void* aUserArg)
 {
   nsAccDocManager *accDocMgr = static_cast<nsAccDocManager*>(aUserArg);
 
   NS_ASSERTION(aDocAccessible,
                "Calling ClearDocCacheEntry with a NULL pointer!");
 
-  if (aDocAccessible) {
-    nsCOMPtr<nsIDocument> document = aDocAccessible->GetDOMDocument();
-    NS_ASSERTION(document, "Document accessible was shutdown already!");
-    if (document)
-      accDocMgr->RemoveListeners(document);
-
+  if (aDocAccessible)
     aDocAccessible->Shutdown();
-  }
 
   return PL_DHASH_REMOVE;
 }
 
 PLDHashOperator
 nsAccDocManager::SearchAccessibleInDocCache(const void* aKey,
                                             nsDocAccessible* aDocAccessible,
                                             void* aUserArg)
 {
   NS_ASSERTION(aDocAccessible,
                "No doc accessible for the object in doc accessible cache!");
 
   if (aDocAccessible) {
     nsSearchAccessibleInCacheArg* arg =
       static_cast<nsSearchAccessibleInCacheArg*>(aUserArg);
-    nsAccessNode* accessNode =
-      aDocAccessible->GetCachedAccessNode(arg->mUniqueID);
-    if (accessNode) {
-      arg->mAccessible = do_QueryObject(accessNode);
+    arg->mAccessible = aDocAccessible->GetCachedAccessible(arg->mUniqueID);
+    if (arg->mAccessible)
       return PL_DHASH_STOP;
-    }
   }
 
   return PL_DHASH_NEXT;
 }
--- a/accessible/src/base/nsAccDocManager.h
+++ b/accessible/src/base/nsAccDocManager.h
@@ -43,16 +43,18 @@
 #include "nsIDocument.h"
 #include "nsIDOMEventListener.h"
 #include "nsIWebProgress.h"
 #include "nsIWebProgressListener.h"
 #include "nsWeakReference.h"
 
 class nsDocAccessible;
 
+//#define DEBUG_ACCDOCMGR
+
 /**
  * Manage the document accessible life cycle.
  */
 class nsAccDocManager : public nsIWebProgressListener,
                         public nsIDOMEventListener,
                         public nsSupportsWeakReference
 {
 public:
@@ -75,29 +77,42 @@ public:
 
   /**
    * Shutdown document accessibles in the tree starting from the given one.
    *
    * @param  aDocument  [in] the DOM document of start document accessible
    */
   void ShutdownDocAccessiblesInTree(nsIDocument *aDocument);
 
+  /**
+   * Return document accessible from the cache. Convenient method for testing.
+   */
+  inline nsDocAccessible* GetDocAccessibleFromCache(nsIDocument* aDocument) const
+  {
+    return mDocAccessibleCache.GetWeak(static_cast<void*>(aDocument));
+  }
+
 protected:
   nsAccDocManager() { };
 
   /**
    * Initialize the manager.
    */
   PRBool Init();
 
   /**
    * Shutdown the manager.
    */
   void Shutdown();
 
+  /**
+   * Shutdown the document accessible.
+   */
+  void ShutdownDocAccessible(nsIDocument* aDocument);
+
 private:
   nsAccDocManager(const nsAccDocManager&);
   nsAccDocManager& operator =(const nsAccDocManager&);
 
 private:
   /**
    * Create an accessible document if it was't created and fire accessibility
    * events if needed.
@@ -127,37 +142,31 @@ private:
    * them have separate processing of iframe documents on the page and therefore
    * they need a way to distinguish sub documents from page document). Ideally
    * we should make events firing for any loaded document and provide additional
    * info AT are needing.
    */
   PRBool IsEventTargetDocument(nsIDocument *aDocument) const;
 
   /**
-   * Add/remove 'pagehide' and 'DOMContentLoaded' event listeners.
+   * Add 'pagehide' and 'DOMContentLoaded' event listeners.
    */
   void AddListeners(nsIDocument *aDocument, PRBool aAddPageShowListener);
-  void RemoveListeners(nsIDocument *aDocument);
 
   /**
    * Create document or root accessible.
    */
   nsDocAccessible *CreateDocOrRootAccessible(nsIDocument *aDocument);
 
   /**
    * Shutdown document accessibles in the tree starting from given tree item.
    */
   void ShutdownDocAccessiblesInTree(nsIDocShellTreeItem *aTreeItem,
                                     nsIDocument *aDocument);
 
-  /**
-   * Shutdown the document accessible.
-   */
-  void ShutdownDocAccessible(nsIDocument *aDocument);
-
   typedef nsRefPtrHashtable<nsVoidPtrHashKey, nsDocAccessible>
     nsDocAccessibleHashtable;
 
   /**
    * Shutdown and remove the document accessible from cache.
    */
   static PLDHashOperator
     ClearDocCacheEntry(const void* aKey,
@@ -169,45 +178,41 @@ private:
    */
   void ClearDocCache()
   {
     mDocAccessibleCache.Enumerate(ClearDocCacheEntry, static_cast<void*>(this));
   }
 
   struct nsSearchAccessibleInCacheArg
   {
-    nsRefPtr<nsAccessible> mAccessible;
+    nsAccessible *mAccessible;
     void *mUniqueID;
   };
 
   static PLDHashOperator
     SearchAccessibleInDocCache(const void* aKey,
                                nsDocAccessible* aDocAccessible,
                                void* aUserArg);
 
   nsDocAccessibleHashtable mDocAccessibleCache;
 };
 
 /**
  * nsAccDocManager debugging macros.
  */
-//#define DEBUG_ACCDOCMGR
-
 #ifdef DEBUG_ACCDOCMGR
 
 // Enable these to log accessible document loading, creation or destruction.
 #define DEBUG_ACCDOCMGR_DOCLOAD
 #define DEBUG_ACCDOCMGR_DOCCREATE
 #define DEBUG_ACCDOCMGR_DOCDESTROY
 
 // Common macros, do not use directly.
 #define NS_LOG_ACCDOC_ADDRESS(aDocument, aDocAcc)                              \
-  printf("DOM id: 0x%x, acc id: 0x%x",                                         \
-         reinterpret_cast<PRInt32>(static_cast<void*>(aDocument)),             \
-         reinterpret_cast<PRInt32>(aDocAcc));
+  printf("DOM id: %p, acc id: %p", aDocument, aDocAcc);
 
 #define NS_LOG_ACCDOC_URI(aDocument)                                           \
   nsIURI *uri = aDocument->GetDocumentURI();                                   \
   nsCAutoString spec;                                                          \
   uri->GetSpec(spec);                                                          \
   printf("uri: %s", spec);
 
 #define NS_LOG_ACCDOC_TYPE(aDocument)                                          \
@@ -250,29 +255,28 @@ private:
   printf("doc state: %s", docState);                                           \
   printf(", %sinitial", aDocument->IsInitialDocument() ? "" : "not ");         \
   printf(", %sshowing", aDocument->IsShowing() ? "" : "not ");                 \
   printf(", %svisible", aDocument->IsVisible() ? "" : "not ");                 \
   printf(", %sactive", aDocument->IsActive() ? "" : "not ");
 
 #define NS_LOG_ACCDOC_DOCPRESSHELL(aDocument)                                  \
   nsIPresShell *ps = aDocument->GetPrimaryShell();                             \
-  printf("presshell: 0x%x", reinterpret_cast<PRInt32>(ps));                    \
+  printf("presshell: %p", ps);                                                 \
   nsIScrollableFrame *sf = ps ?                                                \
     ps->GetRootScrollFrameAsScrollableExternal() : nsnull;                     \
-  printf(", root scroll frame: 0x%x", reinterpret_cast<PRInt32>(sf));
+  printf(", root scroll frame: %p", sf);
 
 #define NS_LOG_ACCDOC_DOCLOADGROUP(aDocument)                                  \
   nsCOMPtr<nsILoadGroup> loadGroup = aDocument->GetDocumentLoadGroup();        \
-  printf("load group: 0x%x", reinterpret_cast<PRInt32>(loadGroup.get()));
+  printf("load group: %p", loadGroup);
 
 #define NS_LOG_ACCDOC_DOCPARENT(aDocument)                                     \
   nsIDocument *parentDoc = aDocument->GetParentDocument();                     \
-  printf("parent id: 0x%x",                                                    \
-         reinterpret_cast<PRInt32>(parentDoc));                                \
+  printf("parent id: %p", parentDoc);                                          \
   if (parentDoc) {                                                             \
     printf("\n    parent ");                                                   \
     NS_LOG_ACCDOC_URI(parentDoc)                                               \
     printf("\n");                                                              \
   }
 
 #define NS_LOG_ACCDOC_SHELLLOADTYPE(aDocShell)                                 \
   {                                                                            \
@@ -377,30 +381,41 @@ private:
   PRUint32 type = aEvent->GetEventType();                                      \
   if (type == nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_STOPPED) {               \
     strEventType.AssignLiteral("load stopped");                                \
   } else if (type == nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE) {       \
     strEventType.AssignLiteral("load complete");                               \
   } else if (type == nsIAccessibleEvent::EVENT_DOCUMENT_RELOAD) {              \
       strEventType.AssignLiteral("reload");                                    \
   } else if (type == nsIAccessibleEvent::EVENT_STATE_CHANGE) {                 \
-    nsCOMPtr<nsIAccessibleStateChangeEvent> event(do_QueryObject(aEvent));     \
-    PRUint32 state = 0;                                                        \
-    event->GetState(&state);                                                   \
-    if (state == nsIAccessibleStates::STATE_BUSY) {                            \
-      PRBool isEnabled;                                                        \
-      event->IsEnabled(&isEnabled);                                            \
+    nsAccStateChangeEvent *event = downcast_accEvent(aEvent);                  \
+    if (event->GetState() == nsIAccessibleStates::STATE_BUSY) {                \
       strEventType.AssignLiteral("busy ");                                     \
-      if (isEnabled)                                                           \
+      if (event->IsStateEnabled())                                             \
         strEventType.AppendLiteral("true");                                    \
       else                                                                     \
         strEventType.AppendLiteral("false");                                   \
     }                                                                          \
   }
 
+#define NS_LOG_ACCDOC_ACCADDRESS(aName, aAcc)                                  \
+  {                                                                            \
+    nsINode* node = aAcc->GetNode();                                           \
+    nsIDocument* doc = aAcc->GetDocumentNode();                                \
+    nsDocAccessible *docacc = GetAccService()->GetDocAccessibleFromCache(doc); \
+    printf("  " aName " accessible: %p, node: %p\n", aAcc, node);              \
+    printf("  docacc for " aName " accessible: %p, node: %p\n", docacc, doc);  \
+    printf("  ");                                                              \
+    NS_LOG_ACCDOC_URI(doc)                                                     \
+    printf("\n");                                                              \
+  }
+
+#define NS_LOG_ACCDOC_MSG(aMsg)                                                \
+  printf("\n" aMsg "\n");                                                      \
+
 #define NS_LOG_ACCDOC_TEXT(aMsg)                                               \
   printf("  " aMsg "\n");
 
 // Accessible document loading macros.
 #ifdef DEBUG_ACCDOCMGR_DOCLOAD
 
 #define NS_LOG_ACCDOCLOAD_REQUEST(aRequest)                                    \
   if (aRequest) {                                                              \
@@ -425,27 +440,27 @@ private:
     if (loadFlags & nsIChannel::LOAD_CLASSIFY_URI)                             \
       printf("classify uri; ");                                                \
   } else {                                                                     \
     printf("    no request");                                                  \
   }
 
 #define NS_LOG_ACCDOCLOAD(aMsg, aWebProgress, aRequest, aStateFlags)           \
   {                                                                            \
-    printf("\nA11Y DOCLOAD: " aMsg "\n");                                      \
+    NS_LOG_ACCDOC_MSG("A11Y DOCLOAD: " aMsg);                                  \
                                                                                \
     nsCOMPtr<nsIDOMWindow> DOMWindow;                                          \
     aWebProgress->GetDOMWindow(getter_AddRefs(DOMWindow));                     \
     if (DOMWindow) {                                                           \
       nsCOMPtr<nsIDOMDocument> DOMDocument;                                    \
       DOMWindow->GetDocument(getter_AddRefs(DOMDocument));                     \
       if (DOMDocument) {                                                       \
         nsCOMPtr<nsIDocument> document(do_QueryInterface(DOMDocument));        \
         nsDocAccessible *docAcc =                                              \
-          mDocAccessibleCache.GetWeak(static_cast<void*>(document));           \
+          GetAccService()->GetDocAccessibleFromCache(document);                \
         NS_LOG_ACCDOC_DOCINFO(document, docAcc)                                \
                                                                                \
         printf("  {\n");                                                       \
         nsCOMPtr<nsIWebNavigation> webNav(do_GetInterface(DOMWindow));         \
         nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(webNav));             \
         printf("    ");                                                        \
         NS_LOG_ACCDOC_SHELLLOADTYPE(docShell)                                  \
         printf("\n");                                                          \
@@ -457,19 +472,19 @@ private:
         printf(", document is %sloading\n", (isDocLoading ? "" : "not "));     \
         printf("  }\n");                                                       \
       }                                                                        \
     }                                                                          \
   }
 
 #define NS_LOG_ACCDOCLOAD2(aMsg, aDocument)                                    \
   {                                                                            \
-    printf("\nA11Y DOCLOAD: " aMsg "\n");                                      \
+    NS_LOG_ACCDOC_MSG("A11Y DOCLOAD: " aMsg);                                  \
     nsDocAccessible *docAcc =                                                  \
-      mDocAccessibleCache.GetWeak(static_cast<void*>(aDocument));              \
+      GetAccService()->GetDocAccessibleFromCache(aDocument);                   \
     NS_LOG_ACCDOC_DOCINFO(aDocument, docAcc)                                   \
   }
 
 #define NS_LOG_ACCDOCLOAD_FIREEVENT(aEvent)                                    \
   {                                                                            \
     NS_GET_ACCDOC_EVENTTYPE(aEvent)                                            \
     if (!strEventType.IsEmpty())                                               \
       printf("  fire: %s\n", strEventType.get());                              \
@@ -490,44 +505,55 @@ private:
 #define NS_LOG_ACCDOCLOAD_TEXT(aMsg)                                           \
     NS_LOG_ACCDOC_TEXT(aMsg)
 
 #endif // DEBUG_ACCDOCMGR_DOCLOAD
 
 // Accessible document creation macros.
 #ifdef DEBUG_ACCDOCMGR_DOCCREATE
 #define NS_LOG_ACCDOCCREATE_FOR(aMsg, aDocument, aDocAcc)                      \
-  printf("\nA11Y DOCCREATE: " aMsg "\n");                                      \
+  NS_LOG_ACCDOC_MSG("A11Y DOCCREATE: " aMsg);                                  \
   NS_LOG_ACCDOC_DOCINFO(aDocument, aDocAcc)
 
 #define NS_LOG_ACCDOCCREATE(aMsg, aDocument)                                   \
   {                                                                            \
     nsDocAccessible *docAcc =                                                  \
-      mDocAccessibleCache.GetWeak(static_cast<void*>(aDocument));              \
+      GetAccService()->GetDocAccessibleFromCache(aDocument);                   \
     NS_LOG_ACCDOCCREATE_FOR(aMsg, aDocument, docAcc)                           \
   }
 
+#define NS_LOG_ACCDOCCREATE_ACCADDRESS(aName, aAcc)                            \
+  NS_LOG_ACCDOC_ACCADDRESS(aName, aAcc)
+
 #define NS_LOG_ACCDOCCREATE_TEXT(aMsg)                                         \
     NS_LOG_ACCDOC_TEXT(aMsg)
 
 #endif // DEBUG_ACCDOCMGR_DOCCREATE
 
 // Accessible document destruction macros.
 #ifdef DEBUG_ACCDOCMGR_DOCDESTROY
 #define NS_LOG_ACCDOCDESTROY_FOR(aMsg, aDocument, aDocAcc)                     \
-  printf("\nA11Y DOCDESTROY: " aMsg "\n");                                     \
+  NS_LOG_ACCDOC_MSG("A11Y DOCDESTROY: " aMsg);                                 \
   NS_LOG_ACCDOC_DOCINFO(aDocument, aDocAcc)
 
 #define NS_LOG_ACCDOCDESTROY(aMsg, aDocument)                                  \
-  nsDocAccessible *docAcc =                                                    \
-    mDocAccessibleCache.GetWeak(static_cast<void*>(aDocument));                \
-  NS_LOG_ACCDOCDESTROY_FOR(aMsg, aDocument, docAcc)
+  {                                                                            \
+    nsDocAccessible* docAcc =                                                  \
+      GetAccService()->GetDocAccessibleFromCache(aDocument);                   \
+    NS_LOG_ACCDOCDESTROY_FOR(aMsg, aDocument, docAcc)                          \
+  }
 
-#define NS_LOG_ACCDOCDESTROY_TEXT(aMsg)                                       \
-    NS_LOG_ACCDOC_TEXT(aMsg)
+#define NS_LOG_ACCDOCDESTROY_ACCADDRESS(aName, aAcc)                           \
+  NS_LOG_ACCDOC_ACCADDRESS(aName, aAcc)
+
+#define NS_LOG_ACCDOCDESTROY_MSG(aMsg)                                         \
+  NS_LOG_ACCDOC_MSG(aMsg)
+
+#define NS_LOG_ACCDOCDESTROY_TEXT(aMsg)                                        \
+  NS_LOG_ACCDOC_TEXT(aMsg)
 
 #endif // DEBUG_ACCDOCMGR_DOCDESTROY
 
 #endif // DEBUG_ACCDOCMGR
 
 #ifndef DEBUG_ACCDOCMGR_DOCLOAD
 #define NS_LOG_ACCDOCLOAD(aMsg, aWebProgress, aRequest, aStateFlags)
 #define NS_LOG_ACCDOCLOAD2(aMsg, aDocument)
@@ -535,18 +561,21 @@ private:
 #define NS_LOG_ACCDOCLOAD_FIREEVENT(aEvent)
 #define NS_LOG_ACCDOCLOAD_HANDLEEVENT(aEvent)
 #define NS_LOG_ACCDOCLOAD_TEXT(aMsg)
 #endif
 
 #ifndef DEBUG_ACCDOCMGR_DOCCREATE
 #define NS_LOG_ACCDOCCREATE_FOR(aMsg, aDocument, aDocAcc)
 #define NS_LOG_ACCDOCCREATE(aMsg, aDocument)
+#define NS_LOG_ACCDOCCREATE_ACCADDRESS(aName, aAcc)
 #define NS_LOG_ACCDOCCREATE_TEXT(aMsg)
 #endif
 
 #ifndef DEBUG_ACCDOCMGR_DOCDESTROY
 #define NS_LOG_ACCDOCDESTROY_FOR(aMsg, aDocument, aDocAcc)
 #define NS_LOG_ACCDOCDESTROY(aMsg, aDocument)
+#define NS_LOG_ACCDOCDESTROY_MSG(aMsg)
+#define NS_LOG_ACCDOCDESTROY_ACCADDRESS(aName, aAcc)
 #define NS_LOG_ACCDOCDESTROY_TEXT(aMsg)
 #endif
 
 #endif // nsAccDocManager_h_
--- a/accessible/src/base/nsAccEvent.cpp
+++ b/accessible/src/base/nsAccEvent.cpp
@@ -44,60 +44,62 @@
 #include "nsDocAccessible.h"
 #include "nsIAccessibleText.h"
 #ifdef MOZ_XUL
 #include "nsXULTreeAccessible.h"
 #endif
 
 #include "nsIDOMDocument.h"
 #include "nsIEventStateManager.h"
-#include "nsIPersistentProperties2.h"
 #include "nsIServiceManager.h"
 #ifdef MOZ_XUL
 #include "nsIDOMXULMultSelectCntrlEl.h"
 #endif
-#include "nsIContent.h"
-#include "nsIPresShell.h"
-#include "nsPresContext.h"
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccEvent
 ////////////////////////////////////////////////////////////////////////////////
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccEvent. nsISupports
 
-NS_IMPL_CYCLE_COLLECTION_1(nsAccEvent, mAccessible)
+NS_IMPL_CYCLE_COLLECTION_CLASS(nsAccEvent)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsAccEvent)
+  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mAccessible)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsAccEvent)
+  NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mAccessible");
+  cb.NoteXPCOMChild(static_cast<nsIAccessible*>(tmp->mAccessible));
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsAccEvent)
   NS_INTERFACE_MAP_ENTRY(nsIAccessibleEvent)
-  NS_INTERFACE_MAP_ENTRY(nsAccEvent)
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsAccEvent)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsAccEvent)
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccEvent. Constructors
 
-nsAccEvent::nsAccEvent(PRUint32 aEventType, nsIAccessible *aAccessible,
+nsAccEvent::nsAccEvent(PRUint32 aEventType, nsAccessible *aAccessible,
                        PRBool aIsAsync, EIsFromUserInput aIsFromUserInput,
                        EEventRule aEventRule) :
   mEventType(aEventType), mEventRule(aEventRule), mIsAsync(aIsAsync),
   mAccessible(aAccessible)
 {
   CaptureIsFromUserInput(aIsFromUserInput);
 }
 
-nsAccEvent::nsAccEvent(PRUint32 aEventType, nsIDOMNode *aDOMNode,
+nsAccEvent::nsAccEvent(PRUint32 aEventType, nsINode *aNode,
                        PRBool aIsAsync, EIsFromUserInput aIsFromUserInput,
                        EEventRule aEventRule) :
   mEventType(aEventType), mEventRule(aEventRule), mIsAsync(aIsAsync),
-  mNode(do_QueryInterface(aDOMNode))
+  mNode(aNode)
 {
   CaptureIsFromUserInput(aIsFromUserInput);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccEvent: nsIAccessibleEvent
 
 NS_IMETHODIMP
@@ -122,20 +124,17 @@ nsAccEvent::GetEventType(PRUint32 *aEven
 }
 
 NS_IMETHODIMP
 nsAccEvent::GetAccessible(nsIAccessible **aAccessible)
 {
   NS_ENSURE_ARG_POINTER(aAccessible);
   *aAccessible = nsnull;
 
-  if (!mAccessible)
-    mAccessible = GetAccessibleByNode();
-
-  NS_IF_ADDREF(*aAccessible = mAccessible);
+  NS_IF_ADDREF(*aAccessible = GetAccessible());
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsAccEvent::GetDOMNode(nsIDOMNode **aDOMNode)
 {
   NS_ENSURE_ARG_POINTER(aDOMNode);
   *aDOMNode = nsnull;
@@ -156,29 +155,30 @@ nsAccEvent::GetAccessibleDocument(nsIAcc
 
   NS_IF_ADDREF(*aDocAccessible = GetDocAccessible());
   return NS_OK;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccEvent: public methods
 
+nsAccessible *
+nsAccEvent::GetAccessible()
+{
+  if (!mAccessible)
+    mAccessible = GetAccessibleForNode();
+
+  return mAccessible;
+}
+
 nsINode*
 nsAccEvent::GetNode()
 {
-  if (!mNode) {
-    nsCOMPtr<nsIAccessNode> accessNode(do_QueryInterface(mAccessible));
-    if (!accessNode)
-      return nsnull;
-
-    nsCOMPtr<nsIDOMNode> DOMNode;
-    accessNode->GetDOMNode(getter_AddRefs(DOMNode));
-
-    mNode = do_QueryInterface(DOMNode);
-  }
+  if (!mNode && mAccessible)
+    mNode = mAccessible->GetNode();
 
   return mNode;
 }
 
 nsDocAccessible*
 nsAccEvent::GetDocAccessible()
 {
   nsINode *node = GetNode();
@@ -186,26 +186,23 @@ nsAccEvent::GetDocAccessible()
     return GetAccService()->GetDocAccessible(node->GetOwnerDoc());
 
   return nsnull;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccEvent: protected methods
 
-already_AddRefed<nsIAccessible>
-nsAccEvent::GetAccessibleByNode()
+nsAccessible *
+nsAccEvent::GetAccessibleForNode() const
 {
   if (!mNode)
     return nsnull;
 
-  nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mNode));
-
-  nsCOMPtr<nsIAccessible> accessible;
-  GetAccService()->GetAccessibleFor(DOMNode, getter_AddRefs(accessible));
+  nsAccessible *accessible = GetAccService()->GetAccessible(mNode);
 
 #ifdef MOZ_XUL
   // hack for xul tree table. We need a better way for firing delayed event
   // against xul tree table. see bug 386821.
   // There will be problem if some day we want to fire delayed event against
   // the xul tree itself or an unselected treeitem.
   nsCOMPtr<nsIContent> content(do_QueryInterface(mNode));
   if (content && content->NodeInfo()->Equals(nsAccessibilityAtoms::tree,
@@ -215,30 +212,29 @@ nsAccEvent::GetAccessibleByNode()
       do_QueryInterface(mNode);
 
     if (multiSelect) {
       PRInt32 treeIndex = -1;
       multiSelect->GetCurrentIndex(&treeIndex);
       if (treeIndex >= 0) {
         nsRefPtr<nsXULTreeAccessible> treeAcc = do_QueryObject(accessible);
         if (treeAcc)
-          accessible = treeAcc->GetTreeItemAccessible(treeIndex);
+          return treeAcc->GetTreeItemAccessible(treeIndex);
       }
     }
   }
 #endif
 
-  return accessible.forget();
+  return accessible;
 }
 
 void
 nsAccEvent::CaptureIsFromUserInput(EIsFromUserInput aIsFromUserInput)
 {
-  nsCOMPtr<nsIDOMNode> targetNode;
-  GetDOMNode(getter_AddRefs(targetNode));
+  nsINode *targetNode = GetNode();
 
 #ifdef DEBUG
   if (!targetNode) {
     // XXX: remove this hack during reorganization of 506907. Meanwhile we
     // want to get rid an assertion for application accessible events which
     // don't have DOM node (see bug 506206).
     nsApplicationAccessible *applicationAcc =
       nsAccessNode::GetApplicationAccessible();
@@ -271,23 +267,22 @@ nsAccEvent::CaptureIsFromUserInput(EIsFr
   mIsFromUserInput = esm->IsHandlingUserInputExternal();
 }
 
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccReorderEvent
 ////////////////////////////////////////////////////////////////////////////////
 
-NS_IMPL_ISUPPORTS_INHERITED1(nsAccReorderEvent, nsAccEvent,
-                             nsAccReorderEvent)
+NS_IMPL_ISUPPORTS_INHERITED0(nsAccReorderEvent, nsAccEvent)
 
-nsAccReorderEvent::nsAccReorderEvent(nsIAccessible *aAccTarget,
+nsAccReorderEvent::nsAccReorderEvent(nsAccessible *aAccTarget,
                                      PRBool aIsAsynch,
                                      PRBool aIsUnconditional,
-                                     nsIDOMNode *aReasonNode) :
+                                     nsINode *aReasonNode) :
   nsAccEvent(::nsIAccessibleEvent::EVENT_REORDER, aAccTarget,
              aIsAsynch, eAutoDetect, nsAccEvent::eCoalesceFromSameSubtree),
   mUnconditionalEvent(aIsUnconditional), mReasonNode(aReasonNode)
 {
 }
 
 PRBool
 nsAccReorderEvent::IsUnconditionalEvent()
@@ -296,88 +291,87 @@ nsAccReorderEvent::IsUnconditionalEvent(
 }
 
 PRBool
 nsAccReorderEvent::HasAccessibleInReasonSubtree()
 {
   if (!mReasonNode)
     return PR_FALSE;
 
-  nsCOMPtr<nsIAccessible> accessible;
-  GetAccService()->GetAccessibleFor(mReasonNode, getter_AddRefs(accessible));
-
+  nsAccessible *accessible = GetAccService()->GetAccessible(mReasonNode);
   return accessible || nsAccUtils::HasAccessibleChildren(mReasonNode);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccStateChangeEvent
 ////////////////////////////////////////////////////////////////////////////////
 
 NS_IMPL_ISUPPORTS_INHERITED1(nsAccStateChangeEvent, nsAccEvent,
                              nsIAccessibleStateChangeEvent)
 
 // Note: we pass in eAllowDupes to the base class because we don't currently
 // support correct state change coalescence (XXX Bug 569356). Also we need to
 // decide how to coalesce events created via accessible (instead of node).
 nsAccStateChangeEvent::
-  nsAccStateChangeEvent(nsIAccessible *aAccessible,
+  nsAccStateChangeEvent(nsAccessible *aAccessible,
                         PRUint32 aState, PRBool aIsExtraState,
                         PRBool aIsEnabled, PRBool aIsAsynch,
                         EIsFromUserInput aIsFromUserInput):
   nsAccEvent(nsIAccessibleEvent::EVENT_STATE_CHANGE, aAccessible, aIsAsynch,
              aIsFromUserInput, eAllowDupes),
   mState(aState), mIsExtraState(aIsExtraState), mIsEnabled(aIsEnabled)
 {
 }
 
 nsAccStateChangeEvent::
-  nsAccStateChangeEvent(nsIDOMNode *aNode,
-                        PRUint32 aState, PRBool aIsExtraState,
+  nsAccStateChangeEvent(nsINode *aNode, PRUint32 aState, PRBool aIsExtraState,
                         PRBool aIsEnabled):
   nsAccEvent(::nsIAccessibleEvent::EVENT_STATE_CHANGE, aNode),
   mState(aState), mIsExtraState(aIsExtraState), mIsEnabled(aIsEnabled)
 {
 }
 
 nsAccStateChangeEvent::
-  nsAccStateChangeEvent(nsIDOMNode *aNode,
-                        PRUint32 aState, PRBool aIsExtraState):
+  nsAccStateChangeEvent(nsINode *aNode, PRUint32 aState, PRBool aIsExtraState) :
   nsAccEvent(::nsIAccessibleEvent::EVENT_STATE_CHANGE, aNode),
   mState(aState), mIsExtraState(aIsExtraState)
 {
-  // Use GetAccessibleByNode() because we do not want to store an accessible
+  // Use GetAccessibleForNode() because we do not want to store an accessible
   // since it leads to problems with delayed events in the case when
   // an accessible gets reorder event before delayed event is processed.
-  nsCOMPtr<nsIAccessible> accessible(GetAccessibleByNode());
+  nsAccessible *accessible = GetAccessibleForNode();
   if (accessible) {
     PRUint32 state = 0, extraState = 0;
     accessible->GetState(&state, mIsExtraState ? &extraState : nsnull);
     mIsEnabled = ((mIsExtraState ? extraState : state) & mState) != 0;
   } else {
     mIsEnabled = PR_FALSE;
   }
 }
 
 NS_IMETHODIMP
 nsAccStateChangeEvent::GetState(PRUint32 *aState)
 {
+  NS_ENSURE_ARG_POINTER(aState);
   *aState = mState;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsAccStateChangeEvent::IsExtraState(PRBool *aIsExtraState)
 {
+  NS_ENSURE_ARG_POINTER(aIsExtraState);
   *aIsExtraState = mIsExtraState;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsAccStateChangeEvent::IsEnabled(PRBool *aIsEnabled)
 {
+  NS_ENSURE_ARG_POINTER(aIsEnabled);
   *aIsEnabled = mIsEnabled;
   return NS_OK;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccTextChangeEvent
 ////////////////////////////////////////////////////////////////////////////////
 
@@ -388,44 +382,47 @@ NS_IMPL_ISUPPORTS_INHERITED1(nsAccTextCh
 // events coalescence. We fire delayed text change events in nsDocAccessible but
 // we continue to base the event off the accessible object rather than just the
 // node. This means we won't try to create an accessible based on the node when
 // we are ready to fire the event and so we will no longer assert at that point
 // if the node was removed from the document. Either way, the AT won't work with
 // a defunct accessible so the behaviour should be equivalent.
 // XXX revisit this when coalescence is faster (eCoalesceFromSameSubtree)
 nsAccTextChangeEvent::
-  nsAccTextChangeEvent(nsIAccessible *aAccessible,
+  nsAccTextChangeEvent(nsAccessible *aAccessible,
                        PRInt32 aStart, PRUint32 aLength,
                        nsAString& aModifiedText, PRBool aIsInserted,
                        PRBool aIsAsynch, EIsFromUserInput aIsFromUserInput) :
   nsAccEvent(aIsInserted ? nsIAccessibleEvent::EVENT_TEXT_INSERTED : nsIAccessibleEvent::EVENT_TEXT_REMOVED,
              aAccessible, aIsAsynch, aIsFromUserInput, eAllowDupes),
   mStart(aStart), mLength(aLength), mIsInserted(aIsInserted),
   mModifiedText(aModifiedText)
 {
 }
 
 NS_IMETHODIMP
 nsAccTextChangeEvent::GetStart(PRInt32 *aStart)
 {
+  NS_ENSURE_ARG_POINTER(aStart);
   *aStart = mStart;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsAccTextChangeEvent::GetLength(PRUint32 *aLength)
 {
+  NS_ENSURE_ARG_POINTER(aLength);
   *aLength = mLength;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsAccTextChangeEvent::IsInserted(PRBool *aIsInserted)
 {
+  NS_ENSURE_ARG_POINTER(aIsInserted);
   *aIsInserted = mIsInserted;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsAccTextChangeEvent::GetModifiedText(nsAString& aModifiedText)
 {
   aModifiedText = mModifiedText;
@@ -435,24 +432,24 @@ nsAccTextChangeEvent::GetModifiedText(ns
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccCaretMoveEvent
 ////////////////////////////////////////////////////////////////////////////////
 
 NS_IMPL_ISUPPORTS_INHERITED1(nsAccCaretMoveEvent, nsAccEvent,
                              nsIAccessibleCaretMoveEvent)
 
 nsAccCaretMoveEvent::
-  nsAccCaretMoveEvent(nsIAccessible *aAccessible, PRInt32 aCaretOffset) :
+  nsAccCaretMoveEvent(nsAccessible *aAccessible, PRInt32 aCaretOffset) :
   nsAccEvent(::nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED, aAccessible, PR_TRUE), // Currently always asynch
   mCaretOffset(aCaretOffset)
 {
 }
 
 nsAccCaretMoveEvent::
-  nsAccCaretMoveEvent(nsIDOMNode *aNode) :
+  nsAccCaretMoveEvent(nsINode *aNode) :
   nsAccEvent(::nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED, aNode, PR_TRUE), // Currently always asynch
   mCaretOffset(-1)
 {
 }
 
 NS_IMETHODIMP
 nsAccCaretMoveEvent::GetCaretOffset(PRInt32* aCaretOffset)
 {
@@ -465,17 +462,17 @@ nsAccCaretMoveEvent::GetCaretOffset(PRIn
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccTableChangeEvent
 ////////////////////////////////////////////////////////////////////////////////
 
 NS_IMPL_ISUPPORTS_INHERITED1(nsAccTableChangeEvent, nsAccEvent,
                              nsIAccessibleTableChangeEvent)
 
 nsAccTableChangeEvent::
-  nsAccTableChangeEvent(nsIAccessible *aAccessible, PRUint32 aEventType,
+  nsAccTableChangeEvent(nsAccessible *aAccessible, PRUint32 aEventType,
                         PRInt32 aRowOrColIndex, PRInt32 aNumRowsOrCols, PRBool aIsAsynch):
   nsAccEvent(aEventType, aAccessible, aIsAsynch), 
   mRowOrColIndex(aRowOrColIndex), mNumRowsOrCols(aNumRowsOrCols)
 {
 }
 
 NS_IMETHODIMP
 nsAccTableChangeEvent::GetRowOrColIndex(PRInt32* aRowOrColIndex)
--- a/accessible/src/base/nsAccEvent.h
+++ b/accessible/src/base/nsAccEvent.h
@@ -38,45 +38,34 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef _nsAccEvent_H_
 #define _nsAccEvent_H_
 
 #include "nsIAccessibleEvent.h"
 
-#include "nsCOMPtr.h"
-#include "nsCOMArray.h"
-#include "nsString.h"
-#include "nsCycleCollectionParticipant.h"
-
-#include "nsINode.h"
-#include "nsIDOMNode.h"
+#include "nsAccessible.h"
 
 class nsDocAccessible;
 
 // Constants used to point whether the event is from user input.
 enum EIsFromUserInput
 {
   // eNoUserInput: event is not from user input
   eNoUserInput = 0,
   // eFromUserInput: event is from user input
   eFromUserInput = 1,
   // eAutoDetect: the value should be obtained from event state manager
   eAutoDetect = -1
 };
 
-#define NS_ACCEVENT_IMPL_CID                            \
-{  /* 39bde096-317e-4294-b23b-4af4a9b283f7 */           \
-  0x39bde096,                                           \
-  0x317e,                                               \
-  0x4294,                                               \
-  { 0xb2, 0x3b, 0x4a, 0xf4, 0xa9, 0xb2, 0x83, 0xf7 }    \
-}
-
+/**
+ * Generic accessible event.
+ */
 class nsAccEvent: public nsIAccessibleEvent
 {
 public:
 
   // Rule for accessible events.
   // The rule will be applied when flushing pending events.
   enum EEventRule {
      // eAllowDupes : More than one event of the same type is allowed.
@@ -95,175 +84,264 @@ public:
      // eRemoveDupes : For repeat events, only the newest event in queue
      //    will be emitted.
      eRemoveDupes,
 
      // eDoNotEmit : This event is confirmed as a duplicate, do not emit it.
      eDoNotEmit
   };
 
-  NS_DECLARE_STATIC_IID_ACCESSOR(NS_ACCEVENT_IMPL_CID)
-
   // Initialize with an nsIAccessible
-  nsAccEvent(PRUint32 aEventType, nsIAccessible *aAccessible,
+  nsAccEvent(PRUint32 aEventType, nsAccessible *aAccessible,
              PRBool aIsAsynch = PR_FALSE,
              EIsFromUserInput aIsFromUserInput = eAutoDetect,
              EEventRule aEventRule = eRemoveDupes);
   // Initialize with an nsIDOMNode
-  nsAccEvent(PRUint32 aEventType, nsIDOMNode *aDOMNode,
-             PRBool aIsAsynch = PR_FALSE,
+  nsAccEvent(PRUint32 aEventType, nsINode *aNode, PRBool aIsAsynch = PR_FALSE,
              EIsFromUserInput aIsFromUserInput = eAutoDetect,
              EEventRule aEventRule = eRemoveDupes);
   virtual ~nsAccEvent() {}
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_CLASS(nsAccEvent)
 
   NS_DECL_NSIACCESSIBLEEVENT
 
   // nsAccEvent
   PRUint32 GetEventType() const { return mEventType; }
   EEventRule GetEventRule() const { return mEventRule; }
   PRBool IsAsync() const { return mIsAsync; }
   PRBool IsFromUserInput() const { return mIsFromUserInput; }
-  nsIAccessible* GetAccessible() const { return mAccessible; }
 
+  nsAccessible *GetAccessible();
   nsINode* GetNode();
   nsDocAccessible* GetDocAccessible();
 
+  enum EventGroup {
+    eGenericEvent,
+    eReorderEvent,
+    eStateChangeEvent,
+    eTextChangeEvent,
+    eCaretMoveEvent,
+    eTableChangeEvent
+  };
+
+  static const EventGroup kEventGroup = eGenericEvent;
+  virtual unsigned int GetEventGroups() const
+  {
+    return 1U << eGenericEvent;
+  }
+
 protected:
   /**
    * Get an accessible from event target node.
    */
-  already_AddRefed<nsIAccessible> GetAccessibleByNode();
+  nsAccessible *GetAccessibleForNode() const;
 
   /**
    * Determine whether the event is from user input by event state manager if
    * it's not pointed explicetly.
    */
   void CaptureIsFromUserInput(EIsFromUserInput aIsFromUserInput);
 
   PRBool mIsFromUserInput;
 
   PRUint32 mEventType;
   EEventRule mEventRule;
   PRPackedBool mIsAsync;
-  nsCOMPtr<nsIAccessible> mAccessible;
+  nsRefPtr<nsAccessible> mAccessible;
   nsCOMPtr<nsINode> mNode;
 
   friend class nsAccEventQueue;
 };
 
-NS_DEFINE_STATIC_IID_ACCESSOR(nsAccEvent, NS_ACCEVENT_IMPL_CID)
 
-
-#define NS_ACCREORDEREVENT_IMPL_CID                     \
-{  /* f2629eb8-2458-4358-868c-3912b15b767a */           \
-  0xf2629eb8,                                           \
-  0x2458,                                               \
-  0x4358,                                               \
-  { 0x86, 0x8c, 0x39, 0x12, 0xb1, 0x5b, 0x76, 0x7a }    \
-}
-
+/**
+ * Accessible reorder event.
+ */
 class nsAccReorderEvent : public nsAccEvent
 {
 public:
-
-  nsAccReorderEvent(nsIAccessible *aAccTarget, PRBool aIsAsynch,
-                    PRBool aIsUnconditional, nsIDOMNode *aReasonNode);
-
-  NS_DECLARE_STATIC_IID_ACCESSOR(NS_ACCREORDEREVENT_IMPL_CID)
+  nsAccReorderEvent(nsAccessible *aAccTarget, PRBool aIsAsynch,
+                    PRBool aIsUnconditional, nsINode *aReasonNode);
 
   NS_DECL_ISUPPORTS_INHERITED
 
+  // nsAccEvent
+  static const EventGroup kEventGroup = eReorderEvent;
+  virtual unsigned int GetEventGroups() const
+  {
+    return nsAccEvent::GetEventGroups() | (1U << eReorderEvent);
+  }
+
+  // nsAccReorderEvent
   /**
    * Return true if event is unconditional, i.e. must be fired.
    */
   PRBool IsUnconditionalEvent();
 
   /**
    * Return true if changed DOM node has accessible in its tree.
    */
   PRBool HasAccessibleInReasonSubtree();
 
 private:
   PRBool mUnconditionalEvent;
-  nsCOMPtr<nsIDOMNode> mReasonNode;
+  nsCOMPtr<nsINode> mReasonNode;
 };
 
-NS_DEFINE_STATIC_IID_ACCESSOR(nsAccReorderEvent, NS_ACCREORDEREVENT_IMPL_CID)
 
-
+/**
+ * Accessible state change event.
+ */
 class nsAccStateChangeEvent: public nsAccEvent,
                              public nsIAccessibleStateChangeEvent
 {
 public:
-  nsAccStateChangeEvent(nsIAccessible *aAccessible,
+  nsAccStateChangeEvent(nsAccessible *aAccessible,
                         PRUint32 aState, PRBool aIsExtraState,
                         PRBool aIsEnabled, PRBool aIsAsynch = PR_FALSE,
                         EIsFromUserInput aIsFromUserInput = eAutoDetect);
 
-  nsAccStateChangeEvent(nsIDOMNode *aNode,
-                        PRUint32 aState, PRBool aIsExtraState,
+  nsAccStateChangeEvent(nsINode *aNode, PRUint32 aState, PRBool aIsExtraState,
                         PRBool aIsEnabled);
 
-  nsAccStateChangeEvent(nsIDOMNode *aNode,
-                        PRUint32 aState, PRBool aIsExtraState);
+  nsAccStateChangeEvent(nsINode *aNode, PRUint32 aState, PRBool aIsExtraState);
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIACCESSIBLESTATECHANGEEVENT
 
+  // nsAccEvent
+  static const EventGroup kEventGroup = eStateChangeEvent;
+  virtual unsigned int GetEventGroups() const
+  {
+    return nsAccEvent::GetEventGroups() | (1U << eStateChangeEvent);
+  }
+
+  // nsAccStateChangeEvent
+  PRUint32 GetState() const { return mState; }
+  PRBool IsExtraState() const { return mIsExtraState; }
+  PRBool IsStateEnabled() const { return mIsEnabled; }
+
 private:
   PRUint32 mState;
   PRBool mIsExtraState;
   PRBool mIsEnabled;
 };
 
+
+/**
+ * Accessible text change event.
+ */
 class nsAccTextChangeEvent: public nsAccEvent,
                             public nsIAccessibleTextChangeEvent
 {
 public:
-  nsAccTextChangeEvent(nsIAccessible *aAccessible, PRInt32 aStart,
+  nsAccTextChangeEvent(nsAccessible *aAccessible, PRInt32 aStart,
                        PRUint32 aLength, nsAString& aModifiedText,
                        PRBool aIsInserted, PRBool aIsAsynch = PR_FALSE,
                        EIsFromUserInput aIsFromUserInput = eAutoDetect);
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIACCESSIBLETEXTCHANGEEVENT
 
+  // nsAccEvent
+  static const EventGroup kEventGroup = eTextChangeEvent;
+  virtual unsigned int GetEventGroups() const
+  {
+    return nsAccEvent::GetEventGroups() | (1U << eTextChangeEvent);
+  }
+
+  // nsAccTextChangeEvent
+  PRInt32 GetStartOffset() const { return mStart; }
+  PRUint32 GetLength() const { return mLength; }
+  PRBool IsTextInserted() const { return mIsInserted; }
+
 private:
   PRInt32 mStart;
   PRUint32 mLength;
   PRBool mIsInserted;
   nsString mModifiedText;
 };
 
+
+/**
+ * Accessible caret move event.
+ */
 class nsAccCaretMoveEvent: public nsAccEvent,
                            public nsIAccessibleCaretMoveEvent
 {
 public:
-  nsAccCaretMoveEvent(nsIAccessible *aAccessible, PRInt32 aCaretOffset);
-  nsAccCaretMoveEvent(nsIDOMNode *aNode);
+  nsAccCaretMoveEvent(nsAccessible *aAccessible, PRInt32 aCaretOffset);
+  nsAccCaretMoveEvent(nsINode *aNode);
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIACCESSIBLECARETMOVEEVENT
 
+  // nsAccEvent
+  static const EventGroup kEventGroup = eCaretMoveEvent;
+  virtual unsigned int GetEventGroups() const
+  {
+    return nsAccEvent::GetEventGroups() | (1U << eCaretMoveEvent);
+  }
+
+  // nsAccCaretMoveEvent
+  PRInt32 GetCaretOffset() const { return mCaretOffset; }
+
 private:
   PRInt32 mCaretOffset;
 };
 
+
+/**
+ * Accessible table change event.
+ */
 class nsAccTableChangeEvent : public nsAccEvent,
-                              public nsIAccessibleTableChangeEvent {
+                              public nsIAccessibleTableChangeEvent
+{
 public:
-  nsAccTableChangeEvent(nsIAccessible *aAccessible, PRUint32 aEventType,
+  nsAccTableChangeEvent(nsAccessible *aAccessible, PRUint32 aEventType,
                         PRInt32 aRowOrColIndex, PRInt32 aNumRowsOrCols,
                         PRBool aIsAsynch);
 
-  NS_DECL_ISUPPORTS
+  NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIACCESSIBLETABLECHANGEEVENT
 
+  // nsAccEvent
+  static const EventGroup kEventGroup = eTableChangeEvent;
+  virtual unsigned int GetEventGroups() const
+  {
+    return nsAccEvent::GetEventGroups() | (1U << eTableChangeEvent);
+  }
+
+  // nsAccTableChangeEvent
+  PRUint32 GetIndex() const { return mRowOrColIndex; }
+  PRUint32 GetCount() const { return mNumRowsOrCols; }
+
 private:
   PRUint32 mRowOrColIndex;   // the start row/column after which the rows are inserted/deleted.
   PRUint32 mNumRowsOrCols;   // the number of inserted/deleted rows/columns
 };
 
+
+/**
+ * Downcast the generic accessible event object to derived type.
+ */
+class downcast_accEvent
+{
+public:
+  downcast_accEvent(nsAccEvent *e) : mRawPtr(e) { }
+
+  template<class Destination>
+  operator Destination*() {
+    if (!mRawPtr)
+      return nsnull;
+
+    return mRawPtr->GetEventGroups() & (1U << Destination::kEventGroup) ?
+      static_cast<Destination*>(mRawPtr) : nsnull;
+  }
+
+private:
+  nsAccEvent *mRawPtr;
+};
+
 #endif
 
--- a/accessible/src/base/nsAccTreeWalker.cpp
+++ b/accessible/src/base/nsAccTreeWalker.cpp
@@ -107,19 +107,18 @@ nsAccTreeWalker::GetNextChildInternal(PR
   if (mState->childList)
     mState->childList->GetLength(&length);
 
   while (mState->childIdx < length) {
     nsIContent* childNode = mState->childList->GetNodeAt(mState->childIdx);
     mState->childIdx++;
 
     PRBool isHidden = PR_FALSE;
-    nsCOMPtr<nsIDOMNode> childDOMNode(do_QueryInterface(childNode));
     nsRefPtr<nsAccessible> accessible =
-      GetAccService()->GetAccessible(childDOMNode, presShell, mWeakShell,
+      GetAccService()->GetAccessible(childNode, presShell, mWeakShell,
                                      &isHidden);
 
     if (accessible)
       return accessible.forget();
 
     // Walk down into subtree to find accessibles.
     if (!isHidden) {
       if (!PushState(childNode))
--- a/accessible/src/base/nsAccUtils.cpp
+++ b/accessible/src/base/nsAccUtils.cpp
@@ -96,61 +96,54 @@ nsAccUtils::SetAccGroupAttrs(nsIPersiste
 
     value.Truncate();
     value.AppendInt(aSetSize);
     SetAccAttr(aAttributes, nsAccessibilityAtoms::setsize, value);
   }
 }
 
 PRInt32
-nsAccUtils::GetDefaultLevel(nsAccessible *aAcc)
+nsAccUtils::GetDefaultLevel(nsAccessible *aAccessible)
 {
-  PRUint32 role = nsAccUtils::Role(aAcc);
+  PRUint32 role = nsAccUtils::Role(aAccessible);
 
   if (role == nsIAccessibleRole::ROLE_OUTLINEITEM)
     return 1;
 
   if (role == nsIAccessibleRole::ROLE_ROW) {
-    nsCOMPtr<nsIAccessible> parent = aAcc->GetParent();
+    nsAccessible *parent = aAccessible->GetParent();
     if (Role(parent) == nsIAccessibleRole::ROLE_TREE_TABLE) {
       // It is a row inside flatten treegrid. Group level is always 1 until it
       // is overriden by aria-level attribute.
       return 1;
     }
   }
 
   return 0;
 }
 
 PRInt32
-nsAccUtils::GetARIAOrDefaultLevel(nsIAccessible *aAcc)
+nsAccUtils::GetARIAOrDefaultLevel(nsAccessible *aAccessible)
 {
-  nsRefPtr<nsAccessible> acc = do_QueryObject(aAcc);
-  NS_ENSURE_TRUE(acc, 0);
-
-  nsCOMPtr<nsIDOMNode> node;
-  acc->GetDOMNode(getter_AddRefs(node));
-  nsCOMPtr<nsIContent> content(do_QueryInterface(node));
-  NS_ENSURE_TRUE(content, 0);
-
   PRInt32 level = 0;
-  nsCoreUtils::GetUIntAttr(content, nsAccessibilityAtoms::aria_level, &level);
+  nsCoreUtils::GetUIntAttr(aAccessible->GetContent(),
+                           nsAccessibilityAtoms::aria_level, &level);
 
   if (level != 0)
     return level;
 
-  return GetDefaultLevel(acc);
+  return GetDefaultLevel(aAccessible);
 }
 
 void
-nsAccUtils::GetPositionAndSizeForXULSelectControlItem(nsIDOMNode *aNode,
+nsAccUtils::GetPositionAndSizeForXULSelectControlItem(nsIContent *aContent,
                                                       PRInt32 *aPosInSet,
                                                       PRInt32 *aSetSize)
 {
-  nsCOMPtr<nsIDOMXULSelectControlItemElement> item(do_QueryInterface(aNode));
+  nsCOMPtr<nsIDOMXULSelectControlItemElement> item(do_QueryInterface(aContent));
   if (!item)
     return;
 
   nsCOMPtr<nsIDOMXULSelectControlElement> control;
   item->GetControl(getter_AddRefs(control));
   if (!control)
     return;
 
@@ -177,21 +170,21 @@ nsAccUtils::GetPositionAndSizeForXULSele
         (*aPosInSet)--;
     }
   }
 
   (*aPosInSet)++; // group position is 1-index based.
 }
 
 void
-nsAccUtils::GetPositionAndSizeForXULContainerItem(nsIDOMNode *aNode,
+nsAccUtils::GetPositionAndSizeForXULContainerItem(nsIContent *aContent,
                                                   PRInt32 *aPosInSet,
                                                   PRInt32 *aSetSize)
 {
-  nsCOMPtr<nsIDOMXULContainerItemElement> item(do_QueryInterface(aNode));
+  nsCOMPtr<nsIDOMXULContainerItemElement> item(do_QueryInterface(aContent));
   if (!item)
     return;
 
   nsCOMPtr<nsIDOMXULContainerElement> container;
   item->GetParentContainer(getter_AddRefs(container));
   if (!container)
     return;
 
@@ -241,19 +234,19 @@ nsAccUtils::GetPositionAndSizeForXULCont
       PRUint32 itemState = State(itemAcc);
       if (!(itemState & nsIAccessibleStates::STATE_INVISIBLE))
         (*aSetSize)++;
     }
   }
 }
 
 PRInt32
-nsAccUtils::GetLevelForXULContainerItem(nsIDOMNode *aNode)
+nsAccUtils::GetLevelForXULContainerItem(nsIContent *aContent)
 {
-  nsCOMPtr<nsIDOMXULContainerItemElement> item(do_QueryInterface(aNode));
+  nsCOMPtr<nsIDOMXULContainerItemElement> item(do_QueryInterface(aContent));
   if (!item)
     return 0;
 
   nsCOMPtr<nsIDOMXULContainerElement> container;
   item->GetParentContainer(getter_AddRefs(container));
   if (!container)
     return 0;
 
@@ -282,18 +275,17 @@ nsAccUtils::SetLiveContainerAttributes(n
     // container-relevant attribute
     if (relevant.IsEmpty() &&
         nsAccUtils::HasDefinedARIAToken(ancestor, nsAccessibilityAtoms::aria_relevant) &&
         ancestor->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_relevant, relevant))
       SetAccAttr(aAttributes, nsAccessibilityAtoms::containerRelevant, relevant);
 
     // container-live, and container-live-role attributes
     if (live.IsEmpty()) {
-      nsCOMPtr<nsIDOMNode> node(do_QueryInterface(ancestor));
-      nsRoleMapEntry *role = GetRoleMapEntry(node);
+      nsRoleMapEntry *role = GetRoleMapEntry(ancestor);
       if (nsAccUtils::HasDefinedARIAToken(ancestor,
                                           nsAccessibilityAtoms::aria_live)) {
         ancestor->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_live,
                           live);
       } else if (role) {
         GetLiveAttrValue(role->liveAttRule, live);
       }
       if (!live.IsEmpty()) {
@@ -338,56 +330,44 @@ nsAccUtils::HasDefinedARIAToken(nsIConte
       aContent->AttrValueIs(kNameSpaceID_None, aAtom,
                             nsAccessibilityAtoms::_undefined, eCaseMatters)) {
         return PR_FALSE;
   }
   return PR_TRUE;
 }
 
 PRBool
-nsAccUtils::HasAccessibleChildren(nsIDOMNode *aNode)
+nsAccUtils::HasAccessibleChildren(nsINode *aNode)
 {
   if (!aNode)
     return PR_FALSE;
 
-  nsCOMPtr<nsIContent> content(do_QueryInterface(aNode));
-  if (!content)
-    return PR_FALSE;
-
   nsIPresShell *presShell = nsCoreUtils::GetPresShellFor(aNode);
   if (!presShell)
     return PR_FALSE;
 
-  nsIFrame *frame = content->GetPrimaryFrame();
-  if (!frame)
-    return PR_FALSE;
-
+  nsIContent *content = nsCoreUtils::GetRoleContent(aNode);
   nsCOMPtr<nsIWeakReference> weakShell(do_GetWeakReference(presShell));
   nsAccTreeWalker walker(weakShell, content, PR_FALSE);
   nsRefPtr<nsAccessible> accessible = walker.GetNextChild();
   return accessible ? PR_TRUE : PR_FALSE;
 }
 
-already_AddRefed<nsIAccessible>
-nsAccUtils::GetAncestorWithRole(nsIAccessible *aDescendant, PRUint32 aRole)
+nsAccessible *
+nsAccUtils::GetAncestorWithRole(nsAccessible *aDescendant, PRUint32 aRole)
 {
-  nsCOMPtr<nsIAccessible> parentAccessible = aDescendant, testRoleAccessible;
-  while (NS_SUCCEEDED(parentAccessible->GetParent(getter_AddRefs(testRoleAccessible))) &&
-         testRoleAccessible) {
-    PRUint32 testRole = nsAccUtils::Role(testRoleAccessible);
-    if (testRole == aRole) {
-      nsIAccessible *returnAccessible = testRoleAccessible;
-      NS_ADDREF(returnAccessible);
-      return returnAccessible;
-    }
-    nsCOMPtr<nsIAccessibleDocument> docAccessible = do_QueryInterface(testRoleAccessible);
-    if (docAccessible) {
+  nsAccessible *document = aDescendant->GetDocAccessible();
+  nsAccessible *parent = aDescendant;
+  while ((parent = parent->GetParent())) {
+    PRUint32 testRole = nsAccUtils::Role(parent);
+    if (testRole == aRole)
+      return parent;
+
+    if (parent == document)
       break;
-    }
-    parentAccessible.swap(testRoleAccessible);
   }
   return nsnull;
 }
 
 void
 nsAccUtils::GetARIATreeItemParent(nsIAccessible *aStartTreeItem,
                                   nsIContent *aStartContent,
                                   nsIAccessible **aTreeItemParentResult)
@@ -482,77 +462,61 @@ nsAccUtils::GetARIATreeItemParent(nsIAcc
     role = nsAccUtils::Role(prevAccessible);
   }
   if (role == nsIAccessibleRole::ROLE_OUTLINEITEM) {
     // Previous sibling of parent group is a tree item -- this is the conceptual tree item parent
     NS_ADDREF(*aTreeItemParentResult = prevAccessible);
   }
 }
 
-already_AddRefed<nsIAccessible>
-nsAccUtils::GetSelectableContainer(nsIAccessible *aAccessible, PRUint32 aState)
+nsAccessible *
+nsAccUtils::GetSelectableContainer(nsAccessible *aAccessible, PRUint32 aState)
 {
   if (!aAccessible)
     return nsnull;
 
   if (!(aState & nsIAccessibleStates::STATE_SELECTABLE))
     return nsnull;
 
   nsCOMPtr<nsIAccessibleSelectable> container;
-  nsCOMPtr<nsIAccessible> parent, accessible(aAccessible);
+  nsAccessible *parent = aAccessible;
   while (!container) {
-    accessible->GetParent(getter_AddRefs(parent));
-
+    parent = parent->GetParent();
     if (!parent || Role(parent) == nsIAccessibleRole::ROLE_PANE)
       return nsnull;
 
-    container = do_QueryInterface(parent);
-    parent.swap(accessible);
+    container = do_QueryObject(parent);
   }
 
-  return accessible.forget();
+  return parent;
 }
 
-already_AddRefed<nsIAccessible>
-nsAccUtils::GetMultiSelectableContainer(nsIDOMNode *aNode)
+nsAccessible *
+nsAccUtils::GetMultiSelectableContainer(nsINode *aNode)
 {
-  nsCOMPtr<nsIAccessible> accessible;
-  GetAccService()->GetAccessibleFor(aNode, getter_AddRefs(accessible));
-
-  nsCOMPtr<nsIAccessible> container =
-    GetSelectableContainer(accessible, State(accessible));
+  nsAccessible *accessible = GetAccService()->GetAccessible(aNode);
+  nsAccessible *container = GetSelectableContainer(accessible,
+                                                   State(accessible));
 
   if (State(container) & nsIAccessibleStates::STATE_MULTISELECTABLE)
-    return container.forget();
-
+    return container;
   return nsnull;
 }
 
 PRBool
-nsAccUtils::IsARIASelected(nsIAccessible *aAccessible)
+nsAccUtils::IsARIASelected(nsAccessible *aAccessible)
 {
-  nsRefPtr<nsAccessible> acc = do_QueryObject(aAccessible);
-  nsCOMPtr<nsIDOMNode> node;
-  acc->GetDOMNode(getter_AddRefs(node));
-  NS_ASSERTION(node, "No DOM node!");
-
-  if (node) {
-    nsCOMPtr<nsIContent> content(do_QueryInterface(node));
-    if (content->AttrValueIs(kNameSpaceID_None,
-                             nsAccessibilityAtoms::aria_selected,
-                             nsAccessibilityAtoms::_true, eCaseMatters))
-      return PR_TRUE;
-  }
-
-  return PR_FALSE;
+  return aAccessible->GetContent()->
+    AttrValueIs(kNameSpaceID_None, nsAccessibilityAtoms::aria_selected,
+                nsAccessibilityAtoms::_true, eCaseMatters);
 }
 
-already_AddRefed<nsIAccessibleText>
+already_AddRefed<nsHyperTextAccessible>
 nsAccUtils::GetTextAccessibleFromSelection(nsISelection *aSelection,
-                                           nsIDOMNode **aNode)
+                                           nsINode **aNode)
 {
   // Get accessible from selection's focus DOM point (the DOM point where
   // selection is ended).
 
   nsCOMPtr<nsIDOMNode> focusDOMNode;
   aSelection->GetFocusNode(getter_AddRefs(focusDOMNode));
   if (!focusDOMNode)
     return nsnull;
@@ -563,51 +527,43 @@ nsAccUtils::GetTextAccessibleFromSelecti
   nsCOMPtr<nsINode> focusNode(do_QueryInterface(focusDOMNode));
   nsCOMPtr<nsINode> resultNode =
     nsCoreUtils::GetDOMNodeFromDOMPoint(focusNode, focusOffset);
 
   // Get text accessible containing the result node.
   while (resultNode) {
     // Make sure to get the correct starting node for selection events inside
     // XBL content trees.
-    nsCOMPtr<nsIDOMNode> resultDOMNode(do_QueryInterface(resultNode));
-    nsCOMPtr<nsIDOMNode> relevantDOMNode;
-    GetAccService()->GetRelevantContentNodeFor(resultDOMNode,
-                                               getter_AddRefs(relevantDOMNode));
-    if (relevantDOMNode) {
-      resultNode = do_QueryInterface(relevantDOMNode);
-      resultDOMNode.swap(relevantDOMNode);
-    }
-
-    if (!resultNode || !resultNode->IsNodeOfType(nsINode::eTEXT)) {
-      nsAccessible *accessible = GetAccService()->GetAccessible(resultDOMNode);
+    resultNode = GetAccService()->GetRelevantContentNodeFor(resultNode);
+    if (!resultNode->IsNodeOfType(nsINode::eTEXT)) {
+      nsAccessible *accessible = GetAccService()->GetAccessible(resultNode);
       if (accessible) {
-        nsIAccessibleText *textAcc = nsnull;
+        nsHyperTextAccessible *textAcc = nsnull;
         CallQueryInterface(accessible, &textAcc);
         if (textAcc) {
           if (aNode)
-            resultDOMNode.forget(aNode);
+            NS_ADDREF(*aNode = resultNode);
 
           return textAcc;
         }
       }
     }
 
-    resultNode = resultNode->GetParent();
+    resultNode = resultNode->GetNodeParent();
   }
 
   NS_NOTREACHED("No nsIAccessibleText for selection change event!");
 
   return nsnull;
 }
 
 nsresult
 nsAccUtils::ConvertToScreenCoords(PRInt32 aX, PRInt32 aY,
                                   PRUint32 aCoordinateType,
-                                  nsIAccessNode *aAccessNode,
+                                  nsAccessNode *aAccessNode,
                                   nsIntPoint *aCoords)
 {
   NS_ENSURE_ARG_POINTER(aCoords);
 
   aCoords->MoveTo(aX, aY);
 
   switch (aCoordinateType) {
     case nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE:
@@ -632,17 +588,17 @@ nsAccUtils::ConvertToScreenCoords(PRInt3
   }
 
   return NS_OK;
 }
 
 nsresult
 nsAccUtils::ConvertScreenCoordsTo(PRInt32 *aX, PRInt32 *aY,
                                   PRUint32 aCoordinateType,
-                                  nsIAccessNode *aAccessNode)
+                                  nsAccessNode *aAccessNode)
 {
   switch (aCoordinateType) {
     case nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE:
       break;
 
     case nsIAccessibleCoordinateType::COORDTYPE_WINDOW_RELATIVE:
     {
       NS_ENSURE_ARG(aAccessNode);
@@ -664,54 +620,39 @@ nsAccUtils::ConvertScreenCoordsTo(PRInt3
     default:
       return NS_ERROR_INVALID_ARG;
   }
 
   return NS_OK;
 }
 
 nsIntPoint
-nsAccUtils::GetScreenCoordsForWindow(nsIAccessNode *aAccessNode)
+nsAccUtils::GetScreenCoordsForWindow(nsAccessNode *aAccessNode)
 {
-  nsCOMPtr<nsIDOMNode> DOMNode;
-  aAccessNode->GetDOMNode(getter_AddRefs(DOMNode));
-  if (DOMNode)
-    return nsCoreUtils::GetScreenCoordsForWindow(DOMNode);
-
-  return nsIntPoint(0, 0);
+  return nsCoreUtils::GetScreenCoordsForWindow(aAccessNode->GetNode());
 }
 
 nsIntPoint
-nsAccUtils::GetScreenCoordsForParent(nsIAccessNode *aAccessNode)
+nsAccUtils::GetScreenCoordsForParent(nsAccessNode *aAccessNode)
 {
-  nsRefPtr<nsAccessNode> parent;
-  nsCOMPtr<nsIAccessible> accessible(do_QueryInterface(aAccessNode));
-  if (accessible) {
-    nsCOMPtr<nsIAccessible> parentAccessible;
-    accessible->GetParent(getter_AddRefs(parentAccessible));
-    parent = do_QueryObject(parentAccessible);
-  } else {
-    nsCOMPtr<nsIAccessNode> parentAccessNode;
-    aAccessNode->GetParentNode(getter_AddRefs(parentAccessNode));
-    parent = do_QueryObject(parentAccessNode);
-  }
-
+  nsAccessible *parent =
+    GetAccService()->GetContainerAccessible(aAccessNode->GetNode(), PR_TRUE);
   if (!parent)
     return nsIntPoint(0, 0);
 
   nsIFrame *parentFrame = parent->GetFrame();
   if (!parentFrame)
     return nsIntPoint(0, 0);
 
   nsIntRect parentRect = parentFrame->GetScreenRectExternal();
   return nsIntPoint(parentRect.x, parentRect.y);
 }
 
 nsRoleMapEntry*
-nsAccUtils::GetRoleMapEntry(nsIDOMNode *aNode)
+nsAccUtils::GetRoleMapEntry(nsINode *aNode)
 {
   nsIContent *content = nsCoreUtils::GetRoleContent(aNode);
   nsAutoString roleString;
   if (!content ||
       !content->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::role, roleString) ||
       roleString.IsEmpty()) {
     // We treat role="" as if the role attribute is absent (per aria spec:8.1.1)
     return nsnull;
@@ -870,21 +811,19 @@ nsAccUtils::MustPrune(nsIAccessible *aAc
     role == nsIAccessibleRole::ROLE_TOGGLE_BUTTON ||
     role == nsIAccessibleRole::ROLE_GRAPHIC ||
     role == nsIAccessibleRole::ROLE_SLIDER ||
     role == nsIAccessibleRole::ROLE_PROGRESSBAR ||
     role == nsIAccessibleRole::ROLE_SEPARATOR;
 }
 
 PRBool
-nsAccUtils::IsNodeRelevant(nsIDOMNode *aNode)
+nsAccUtils::IsNodeRelevant(nsINode *aNode)
 {
-  nsCOMPtr<nsIDOMNode> relevantNode;
-  GetAccService()->GetRelevantContentNodeFor(aNode, getter_AddRefs(relevantNode));
-  return aNode == relevantNode;
+  return aNode == GetAccService()->GetRelevantContentNodeFor(aNode);
 }
 
 nsresult
 nsAccUtils::GetHeaderCellsFor(nsIAccessibleTable *aTable,
                               nsIAccessibleTableCell *aCell,
                               PRInt32 aRowOrColHeaderCells, nsIArray **aCells)
 {
   nsresult rv = NS_OK;
--- a/accessible/src/base/nsAccUtils.h
+++ b/accessible/src/base/nsAccUtils.h
@@ -54,16 +54,17 @@
 #include "nsIDocShell.h"
 #include "nsIDOMNode.h"
 #include "nsIPersistentProperties2.h"
 #include "nsIPresShell.h"
 #include "nsPoint.h"
 
 class nsAccessNode;
 class nsAccessible;
+class nsHyperTextAccessible;
 class nsHTMLTableAccessible;
 class nsDocAccessible;
 #ifdef MOZ_XUL
 class nsXULTreeAccessible;
 #endif
 
 class nsAccUtils
 {
@@ -101,38 +102,38 @@ public:
    * Get default value of the level for the given accessible.
    */
   static PRInt32 GetDefaultLevel(nsAccessible *aAcc);
 
   /**
    * Return ARIA level value or the default one if ARIA is missed for the
    * given accessible.
    */
-  static PRInt32 GetARIAOrDefaultLevel(nsIAccessible *aAcc);
+  static PRInt32 GetARIAOrDefaultLevel(nsAccessible *aAccessible);
 
   /**
    * Compute position in group (posinset) and group size (setsize) for
    * nsIDOMXULSelectControlItemElement node.
    */
-  static void GetPositionAndSizeForXULSelectControlItem(nsIDOMNode *aNode,
+  static void GetPositionAndSizeForXULSelectControlItem(nsIContent *aContent,
                                                         PRInt32 *aPosInSet,
                                                         PRInt32 *aSetSize);
 
   /**
    * Compute group position and group size (posinset and setsize) for
    * nsIDOMXULContainerItemElement node.
    */
-  static void GetPositionAndSizeForXULContainerItem(nsIDOMNode *aNode,
+  static void GetPositionAndSizeForXULContainerItem(nsIContent *aContent,
                                                     PRInt32 *aPosInSet,
                                                     PRInt32 *aSetSize);
 
   /**
    * Compute group level for nsIDOMXULContainerItemElement node.
    */
-  static PRInt32 GetLevelForXULContainerItem(nsIDOMNode *aNode);
+  static PRInt32 GetLevelForXULContainerItem(nsIContent *aContent);
 
   /**
    * Set container-foo live region attributes for the given node.
    *
    * @param aAttributes    where to store the attributes
    * @param aStartContent  node to start from
    * @param aTopContent    node to end at
    */
@@ -157,17 +158,17 @@ public:
     nsCOMPtr<nsIPresShell> presShell(do_QueryReferent(aWeakShell));
     return presShell ?
       GetAccService()->GetDocAccessible(presShell->GetDocument()) : nsnull;
   }
 
   /**
    * Return document accessible for the given DOM node.
    */
-  static nsDocAccessible *GetDocAccessibleFor(nsIDOMNode *aNode)
+  static nsDocAccessible *GetDocAccessibleFor(nsINode *aNode)
   {
     nsIPresShell *presShell = nsCoreUtils::GetPresShellFor(aNode);
     return presShell ?
       GetAccService()->GetDocAccessible(presShell->GetDocument()) : nsnull;
   }
 
   /**
    * Return document accessible for the given docshell.
@@ -179,26 +180,28 @@ public:
     docShell->GetPresShell(getter_AddRefs(presShell));
     return presShell ?
       GetAccService()->GetDocAccessible(presShell->GetDocument()) : nsnull;
   }
 
   /**
    * Return true if the given DOM node contains accessible children.
    */
-  static PRBool HasAccessibleChildren(nsIDOMNode *aNode);
+  static PRBool HasAccessibleChildren(nsINode *aNode);
 
   /**
-    * If an ancestor in this document exists with the given role, return it
-    * @param aDescendant Descendant to start search with
-    * @param aRole Role to find matching ancestor for
-    * @return The ancestor accessible with the given role, or nsnull if no match is found
+    * Return ancestor in this document with the given role if it exists.
+    *
+    * @param  aDescendant  [in] descendant to start search with
+    * @param  aRole        [in] role to find matching ancestor for
+    * @return               the ancestor accessible with the given role, or
+    *                       nsnull if no match is found
     */
-   static already_AddRefed<nsIAccessible>
-     GetAncestorWithRole(nsIAccessible *aDescendant, PRUint32 aRole);
+   static nsAccessible * GetAncestorWithRole(nsAccessible *aDescendant,
+                                             PRUint32 aRole);
 
    /**
      * For an ARIA tree item , get the accessible that represents its conceptual parent.
      * This method will use the correct method for the given way the tree is constructed.
      * The conceptual parent is what the user sees as the parent, not the DOM or accessible parent.
      * @param aStartTreeItem  The tree item to get the parent for
      * @param aStartTreeItemContent  The content node for the tree item
      * @param The tree item's parent, or null if none
@@ -209,95 +212,96 @@ public:
                            nsIAccessible **aTreeItemParent);
 
   /**
    * Return single or multi selectable container for the given item.
    *
    * @param  aAccessible  [in] the item accessible
    * @param  aState       [in] the state of the item accessible
    */
-  static already_AddRefed<nsIAccessible>
-    GetSelectableContainer(nsIAccessible *aAccessible, PRUint32 aState);
+  static nsAccessible *GetSelectableContainer(nsAccessible *aAccessible,
+                                              PRUint32 aState);
 
   /**
    * Return multi selectable container for the given item.
    */
-  static already_AddRefed<nsIAccessible>
-    GetMultiSelectableContainer(nsIDOMNode *aNode);
+  static nsAccessible *GetMultiSelectableContainer(nsINode *aNode);
 
   /**
    * Return true if the DOM node of given accessible has aria-selected="true"
    * attribute.
    */
-  static PRBool IsARIASelected(nsIAccessible *aAccessible);
+  static PRBool IsARIASelected(nsAccessible *aAccessible);
 
   /**
    * Return text accessible containing focus point of the given selection.
    * Used for normal and misspelling selection changes processing.
    *
    * @param aSelection  [in] the given selection
    * @param aNode       [out, optional] the DOM node of text accessible
    * @return            text accessible
    */
-  static already_AddRefed<nsIAccessibleText>
+  static already_AddRefed<nsHyperTextAccessible>
     GetTextAccessibleFromSelection(nsISelection *aSelection,
-                                   nsIDOMNode **aNode = nsnull);
+                                   nsINode **aNode = nsnull);
 
   /**
    * Converts the given coordinates to coordinates relative screen.
    *
    * @param aX               [in] the given x coord
    * @param aY               [in] the given y coord
    * @param aCoordinateType  [in] specifies coordinates origin (refer to
    *                         nsIAccessibleCoordinateType)
    * @param aAccessNode      [in] the accessible if coordinates are given
    *                         relative it.
    * @param aCoords          [out] converted coordinates
    */
   static nsresult ConvertToScreenCoords(PRInt32 aX, PRInt32 aY,
                                         PRUint32 aCoordinateType,
-                                        nsIAccessNode *aAccessNode,
+                                        nsAccessNode *aAccessNode,
                                         nsIntPoint *aCoords);
 
   /**
    * Converts the given coordinates relative screen to another coordinate
    * system.
    *
    * @param aX               [in, out] the given x coord
    * @param aY               [in, out] the given y coord
    * @param aCoordinateType  [in] specifies coordinates origin (refer to
    *                         nsIAccessibleCoordinateType)
    * @param aAccessNode      [in] the accessible if coordinates are given
    *                         relative it
    */
   static nsresult ConvertScreenCoordsTo(PRInt32 *aX, PRInt32 *aY,
                                         PRUint32 aCoordinateType,
-                                        nsIAccessNode *aAccessNode);
+                                        nsAccessNode *aAccessNode);
 
   /**
    * Returns coordinates relative screen for the top level window.
    *
    * @param aAccessNode  the accessible hosted in the window
    */
-  static nsIntPoint GetScreenCoordsForWindow(nsIAccessNode *aAccessNode);
+  static nsIntPoint GetScreenCoordsForWindow(nsAccessNode *aAccessNode);
 
   /**
    * Returns coordinates relative screen for the parent of the given accessible.
    *
    * @param aAccessNode  the accessible
    */
-  static nsIntPoint GetScreenCoordsForParent(nsIAccessNode *aAccessNode);
+  static nsIntPoint GetScreenCoordsForParent(nsAccessNode *aAccessNode);
 
   /**
    * Get the role map entry for a given DOM node. This will use the first
    * ARIA role if the role attribute provides a space delimited list of roles.
-   * @param aNode  The DOM node to get the role map entry for
-   * @return       A pointer to the role map entry for the ARIA role, or nsnull if none
+   *
+   * @param aNode  [in] the DOM node to get the role map entry for
+   * @return        a pointer to the role map entry for the ARIA role, or nsnull
+   *                if none
    */
-  static nsRoleMapEntry* GetRoleMapEntry(nsIDOMNode *aNode);
+  static nsRoleMapEntry *GetRoleMapEntry(nsINode *aNode);
 
   /**
    * Return the role of the given accessible.
    */
   static PRUint32 Role(nsIAccessible *aAcc)
   {
     PRUint32 role = nsIAccessibleRole::ROLE_NOTHING;
     if (aAcc)
@@ -405,17 +409,17 @@ public:
    * to platform accessibility APIs, should the children be pruned off?
    */
   static PRBool MustPrune(nsIAccessible *aAccessible);
 
   /**
    * Return true if the given node can be accessible and attached to
    * the document's accessible tree.
    */
-  static PRBool IsNodeRelevant(nsIDOMNode *aNode);
+  static PRBool IsNodeRelevant(nsINode *aNode);
 
   /**
    * Search hint enum constants. Used by GetHeaderCellsFor() method.
    */
   enum {
     // search for row header cells, left direction
     eRowHeaderCells,
     // search for column header cells, top direction
--- a/accessible/src/base/nsAccessNode.cpp
+++ b/accessible/src/base/nsAccessNode.cpp
@@ -75,17 +75,17 @@
 #include "mozilla/Services.h"
 
 /* For documentation of the accessibility architecture, 
  * see http://lxr.mozilla.org/seamonkey/source/accessible/accessible-docs.html
  */
 
 nsIStringBundle *nsAccessNode::gStringBundle = 0;
 nsIStringBundle *nsAccessNode::gKeyStringBundle = 0;
-nsIDOMNode *nsAccessNode::gLastFocusedNode = 0;
+nsINode *nsAccessNode::gLastFocusedNode = nsnull;
 
 PRBool nsAccessNode::gIsCacheDisabled = PR_FALSE;
 PRBool nsAccessNode::gIsFormFillEnabled = PR_FALSE;
 
 nsApplicationAccessible *nsAccessNode::gApplicationAccessible = nsnull;
 
 /*
  * Class nsAccessNode
@@ -104,18 +104,19 @@ NS_INTERFACE_MAP_END
  
 NS_IMPL_CYCLE_COLLECTING_ADDREF_AMBIGUOUS(nsAccessNode, nsIAccessNode)
 NS_IMPL_CYCLE_COLLECTING_RELEASE_FULL(nsAccessNode, nsIAccessNode,
                                       LastRelease())
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccessNode construction/desctruction
 
-nsAccessNode::nsAccessNode(nsIDOMNode *aNode, nsIWeakReference* aShell): 
-  mDOMNode(aNode), mWeakShell(aShell)
+nsAccessNode::
+  nsAccessNode(nsIContent *aContent, nsIWeakReference *aShell) :
+  mContent(aContent), mWeakShell(aShell)
 {
 #ifdef DEBUG_A11Y
   mIsInitialized = PR_FALSE;
 #endif
 }
 
 nsAccessNode::~nsAccessNode()
 {
@@ -131,89 +132,48 @@ void nsAccessNode::LastRelease()
   }
   // ... then die.
   NS_DELETEXPCOM(this);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccessNode public
 
-nsresult
+PRBool
 nsAccessNode::Init()
 {
-  // We have to put this here, instead of constructor, otherwise
-  // we don't have the virtual GetUniqueID() method for the hash key.
-  // We need that for accessibles that don't have DOM nodes
-
-#ifdef DEBUG_A11Y
-  NS_ASSERTION(!mIsInitialized, "Initialized twice!");
-#endif
-  nsDocAccessible *docAcc = nsnull;
-  nsCOMPtr<nsIPresShell> presShell(do_QueryReferent(mWeakShell));
-  if (presShell)
-    docAcc = GetAccService()->GetDocAccessible(presShell->GetDocument());
-
-  NS_ASSERTION(docAcc, "Cannot cache new nsAccessNode");
-  if (!docAcc) {
-#ifdef DEBUG
-    docAcc = GetAccService()->GetDocAccessible(presShell->GetDocument());
-#endif
-    return NS_ERROR_FAILURE;
-  }
-
-  void* uniqueID;
-  GetUniqueID(&uniqueID);
-
-  if (!docAcc->CacheAccessNode(uniqueID, this))
-    return NS_ERROR_OUT_OF_MEMORY;
-
-  // Make sure an ancestor in real content is cached
-  // so that nsDocAccessible::RefreshNodes() can find the anonymous subtree to release when
-  // the root node goes away
-  nsCOMPtr<nsIContent> content = do_QueryInterface(mDOMNode);
-  if (content && content->IsInAnonymousSubtree()) {
-    // Specific examples of where this is used: <input type="file"> and <xul:findbar>
-    nsAccessible *parent = GetAccService()->GetContainerAccessible(mDOMNode,
-                                                                   PR_TRUE);
-    if (parent)
-      parent->EnsureChildren();
-  }
-
-#ifdef DEBUG_A11Y
-  mIsInitialized = PR_TRUE;
-#endif
-
-  return NS_OK;
+  return PR_TRUE;
 }
 
 
-nsresult
+void
 nsAccessNode::Shutdown()
 {
-  mDOMNode = nsnull;
+  mContent = nsnull;
   mWeakShell = nsnull;
-
-  return NS_OK;
 }
 
 // nsIAccessNode
 NS_IMETHODIMP nsAccessNode::GetUniqueID(void **aUniqueID)
 {
-  *aUniqueID = static_cast<void*>(mDOMNode);
+  *aUniqueID = static_cast<void*>(GetNode());
   return NS_OK;
 }
 
 // nsIAccessNode
-NS_IMETHODIMP nsAccessNode::GetOwnerWindow(void **aWindow)
+NS_IMETHODIMP
+nsAccessNode::GetOwnerWindow(void **aWindow)
 {
+  NS_ENSURE_ARG_POINTER(aWindow);
   *aWindow = nsnull;
-  nsCOMPtr<nsIAccessibleDocument> docAccessible(GetDocAccessible());
-  if (!docAccessible)
-    return NS_ERROR_FAILURE; // This node or doc accessible is shut down
-  return docAccessible->GetWindowHandle(aWindow);
+
+  if (IsDefunct())
+    return NS_ERROR_FAILURE;
+
+  return GetDocAccessible()->GetWindowHandle(aWindow);
 }
 
 nsApplicationAccessible*
 nsAccessNode::GetApplicationAccessible()
 {
   NS_ASSERTION(!nsAccessibilityService::IsShutdown(),
                "Accessibility wasn't initialized!");
 
@@ -295,17 +255,17 @@ void nsAccessNode::ShutdownXPAccessibili
   }
 
   NotifyA11yInitOrShutdown(PR_FALSE);
 }
 
 PRBool
 nsAccessNode::IsDefunct()
 {
-  if (!mDOMNode)
+  if (!mContent)
     return PR_TRUE;
 
   // Call GetPresShell() since the accessible may be shut down in it.
   nsCOMPtr<nsIPresShell> presShell(GetPresShell());
   return !presShell;
 }
 
 already_AddRefed<nsIPresShell> nsAccessNode::GetPresShell()
@@ -330,21 +290,28 @@ nsPresContext* nsAccessNode::GetPresCont
 {
   nsCOMPtr<nsIPresShell> presShell(GetPresShell());
   if (!presShell) {
     return nsnull;
   }
   return presShell->GetPresContext();
 }
 
+nsDocAccessible *
+nsAccessNode::GetDocAccessible() const
+{
+  return mContent ?
+    GetAccService()->GetDocAccessible(mContent->GetOwnerDoc()) : nsnull;
+}
+
 already_AddRefed<nsRootAccessible> nsAccessNode::GetRootAccessible()
 {
   nsCOMPtr<nsIDocShellTreeItem> docShellTreeItem =
-    nsCoreUtils::GetDocShellTreeItemFor(mDOMNode);
-  NS_ASSERTION(docShellTreeItem, "No docshell tree item for mDOMNode");
+    nsCoreUtils::GetDocShellTreeItemFor(mContent);
+  NS_ASSERTION(docShellTreeItem, "No docshell tree item for mContent");
   if (!docShellTreeItem) {
     return nsnull;
   }
   nsCOMPtr<nsIDocShellTreeItem> root;
   docShellTreeItem->GetRootTreeItem(getter_AddRefs(root));
   NS_ASSERTION(root, "No root content tree item");
   if (!root) {
     return nsnull;
@@ -353,67 +320,41 @@ already_AddRefed<nsRootAccessible> nsAcc
   nsDocAccessible *docAcc = nsAccUtils::GetDocAccessibleFor(root);
   nsRefPtr<nsRootAccessible> rootAcc = do_QueryObject(docAcc);
   return rootAcc.forget();
 }
 
 nsIFrame*
 nsAccessNode::GetFrame()
 {
-  nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
-  return content ? content->GetPrimaryFrame() : nsnull;
+  return mContent ? mContent->GetPrimaryFrame() : nsnull;
 }
 
-#ifdef DEBUG
-PRBool
-nsAccessNode::IsInCache()
-{
-  nsDocAccessible *docAccessible = nsAccUtils::GetDocAccessibleFor(mWeakShell);
-  if (!docAccessible)
-    return nsnull;
-
-  void* uniqueID = nsnull;
-  GetUniqueID(&uniqueID);
-
-  return docAccessible->GetCachedAccessNode(uniqueID) ? PR_TRUE : PR_FALSE;
-}
-#endif
-
 ////////////////////////////////////////////////////////////////////////////////
 // nsIAccessNode
 
 NS_IMETHODIMP
-nsAccessNode::GetDOMNode(nsIDOMNode **aNode)
-{
-  NS_IF_ADDREF(*aNode = mDOMNode);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsAccessNode::GetNumChildren(PRInt32 *aNumChildren)
+nsAccessNode::GetDOMNode(nsIDOMNode **aDOMNode)
 {
-  nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
-
-  if (!content) {
-    *aNumChildren = 0;
+  NS_ENSURE_ARG_POINTER(aDOMNode);
+  *aDOMNode = nsnull;
 
-    return NS_ERROR_NULL_POINTER;
-  }
-
-  *aNumChildren = content->GetChildCount();
+  nsINode *node = GetNode();
+  if (node)
+    CallQueryInterface(node, aDOMNode);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsAccessNode::GetDocument(nsIAccessibleDocument **aDocument)
 {
   NS_ENSURE_ARG_POINTER(aDocument);
 
-  NS_IF_ADDREF(*aDocument = nsAccUtils::GetDocAccessibleFor(mWeakShell));
+  NS_IF_ADDREF(*aDocument = GetDocAccessible());
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsAccessNode::GetRootDocument(nsIAccessibleDocument **aRootDocument)
 {
   NS_ENSURE_ARG_POINTER(aRootDocument);
 
@@ -422,17 +363,17 @@ nsAccessNode::GetRootDocument(nsIAccessi
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsAccessNode::GetInnerHTML(nsAString& aInnerHTML)
 {
   aInnerHTML.Truncate();
 
-  nsCOMPtr<nsIDOMNSHTMLElement> domNSElement(do_QueryInterface(mDOMNode));
+  nsCOMPtr<nsIDOMNSHTMLElement> domNSElement(do_QueryInterface(mContent));
   NS_ENSURE_TRUE(domNSElement, NS_ERROR_NULL_POINTER);
 
   return domNSElement->GetInnerHTML(aInnerHTML);
 }
 
 NS_IMETHODIMP
 nsAccessNode::ScrollTo(PRUint32 aScrollType)
 {
@@ -467,181 +408,74 @@ nsAccessNode::ScrollToPoint(PRUint32 aCo
 
   nsIFrame *parentFrame = frame;
   while ((parentFrame = parentFrame->GetParent()))
     nsCoreUtils::ScrollFrameToPoint(parentFrame, frame, coords);
 
   return NS_OK;
 }
 
-// nsAccessNode protected
-nsresult
-nsAccessNode::MakeAccessNode(nsIDOMNode *aNode, nsIAccessNode **aAccessNode)
-{
-  *aAccessNode = nsnull;
-  
-  nsCOMPtr<nsIAccessNode> accessNode =
-    GetAccService()->GetCachedAccessNode(aNode, mWeakShell);
-
-  if (!accessNode)
-    accessNode = GetAccService()->GetAccessibleInWeakShell(aNode, mWeakShell);
-
-  if (accessNode) {
-    NS_ADDREF(*aAccessNode = accessNode);
-    return NS_OK;
-  }
-
-  nsAccessNode *newAccessNode = new nsAccessNode(aNode, mWeakShell);
-  if (!newAccessNode) {
-    return NS_ERROR_OUT_OF_MEMORY;
-  }
-
-  NS_ADDREF(*aAccessNode = newAccessNode);
-  newAccessNode->Init();
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsAccessNode::GetFirstChildNode(nsIAccessNode **aAccessNode)
-{
-  NS_ENSURE_ARG_POINTER(aAccessNode);
-  *aAccessNode = nsnull;
-  NS_ENSURE_TRUE(mDOMNode, NS_ERROR_NULL_POINTER);
-
-  nsCOMPtr<nsIDOMNode> domNode;
-  mDOMNode->GetFirstChild(getter_AddRefs(domNode));
-
-  return domNode ? MakeAccessNode(domNode, aAccessNode) : NS_OK;
-}
-
-NS_IMETHODIMP
-nsAccessNode::GetLastChildNode(nsIAccessNode **aAccessNode)
-{
-  NS_ENSURE_ARG_POINTER(aAccessNode);
-  *aAccessNode = nsnull;
-  NS_ENSURE_TRUE(mDOMNode, NS_ERROR_NULL_POINTER);
-
-  nsCOMPtr<nsIDOMNode> domNode;
-  mDOMNode->GetLastChild(getter_AddRefs(domNode));
-
-  return domNode ? MakeAccessNode(domNode, aAccessNode) : NS_OK;
-}
-
-NS_IMETHODIMP
-nsAccessNode::GetParentNode(nsIAccessNode **aAccessNode)
-{
-  NS_ENSURE_ARG_POINTER(aAccessNode);
-  *aAccessNode = nsnull;
-  NS_ENSURE_TRUE(mDOMNode, NS_ERROR_NULL_POINTER);
-
-  nsCOMPtr<nsIDOMNode> domNode;
-  mDOMNode->GetParentNode(getter_AddRefs(domNode));
-
-  return domNode ? MakeAccessNode(domNode, aAccessNode) : NS_OK;
-}
-
-NS_IMETHODIMP
-nsAccessNode::GetPreviousSiblingNode(nsIAccessNode **aAccessNode)
-{
-  NS_ENSURE_ARG_POINTER(aAccessNode);
-  *aAccessNode = nsnull;
-  NS_ENSURE_TRUE(mDOMNode, NS_ERROR_NULL_POINTER);
-
-  nsCOMPtr<nsIDOMNode> domNode;
-  mDOMNode->GetPreviousSibling(getter_AddRefs(domNode));
-
-  return domNode ? MakeAccessNode(domNode, aAccessNode) : NS_OK;
-}
-
-NS_IMETHODIMP
-nsAccessNode::GetNextSiblingNode(nsIAccessNode **aAccessNode)
-{
-  NS_ENSURE_ARG_POINTER(aAccessNode);
-  *aAccessNode = nsnull;
-  NS_ENSURE_TRUE(mDOMNode, NS_ERROR_NULL_POINTER);
-
-  nsCOMPtr<nsIDOMNode> domNode;
-  mDOMNode->GetNextSibling(getter_AddRefs(domNode));
-
-  return domNode ? MakeAccessNode(domNode, aAccessNode) : NS_OK;
-}
-
-NS_IMETHODIMP
-nsAccessNode::GetChildNodeAt(PRInt32 aChildNum, nsIAccessNode **aAccessNode)
-{
-  NS_ENSURE_ARG_POINTER(aAccessNode);
-  *aAccessNode = nsnull;
-
-  nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
-  NS_ENSURE_TRUE(content, NS_ERROR_NULL_POINTER);
-
-  nsCOMPtr<nsIDOMNode> domNode =
-    do_QueryInterface(content->GetChildAt(aChildNum));
-
-  return domNode ? MakeAccessNode(domNode, aAccessNode) : NS_OK;
-}
-
 NS_IMETHODIMP
 nsAccessNode::GetComputedStyleValue(const nsAString& aPseudoElt,
                                     const nsAString& aPropertyName,
                                     nsAString& aValue)
 {
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
-  nsCOMPtr<nsIDOMCSSStyleDeclaration> styleDecl;
-  nsCoreUtils::GetComputedStyleDeclaration(aPseudoElt, mDOMNode,
-                                           getter_AddRefs(styleDecl));
+  nsCOMPtr<nsIDOMCSSStyleDeclaration> styleDecl =
+    nsCoreUtils::GetComputedStyleDeclaration(aPseudoElt, mContent);
   NS_ENSURE_TRUE(styleDecl, NS_ERROR_FAILURE);
 
   return styleDecl->GetPropertyValue(aPropertyName, aValue);
 }
 
 NS_IMETHODIMP
 nsAccessNode::GetComputedStyleCSSValue(const nsAString& aPseudoElt,
                                        const nsAString& aPropertyName,
                                        nsIDOMCSSPrimitiveValue **aCSSValue)
 {
   NS_ENSURE_ARG_POINTER(aCSSValue);
   *aCSSValue = nsnull;
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
-  nsCOMPtr<nsIDOMCSSStyleDeclaration> styleDecl;
-  nsCoreUtils::GetComputedStyleDeclaration(aPseudoElt, mDOMNode,
-                                           getter_AddRefs(styleDecl));
+  nsCOMPtr<nsIDOMCSSStyleDeclaration> styleDecl =
+    nsCoreUtils::GetComputedStyleDeclaration(aPseudoElt, mContent);
   NS_ENSURE_STATE(styleDecl);
 
   nsCOMPtr<nsIDOMCSSValue> cssValue;
   styleDecl->GetPropertyCSSValue(aPropertyName, getter_AddRefs(cssValue));
   NS_ENSURE_TRUE(cssValue, NS_ERROR_FAILURE);
 
   return CallQueryInterface(cssValue, aCSSValue);
 }
 
 // nsAccessNode public
-already_AddRefed<nsIDOMNode> nsAccessNode::GetCurrentFocus()
+already_AddRefed<nsINode>
+nsAccessNode::GetCurrentFocus()
 {
-  nsIPresShell *shell = nsCoreUtils::GetPresShellFor(mDOMNode);
+  // XXX: consider to use nsFocusManager directly, it allows us to avoid
+  // unnecessary query interface calls.
+  nsCOMPtr<nsIPresShell> shell = GetPresShell();
   NS_ENSURE_TRUE(shell, nsnull);
-  nsCOMPtr<nsIDocument> doc = shell->GetDocument();
+  nsIDocument *doc = shell->GetDocument();
   NS_ENSURE_TRUE(doc, nsnull);
 
   nsIDOMWindow* win = doc->GetWindow();
 
   nsCOMPtr<nsIDOMWindow> focusedWindow;
   nsCOMPtr<nsIDOMElement> focusedElement;
   nsCOMPtr<nsIFocusManager> fm = do_GetService(FOCUSMANAGER_CONTRACTID);
   if (fm)
     fm->GetFocusedElementForWindow(win, PR_TRUE, getter_AddRefs(focusedWindow),
                                    getter_AddRefs(focusedElement));
 
-  nsIDOMNode *focusedNode = nsnull;
+  nsINode *focusedNode = nsnull;
   if (focusedElement) {
     CallQueryInterface(focusedElement, &focusedNode);
   }
   else if (focusedWindow) {
     nsCOMPtr<nsIDOMDocument> doc;
     focusedWindow->GetDocument(getter_AddRefs(doc));
     if (doc)
       CallQueryInterface(doc, &focusedNode);
@@ -649,52 +483,23 @@ already_AddRefed<nsIDOMNode> nsAccessNod
 
   return focusedNode;
 }
 
 NS_IMETHODIMP
 nsAccessNode::GetLanguage(nsAString& aLanguage)
 {
   aLanguage.Truncate();
-  nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
-  if (!content) {
-    // For documents make sure we look for lang attribute on
-    // document element
-    nsCOMPtr<nsIDOMDocument> domDoc(do_QueryInterface(mDOMNode));
-    if (domDoc) {
-      nsCOMPtr<nsIDOMHTMLDocument> htmlDoc(do_QueryInterface(mDOMNode));
-      if (htmlDoc) {
-        // Make sure we look for lang attribute on HTML <body>
-        nsCOMPtr<nsIDOMHTMLElement> bodyElement;
-        htmlDoc->GetBody(getter_AddRefs(bodyElement));
-        content = do_QueryInterface(bodyElement);
-      }
-      if (!content) {
-        nsCOMPtr<nsIDOMElement> docElement;
-        domDoc->GetDocumentElement(getter_AddRefs(docElement));
-        content = do_QueryInterface(docElement);
-      }
-    }
-    if (!content) {
-      return NS_ERROR_FAILURE;
-    }
-  }
 
-  nsCoreUtils::GetLanguageFor(content, nsnull, aLanguage);
+  if (IsDefunct())
+    return NS_ERROR_FAILURE;
+
+  nsCoreUtils::GetLanguageFor(mContent, nsnull, aLanguage);
 
   if (aLanguage.IsEmpty()) { // Nothing found, so use document's language
-    nsIDocument *doc = content->GetOwnerDoc();
+    nsIDocument *doc = mContent->GetOwnerDoc();
     if (doc) {
       doc->GetHeaderData(nsAccessibilityAtoms::headerContentLanguage, aLanguage);
     }
   }
  
   return NS_OK;
 }
-
-////////////////////////////////////////////////////////////////////////////////
-// nsAccessNode protected
-
-nsDocAccessible*
-nsAccessNode::GetDocAccessible() const
-{
-  return nsAccUtils::GetDocAccessibleFor(mWeakShell);
-}
--- a/accessible/src/base/nsAccessNode.h
+++ b/accessible/src/base/nsAccessNode.h
@@ -47,134 +47,153 @@
 #include "nsIAccessibleTypes.h"
 
 #include "a11yGeneric.h"
 
 #include "nsIContent.h"
 #include "nsIDOMNode.h"
 #include "nsINameSpaceManager.h"
 #include "nsIStringBundle.h"
-#include "nsRefPtrHashtable.h"
 #include "nsWeakReference.h"
 
 class nsAccessNode;
 class nsApplicationAccessible;
 class nsDocAccessible;
 class nsIAccessibleDocument;
 class nsRootAccessible;
 
 class nsIPresShell;
 class nsPresContext;
 class nsIFrame;
 class nsIDocShellTreeItem;
 
-typedef nsRefPtrHashtable<nsVoidPtrHashKey, nsAccessNode>
-  nsAccessNodeHashtable;
-
 #define ACCESSIBLE_BUNDLE_URL "chrome://global-platform/locale/accessible.properties"
 #define PLATFORM_KEYS_BUNDLE_URL "chrome://global-platform/locale/platformKeys.properties"
 
 #define NS_ACCESSNODE_IMPL_CID                          \
 {  /* 2b07e3d7-00b3-4379-aa0b-ea22e2c8ffda */           \
   0x2b07e3d7,                                           \
   0x00b3,                                               \
   0x4379,                                               \
   { 0xaa, 0x0b, 0xea, 0x22, 0xe2, 0xc8, 0xff, 0xda }    \
 }
 
 class nsAccessNode: public nsIAccessNode
 {
-  public: // construction, destruction
-    nsAccessNode(nsIDOMNode *, nsIWeakReference* aShell);
-    virtual ~nsAccessNode();
+public:
+
+  nsAccessNode(nsIContent *aContent, nsIWeakReference *aShell);
+  virtual ~nsAccessNode();
 
     NS_DECL_CYCLE_COLLECTING_ISUPPORTS
     NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsAccessNode, nsIAccessNode)
 
     NS_DECL_NSIACCESSNODE
     NS_DECLARE_STATIC_IID_ACCESSOR(NS_ACCESSNODE_IMPL_CID)
 
     static void InitXPAccessibility();
     static void ShutdownXPAccessibility();
 
   /**
    * Return an application accessible.
    */
   static nsApplicationAccessible* GetApplicationAccessible();
 
   /**
-   * Return the document accessible for this accesnode.
+   * Return the document accessible for this access node.
    */
-  nsDocAccessible* GetDocAccessible() const;
+  nsDocAccessible *GetDocAccessible() const;
 
   /**
    * Return the root document accessible for this accessnode.
    */
   already_AddRefed<nsRootAccessible> GetRootAccessible();
 
-    static nsIDOMNode *gLastFocusedNode;
+  /**
+   * Reference to a node of focused accessible.
+   */
+  static nsINode *gLastFocusedNode;
 
-    already_AddRefed<nsIDOMNode> GetCurrentFocus();
+  /**
+   * Return focused node within accessible window.
+   *
+   * XXX: it shouldn't break us if we return focused node not depending on
+   * window so that we can turn this method into util method.
+   */
+  already_AddRefed<nsINode> GetCurrentFocus();
 
     /**
      * Returns true when the accessible is defunct.
      */
     virtual PRBool IsDefunct();
 
-    /**
-     * Initialize the access node object, add it to the cache.
-     */
-    virtual nsresult Init();
+  /**
+   * Initialize the access node object, add it to the cache.
+   */
+  virtual PRBool Init();
 
-    /**
-     * Shutdown the access node object.
-     */
-    virtual nsresult Shutdown();
+  /**
+   * Shutdown the access node object.
+   */
+  virtual void Shutdown();
 
     /**
      * Return frame for the given access node object.
      */
     virtual nsIFrame* GetFrame();
 
   /**
    * Return DOM node associated with this accessible.
    */
-  nsIDOMNode *GetDOMNode() const { return mDOMNode; }
+  already_AddRefed<nsIDOMNode> GetDOMNode() const
+  {
+    nsIDOMNode *DOMNode = nsnull;
+    if (GetNode())
+      CallQueryInterface(GetNode(), &DOMNode);
+    return DOMNode;
+  }
+
+  /**
+   * Return DOM node associated with the accessible.
+   */
+  virtual nsINode* GetNode() const { return mContent; }
+  nsIContent* GetContent() const { return mContent; }
+  nsIDocument* GetDocumentNode() const
+    { return mContent ? mContent->GetOwnerDoc() : nsnull; }
+
+  /**
+   * Return node type information of DOM node associated with the accessible.
+   */
+  PRBool IsContent() const
+  {
+    return GetNode() && GetNode()->IsNodeOfType(nsINode::eCONTENT);
+  }
+  PRBool IsDocument() const
+  {
+    return GetNode() && GetNode()->IsNodeOfType(nsINode::eDOCUMENT);
+  }
 
   /**
    * Return the corresponding press shell for this accessible.
    */
   already_AddRefed<nsIPresShell> GetPresShell();
 
   /**
    * Return true if the accessible still has presentation shell. Light-weight
    * version of IsDefunct() method.
    */
   PRBool HasWeakShell() const { return !!mWeakShell; }
 
-#ifdef DEBUG
-  /**
-   * Return true if the access node is cached.
-   */
-  PRBool IsInCache();
-#endif
-
 protected:
-    nsresult MakeAccessNode(nsIDOMNode *aNode, nsIAccessNode **aAccessNode);
-
     nsPresContext* GetPresContext();
 
     void LastRelease();
 
-    nsCOMPtr<nsIDOMNode> mDOMNode;
-    nsCOMPtr<nsIWeakReference> mWeakShell;
-
-#ifdef DEBUG_A11Y
-    PRBool mIsInitialized;
-#endif
+  nsCOMPtr<nsIContent> mContent;
+  nsCOMPtr<nsIWeakReference> mWeakShell;
 
     /**
      * Notify global nsIObserver's that a11y is getting init'd or shutdown
      */
     static void NotifyA11yInitOrShutdown(PRBool aIsInit);
 
     // Static data, we do our own refcounting for our static data
     static nsIStringBundle *gStringBundle;
--- a/accessible/src/base/nsAccessibilityAtomList.h
+++ b/accessible/src/base/nsAccessibilityAtomList.h
@@ -52,24 +52,28 @@
   The first argument to ACCESSIBILITY_ATOM is the C++ identifier of the atom
   The second argument is the string value of the atom
 
  ******/
 
 
   // Alphabetical list of generic atoms
 ACCESSIBILITY_ATOM(button, "button")
+ACCESSIBILITY_ATOM(checkbox, "checkbox")
 ACCESSIBILITY_ATOM(col, "col")
 ACCESSIBILITY_ATOM(_empty, "")
 ACCESSIBILITY_ATOM(_false, "false")
 ACCESSIBILITY_ATOM(image, "image")
 ACCESSIBILITY_ATOM(menu, "menu")
 ACCESSIBILITY_ATOM(menuButton, "menu-button")
 ACCESSIBILITY_ATOM(menugenerated, "menugenerated")
+ACCESSIBILITY_ATOM(multiple, "multiple")
+ACCESSIBILITY_ATOM(open, "open")
 ACCESSIBILITY_ATOM(password, "password")
+ACCESSIBILITY_ATOM(radio, "radio")
 ACCESSIBILITY_ATOM(reset, "reset")
 ACCESSIBILITY_ATOM(row, "row")
 ACCESSIBILITY_ATOM(submit, "submit")
 ACCESSIBILITY_ATOM(_true, "true")
 ACCESSIBILITY_ATOM(_undefined, "undefined")
 
   // Header info
 ACCESSIBILITY_ATOM(headerContentLanguage, "content-language")
@@ -117,16 +121,17 @@ ACCESSIBILITY_ATOM(h6, "h6")
 ACCESSIBILITY_ATOM(item, "item") // XForms
 ACCESSIBILITY_ATOM(itemset, "itemset") // XForms
 ACCESSIBILITY_ATOM(img, "img")
 ACCESSIBILITY_ATOM(input, "input")
 ACCESSIBILITY_ATOM(label, "label")
 ACCESSIBILITY_ATOM(legend, "legend")
 ACCESSIBILITY_ATOM(li, "li")
 ACCESSIBILITY_ATOM(link, "link")
+ACCESSIBILITY_ATOM(listcell, "listcell") // XUL
 ACCESSIBILITY_ATOM(listcols, "listcols") // XUL
 ACCESSIBILITY_ATOM(listcol, "listcol") // XUL
 ACCESSIBILITY_ATOM(listhead, "listhead") // XUL
 ACCESSIBILITY_ATOM(listheader, "listheader") // XUL
 ACCESSIBILITY_ATOM(map, "map")
 ACCESSIBILITY_ATOM(math, "math")
 ACCESSIBILITY_ATOM(menupopup, "menupopup")     // XUL
 ACCESSIBILITY_ATOM(object, "object")
@@ -156,44 +161,48 @@ ACCESSIBILITY_ATOM(tr, "tr")
 ACCESSIBILITY_ATOM(tree, "tree")
 ACCESSIBILITY_ATOM(ul, "ul")
 
   // Alphabetical list of attributes (DOM)
 ACCESSIBILITY_ATOM(acceltext, "acceltext")
 ACCESSIBILITY_ATOM(accesskey, "accesskey")
 ACCESSIBILITY_ATOM(alt, "alt")
 ACCESSIBILITY_ATOM(anonid, "anonid") // Used for ID's in XBL
+ACCESSIBILITY_ATOM(checked, "checked")
 ACCESSIBILITY_ATOM(contenteditable, "contenteditable")
 ACCESSIBILITY_ATOM(control, "control")
 ACCESSIBILITY_ATOM(disabled, "disabled")
 ACCESSIBILITY_ATOM(_class, "class")
 ACCESSIBILITY_ATOM(cycles, "cycles") // used for XUL cycler attribute
 ACCESSIBILITY_ATOM(curpos, "curpos") // XUL
 ACCESSIBILITY_ATOM(data, "data")
 ACCESSIBILITY_ATOM(_default, "default") // XUL button
 ACCESSIBILITY_ATOM(draggable, "draggable")
 ACCESSIBILITY_ATOM(droppable, "droppable")   // XUL combo box
 ACCESSIBILITY_ATOM(editable, "editable")
 ACCESSIBILITY_ATOM(_for, "for")
 ACCESSIBILITY_ATOM(headers, "headers")   // HTML table
 ACCESSIBILITY_ATOM(hidden, "hidden")   // XUL tree columns
+ACCESSIBILITY_ATOM(hover, "hover") // XUL color picker
 ACCESSIBILITY_ATOM(href, "href") // XUL, XLink
 ACCESSIBILITY_ATOM(increment, "increment") // XUL
 ACCESSIBILITY_ATOM(lang, "lang")
 ACCESSIBILITY_ATOM(linkedPanel, "linkedpanel") // XUL
 ACCESSIBILITY_ATOM(longDesc, "longdesc")
 ACCESSIBILITY_ATOM(max, "max") // XUL
 ACCESSIBILITY_ATOM(maxpos, "maxpos") // XUL
 ACCESSIBILITY_ATOM(minpos, "minpos") // XUL
+ACCESSIBILITY_ATOM(_moz_menuactive, "_moz-menuactive") // XUL
 ACCESSIBILITY_ATOM(multiline, "multiline") // XUL
 ACCESSIBILITY_ATOM(name, "name")
 ACCESSIBILITY_ATOM(onclick, "onclick")
 ACCESSIBILITY_ATOM(popup, "popup")
 ACCESSIBILITY_ATOM(readonly, "readonly")
 ACCESSIBILITY_ATOM(scope, "scope") // HTML table
+ACCESSIBILITY_ATOM(seltype, "seltype") // XUL listbox
 ACCESSIBILITY_ATOM(simple, "simple") // XLink
 ACCESSIBILITY_ATOM(src, "src")
 ACCESSIBILITY_ATOM(selected, "selected")
 ACCESSIBILITY_ATOM(summary, "summary")
 ACCESSIBILITY_ATOM(tabindex, "tabindex")
 ACCESSIBILITY_ATOM(title, "title")
 ACCESSIBILITY_ATOM(toolbarname, "toolbarname")
 ACCESSIBILITY_ATOM(tooltiptext, "tooltiptext")
--- a/accessible/src/base/nsAccessibilityService.cpp
+++ b/accessible/src/base/nsAccessibilityService.cpp
@@ -59,32 +59,25 @@
 #include "nsIDOMDocument.h"
 #include "nsIDOMHTMLAreaElement.h"
 #include "nsIDOMHTMLLegendElement.h"
 #include "nsIDOMHTMLObjectElement.h"
 #include "nsIDOMHTMLOptGroupElement.h"
 #include "nsIDOMHTMLOptionElement.h"
 #include "nsIDOMXULElement.h"
 #include "nsIHTMLDocument.h"
-#include "nsIDocShell.h"
-#include "nsIFrame.h"
 #include "nsIImageFrame.h"
 #include "nsILink.h"
-#include "nsINameSpaceManager.h"
 #include "nsIObserverService.h"
 #include "nsIPluginInstance.h"
-#include "nsIPresShell.h"
 #include "nsISupportsUtils.h"
 #include "nsObjectFrame.h"
 #include "nsOuterDocAccessible.h"
 #include "nsRootAccessibleWrap.h"
 #include "nsTextFragment.h"
-#include "nsServiceManagerUtils.h"
-#include "nsUnicharUtils.h"
-#include "nsNetError.h"
 #include "mozilla/Services.h"
 
 #ifdef MOZ_XUL
 #include "nsXULAlertAccessible.h"
 #include "nsXULColorPickerAccessible.h"
 #include "nsXULComboboxAccessible.h"
 #include "nsXULFormControlAccessible.h"
 #include "nsXULListboxAccessibleWrap.h"
@@ -150,31 +143,30 @@ nsAccessibilityService::Observe(nsISuppo
 // nsIAccessibilityService
 void
 nsAccessibilityService::NotifyOfAnchorJumpTo(nsIContent *aTarget)
 {
   nsIDocument *document = aTarget->GetCurrentDoc();
   if (!document)
     return;
 
-  nsCOMPtr<nsIDOMNode> targetNode(do_QueryInterface(aTarget));
-
+  nsINode *targetNode = aTarget;
   nsAccessible *targetAcc = GetAccessible(targetNode);
 
   // Getting the targetAcc above will have ensured accessible doc creation.
   // XXX Bug 561683
   nsDocAccessible *docAccessible = GetDocAccessible(document);
   if (!docAccessible)
     return;
 
   // If the jump target is not accessible then fire an event for nearest
   // accessible in parent chain.
   if (!targetAcc) {
     targetAcc = GetContainerAccessible(targetNode, PR_TRUE);
-    targetNode = targetAcc->GetDOMNode();
+    targetNode = targetAcc->GetNode();
   }
 
   NS_ASSERTION(targetNode,
       "No accessible in parent chain!? Expect at least a document accessible.");
   if (!targetNode)
     return;
 
   // XXX note in rare cases the node could go away before we flush the queue,
@@ -184,288 +176,274 @@ nsAccessibilityService::NotifyOfAnchorJu
                                targetNode);
 }
 
 // nsIAccessibilityService
 nsresult
 nsAccessibilityService::FireAccessibleEvent(PRUint32 aEvent,
                                             nsIAccessible *aTarget)
 {
-  nsEventShell::FireEvent(aEvent, aTarget);
+  nsRefPtr<nsAccessible> accessible(do_QueryObject(aTarget));
+  nsEventShell::FireEvent(aEvent, accessible);
   return NS_OK;
 }
 
 // nsAccessibilityService private
 nsresult
-nsAccessibilityService::GetInfo(nsIFrame* aFrame, nsIWeakReference** aShell, nsIDOMNode** aNode)
+nsAccessibilityService::GetInfo(nsIFrame *aFrame, nsIWeakReference **aShell,
+                                nsIContent **aContent)
 {
   NS_ASSERTION(aFrame,"Error -- 1st argument (aFrame) is null!!");
   if (!aFrame) {
     return NS_ERROR_FAILURE;
   }
-  nsCOMPtr<nsIContent> content = aFrame->GetContent();
-  nsCOMPtr<nsIDOMNode> node(do_QueryInterface(content));
-  if (!content || !node)
+  nsIContent* content = aFrame->GetContent();
+  if (!content)
     return NS_ERROR_FAILURE;
 
-  *aNode = node;
-  NS_IF_ADDREF(*aNode);
-
-  nsCOMPtr<nsIDocument> document = content->GetDocument();
+  nsIDocument* document = content->GetOwnerDoc();
   if (!document)
     return NS_ERROR_FAILURE;
 
   NS_ASSERTION(document->GetPrimaryShell(),"Error no shells!");
 
   // do_GetWR only works into a |nsCOMPtr| :-(
   nsCOMPtr<nsIWeakReference> weakShell =
     do_GetWeakReference(document->GetPrimaryShell());
-  NS_IF_ADDREF(*aShell = weakShell);
 
-  return NS_OK;
-}
-
-// nsAccessibilityService public
-nsresult
-nsAccessibilityService::GetShellFromNode(nsIDOMNode *aNode, nsIWeakReference **aWeakShell)
-{
-  nsCOMPtr<nsIDOMDocument> domDoc;
-  aNode->GetOwnerDocument(getter_AddRefs(domDoc));
-  nsCOMPtr<nsIDocument> doc(do_QueryInterface(domDoc));
-  if (!doc)
-    return NS_ERROR_INVALID_ARG;
-
-  // ---- Get the pres shell ----
-  nsIPresShell *shell = doc->GetPrimaryShell();
-  if (!shell)
-    return NS_ERROR_FAILURE;
-
-  nsCOMPtr<nsIWeakReference> weakRef(do_GetWeakReference(shell));
-  
-  *aWeakShell = weakRef;
-  NS_IF_ADDREF(*aWeakShell);
+  weakShell.forget(aShell);
+  NS_IF_ADDREF(*aContent = content);
 
   return NS_OK;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsIAccessibilityService
 
 nsresult
 nsAccessibilityService::CreateOuterDocAccessible(nsIDOMNode* aDOMNode, 
                                                  nsIAccessible **aOuterDocAccessible)
 {
   NS_ENSURE_ARG_POINTER(aDOMNode);
   
   *aOuterDocAccessible = nsnull;
 
-  nsCOMPtr<nsIWeakReference> outerWeakShell;
-  GetShellFromNode(aDOMNode, getter_AddRefs(outerWeakShell));
+  nsCOMPtr<nsIContent> content(do_QueryInterface(aDOMNode));
+  nsCOMPtr<nsIWeakReference> outerWeakShell =
+    nsCoreUtils::GetWeakShellFor(content);
   NS_ENSURE_TRUE(outerWeakShell, NS_ERROR_FAILURE);
 
   nsOuterDocAccessible *outerDocAccessible =
-    new nsOuterDocAccessible(aDOMNode, outerWeakShell);
+    new nsOuterDocAccessible(content, outerWeakShell);
   NS_ENSURE_TRUE(outerDocAccessible, NS_ERROR_FAILURE);
 
   NS_ADDREF(*aOuterDocAccessible = outerDocAccessible);
 
   return NS_OK;
 }
 
  /**
    * HTML widget creation
    */
 nsresult
-nsAccessibilityService::CreateHTML4ButtonAccessible(nsIFrame *aFrame, nsIAccessible **_retval)
+nsAccessibilityService::CreateHTML4ButtonAccessible(nsIFrame *aFrame,
+                                                    nsIAccessible **aAccessible)
 {
-  nsCOMPtr<nsIDOMNode> node;
+  nsCOMPtr<nsIContent> content;
   nsCOMPtr<nsIWeakReference> weakShell;
-  nsresult rv = GetInfo(aFrame, getter_AddRefs(weakShell), getter_AddRefs(node));
+  nsresult rv = GetInfo(aFrame, getter_AddRefs(weakShell),
+                        getter_AddRefs(content));
   if (NS_FAILED(rv))
     return rv;
 
-  *_retval = new nsHTML4ButtonAccessible(node, weakShell);
-  if (! *_retval) 
+  *aAccessible = new nsHTML4ButtonAccessible(content, weakShell);
+  if (!*aAccessible)
     return NS_ERROR_OUT_OF_MEMORY;
 
-  NS_ADDREF(*_retval);
+  NS_ADDREF(*aAccessible);
   return NS_OK;
 }
 
 nsresult
-nsAccessibilityService::CreateHTMLButtonAccessible(nsIFrame *aFrame, nsIAccessible **_retval)
+nsAccessibilityService::CreateHTMLButtonAccessible(nsIFrame *aFrame,
+                                                   nsIAccessible **aAccessible)
 {
-  nsCOMPtr<nsIDOMNode> node;
+  nsCOMPtr<nsIContent> content;
   nsCOMPtr<nsIWeakReference> weakShell;
-  nsresult rv = GetInfo(aFrame, getter_AddRefs(weakShell), getter_AddRefs(node));
+  nsresult rv = GetInfo(aFrame, getter_AddRefs(weakShell),
+                        getter_AddRefs(content));
   if (NS_FAILED(rv))
     return rv;
 
-  *_retval = new nsHTMLButtonAccessible(node, weakShell);
-  if (! *_retval) 
+  *aAccessible = new nsHTMLButtonAccessible(content, weakShell);
+  if (!*aAccessible)
     return NS_ERROR_OUT_OF_MEMORY;
 
-  NS_ADDREF(*_retval);
+  NS_ADDREF(*aAccessible);
   return NS_OK;
 }
 
 // nsAccessibilityService private
 already_AddRefed<nsAccessible>
 nsAccessibilityService::CreateHTMLAccessibleByMarkup(nsIFrame *aFrame,
                                                      nsIWeakReference *aWeakShell,
-                                                     nsIDOMNode *aNode)
+                                                     nsINode *aNode)
 {
   // This method assumes we're in an HTML namespace.
   nsRefPtr<nsAccessible> accessible;
 
   nsCOMPtr<nsIContent> content(do_QueryInterface(aNode));
   nsIAtom *tag = content->Tag();
   if (tag == nsAccessibilityAtoms::legend) {
-    accessible = new nsHTMLLegendAccessible(aNode, aWeakShell);
+    accessible = new nsHTMLLegendAccessible(content, aWeakShell);
   }
   else if (tag == nsAccessibilityAtoms::option) {
-    accessible = new nsHTMLSelectOptionAccessible(aNode, aWeakShell);
+    accessible = new nsHTMLSelectOptionAccessible(content, aWeakShell);
   }
   else if (tag == nsAccessibilityAtoms::optgroup) {
-    accessible = new nsHTMLSelectOptGroupAccessible(aNode, aWeakShell);
+    accessible = new nsHTMLSelectOptGroupAccessible(content, aWeakShell);
   }
   else if (tag == nsAccessibilityAtoms::ul || tag == nsAccessibilityAtoms::ol ||
            tag == nsAccessibilityAtoms::dl) {
-    accessible = new nsHTMLListAccessible(aNode, aWeakShell);
+    accessible = new nsHTMLListAccessible(content, aWeakShell);
   }
   else if (tag == nsAccessibilityAtoms::a) {
 
     // Only some roles truly enjoy life as nsHTMLLinkAccessibles, for details
     // see closed bug 494807.
     nsRoleMapEntry *roleMapEntry = nsAccUtils::GetRoleMapEntry(aNode);
     if (roleMapEntry && roleMapEntry->role != nsIAccessibleRole::ROLE_NOTHING
         && roleMapEntry->role != nsIAccessibleRole::ROLE_LINK) {
 
-      accessible = new nsHyperTextAccessibleWrap(aNode, aWeakShell);
+      accessible = new nsHyperTextAccessibleWrap(content, aWeakShell);
     } else {
-      accessible = new nsHTMLLinkAccessible(aNode, aWeakShell);
+      accessible = new nsHTMLLinkAccessible(content, aWeakShell);
     }
   }
   else if (tag == nsAccessibilityAtoms::dt ||
            (tag == nsAccessibilityAtoms::li && 
             aFrame->GetType() != nsAccessibilityAtoms::blockFrame)) {
     // Normally for li, it is created by the list item frame (in nsBlockFrame)
     // which knows about the bullet frame; however, in this case the list item
     // must have been styled using display: foo
-    accessible = new nsHTMLLIAccessible(aNode, aWeakShell, EmptyString());
+    accessible = new nsHTMLLIAccessible(content, aWeakShell, EmptyString());
   }
   else if (tag == nsAccessibilityAtoms::abbr ||
            tag == nsAccessibilityAtoms::acronym ||
            tag == nsAccessibilityAtoms::blockquote ||
            tag == nsAccessibilityAtoms::dd ||
            tag == nsAccessibilityAtoms::form ||
            tag == nsAccessibilityAtoms::h1 ||
            tag == nsAccessibilityAtoms::h2 ||
            tag == nsAccessibilityAtoms::h3 ||
            tag == nsAccessibilityAtoms::h4 ||
            tag == nsAccessibilityAtoms::h5 ||
            tag == nsAccessibilityAtoms::h6 ||
            tag == nsAccessibilityAtoms::q) {
 
-    accessible = new nsHyperTextAccessibleWrap(aNode, aWeakShell);
+    accessible = new nsHyperTextAccessibleWrap(content, aWeakShell);
   }
   else if (tag == nsAccessibilityAtoms::tr) {
-    accessible = new nsEnumRoleAccessible(aNode, aWeakShell,
-                                            nsIAccessibleRole::ROLE_ROW);
+    accessible = new nsEnumRoleAccessible(content, aWeakShell,
+                                          nsIAccessibleRole::ROLE_ROW);
   }
   else if (nsCoreUtils::IsHTMLTableHeader(content)) {
-    accessible = new nsHTMLTableHeaderCellAccessibleWrap(aNode, aWeakShell);
+    accessible = new nsHTMLTableHeaderCellAccessibleWrap(content, aWeakShell);
   }
 
   return accessible.forget();
 }
 
 nsresult
 nsAccessibilityService::CreateHTMLLIAccessible(nsIFrame *aFrame, 
                                                nsIFrame *aBulletFrame,
                                                const nsAString& aBulletText,
-                                               nsIAccessible **_retval)
+                                               nsIAccessible **aAccessible)
 {
-  nsCOMPtr<nsIDOMNode> node;
+  nsCOMPtr<nsIContent> content;
   nsCOMPtr<nsIWeakReference> weakShell;
-  nsresult rv = GetInfo(aFrame, getter_AddRefs(weakShell), getter_AddRefs(node));
+  nsresult rv = GetInfo(aFrame, getter_AddRefs(weakShell),
+                        getter_AddRefs(content));
   if (NS_FAILED(rv))
     return rv;
 
-  *_retval = new nsHTMLLIAccessible(node, weakShell, aBulletText);
-  if (! *_retval) 
+  *aAccessible = new nsHTMLLIAccessible(content, weakShell, aBulletText);
+  if (!*aAccessible)
     return NS_ERROR_OUT_OF_MEMORY;
 
-  NS_ADDREF(*_retval);
-  return NS_OK;
-}
-
-nsresult
-nsAccessibilityService::CreateHyperTextAccessible(nsIFrame *aFrame, nsIAccessible **aAccessible)
-{
-  nsCOMPtr<nsIDOMNode> node;
-  nsCOMPtr<nsIWeakReference> weakShell;
-  nsresult rv = GetInfo(aFrame, getter_AddRefs(weakShell), getter_AddRefs(node));
-  if (NS_FAILED(rv))
-    return rv;
-
-  nsCOMPtr<nsIContent> content(do_QueryInterface(node));
-  NS_ENSURE_TRUE(content, NS_ERROR_FAILURE);
-  
-  *aAccessible = new nsHyperTextAccessibleWrap(node, weakShell);
-  NS_ENSURE_TRUE(*aAccessible, NS_ERROR_OUT_OF_MEMORY);
-
   NS_ADDREF(*aAccessible);
   return NS_OK;
 }
 
 nsresult
-nsAccessibilityService::CreateHTMLCheckboxAccessible(nsIFrame *aFrame, nsIAccessible **_retval)
+nsAccessibilityService::CreateHyperTextAccessible(nsIFrame *aFrame,
+                                                  nsIAccessible **aAccessible)
 {
-  nsCOMPtr<nsIDOMNode> node;
+  nsCOMPtr<nsIContent> content;
   nsCOMPtr<nsIWeakReference> weakShell;
-  nsresult rv = GetInfo(aFrame, getter_AddRefs(weakShell), getter_AddRefs(node));
+  nsresult rv = GetInfo(aFrame, getter_AddRefs(weakShell),
+                        getter_AddRefs(content));
   if (NS_FAILED(rv))
     return rv;
 
-  *_retval = new nsHTMLCheckboxAccessible(node, weakShell);
-  if (! *_retval) 
+  *aAccessible = new nsHyperTextAccessibleWrap(content, weakShell);
+  if (!*aAccessible)
     return NS_ERROR_OUT_OF_MEMORY;
 
-  NS_ADDREF(*_retval);
+  NS_ADDREF(*aAccessible);
   return NS_OK;
 }
 
 nsresult
-nsAccessibilityService::CreateHTMLComboboxAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aPresShell, nsIAccessible **_retval)
+nsAccessibilityService::CreateHTMLCheckboxAccessible(nsIFrame *aFrame,
+                                                     nsIAccessible **aAccessible)
 {
-  *_retval = new nsHTMLComboboxAccessible(aDOMNode, aPresShell);
-  if (! *_retval)
+  nsCOMPtr<nsIContent> content;
+  nsCOMPtr<nsIWeakReference> weakShell;
+  nsresult rv = GetInfo(aFrame, getter_AddRefs(weakShell),
+                        getter_AddRefs(content));
+  if (NS_FAILED(rv))
+    return rv;
+
+  *aAccessible = new nsHTMLCheckboxAccessible(content, weakShell);
+  if (!*aAccessible)
     return NS_ERROR_OUT_OF_MEMORY;
 
-  NS_ADDREF(*_retval);
+  NS_ADDREF(*aAccessible);
+  return NS_OK;
+}
+
+nsresult
+nsAccessibilityService::CreateHTMLComboboxAccessible(nsIDOMNode *aDOMNode,
+                                                     nsIWeakReference *aPresShell,
+                                                     nsIAccessible **aAccessible)
+{
+  nsCOMPtr<nsIContent> content(do_QueryInterface(aDOMNode));
+  *aAccessible = new nsHTMLComboboxAccessible(content, aPresShell);
+  if (!*aAccessible)
+    return NS_ERROR_OUT_OF_MEMORY;
+
+  NS_ADDREF(*aAccessible);
   return NS_OK;
 }
 
 nsresult
 nsAccessibilityService::CreateHTMLImageAccessible(nsIFrame *aFrame,
                                                   nsIAccessible **aAccessible)
 {
   NS_ENSURE_ARG_POINTER(aAccessible);
   *aAccessible = nsnull;
 
-  nsCOMPtr<nsIDOMNode> node;
+  nsCOMPtr<nsIContent> content;
   nsCOMPtr<nsIWeakReference> weakShell;
-  nsresult rv = GetInfo(aFrame, getter_AddRefs(weakShell), getter_AddRefs(node));
+  nsresult rv = GetInfo(aFrame, getter_AddRefs(weakShell),
+                        getter_AddRefs(content));
   if (NS_FAILED(rv))
     return rv;
 
-  nsCOMPtr<nsIContent> content = do_QueryInterface(node);
-  NS_ENSURE_STATE(content);
-
   nsCOMPtr<nsIHTMLDocument> htmlDoc =
     do_QueryInterface(content->GetCurrentDoc());
 
   nsCOMPtr<nsIDOMHTMLMapElement> mapElm;
   if (htmlDoc) {
     nsAutoString mapElmName;
     content->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::usemap,
                      mapElmName);
@@ -473,75 +451,80 @@ nsAccessibilityService::CreateHTMLImageA
     if (!mapElmName.IsEmpty()) {
       if (mapElmName.CharAt(0) == '#')
         mapElmName.Cut(0,1);
       mapElm = htmlDoc->GetImageMap(mapElmName);
     }
   }
 
   if (mapElm)
-    *aAccessible = new nsHTMLImageMapAccessible(node, weakShell, mapElm);
+    *aAccessible = new nsHTMLImageMapAccessible(content, weakShell, mapElm);
   else
-    *aAccessible = new nsHTMLImageAccessibleWrap(node, weakShell);
+    *aAccessible = new nsHTMLImageAccessibleWrap(content, weakShell);
 
   if (!*aAccessible)
     return NS_ERROR_OUT_OF_MEMORY;
 
   NS_ADDREF(*aAccessible);
   return NS_OK;
 }
 
 nsresult
 nsAccessibilityService::CreateHTMLGenericAccessible(nsIFrame *aFrame, nsIAccessible **aAccessible)
 {
   return CreateHyperTextAccessible(aFrame, aAccessible);
 }
 
 nsresult
-nsAccessibilityService::CreateHTMLGroupboxAccessible(nsIFrame *aFrame, nsIAccessible **_retval)
+nsAccessibilityService::CreateHTMLGroupboxAccessible(nsIFrame *aFrame,
+                                                     nsIAccessible **aAccessible)
 {
-  nsCOMPtr<nsIDOMNode> node;
+  nsCOMPtr<nsIContent> content;
   nsCOMPtr<nsIWeakReference> weakShell;
-  nsresult rv = GetInfo(aFrame, getter_AddRefs(weakShell), getter_AddRefs(node));
+  nsresult rv = GetInfo(aFrame, getter_AddRefs(weakShell),
+                        getter_AddRefs(content));
   if (NS_FAILED(rv))
     return rv;
 
-  *_retval = new nsHTMLGroupboxAccessible(node, weakShell);
-  if (! *_retval) 
+  *aAccessible = new nsHTMLGroupboxAccessible(content, weakShell);
+  if (!*aAccessible)
     return NS_ERROR_OUT_OF_MEMORY;
 
-  NS_ADDREF(*_retval);
+  NS_ADDREF(*aAccessible);
   return NS_OK;
 }
 
 nsresult
-nsAccessibilityService::CreateHTMLListboxAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aPresShell, nsIAccessible **_retval)
+nsAccessibilityService::CreateHTMLListboxAccessible(nsIDOMNode* aDOMNode,
+                                                    nsIWeakReference *aPresShell,
+                                                    nsIAccessible **aAccessible)
 {
-  *_retval = new nsHTMLSelectListAccessible(aDOMNode, aPresShell);
-  if (! *_retval) 
+  nsCOMPtr<nsIContent> content(do_QueryInterface(aDOMNode));
+  *aAccessible = new nsHTMLSelectListAccessible(content, aPresShell);
+  if (!*aAccessible)
     return NS_ERROR_OUT_OF_MEMORY;
 
-  NS_ADDREF(*_retval);
+  NS_ADDREF(*aAccessible);
   return NS_OK;
 }
 
 nsresult
 nsAccessibilityService::CreateHTMLMediaAccessible(nsIFrame *aFrame,
                                                   nsIAccessible **aAccessible)
 {
   NS_ENSURE_ARG_POINTER(aAccessible);
   *aAccessible = nsnull;
 
-  nsCOMPtr<nsIDOMNode> node;
+  nsCOMPtr<nsIContent> content;
   nsCOMPtr<nsIWeakReference> weakShell;
   nsresult rv = GetInfo(aFrame, getter_AddRefs(weakShell),
-                        getter_AddRefs(node));
+                        getter_AddRefs(content));
   NS_ENSURE_SUCCESS(rv, rv);
 
-  *aAccessible = new nsEnumRoleAccessible(node, weakShell,
+  *aAccessible = new nsEnumRoleAccessible(content, weakShell,
                                           nsIAccessibleRole::ROLE_GROUPING);
   NS_ENSURE_TRUE(*aAccessible, NS_ERROR_OUT_OF_MEMORY);
 
   NS_ADDREF(*aAccessible);
   return NS_OK;
 }
 
 /**
@@ -552,45 +535,48 @@ nsAccessibilityService::CreateHTMLMediaA
   *     have to go to the plugin to get the accessible content
   *  3) An image or imagemap, where the image frame points back to 
   *     the object element DOMNode
   */
 nsresult
 nsAccessibilityService::CreateHTMLObjectFrameAccessible(nsObjectFrame *aFrame,
                                                         nsIAccessible **aAccessible)
 {
-  nsCOMPtr<nsIDOMNode> node;
+  NS_ENSURE_ARG_POINTER(aAccessible);
+  *aAccessible = nsnull;
+
+  nsCOMPtr<nsIContent> content;
   nsCOMPtr<nsIWeakReference> weakShell;
-  GetInfo(aFrame, getter_AddRefs(weakShell), getter_AddRefs(node));
+  GetInfo(aFrame, getter_AddRefs(weakShell), getter_AddRefs(content));
 
-  *aAccessible = nsnull;
   if (aFrame->GetRect().IsEmpty()) {
     return NS_ERROR_FAILURE;
   }
   // 1) for object elements containing either HTML or TXT documents
-  nsCOMPtr<nsIDOMDocument> domDoc;
-  nsCOMPtr<nsIDOMHTMLObjectElement> obj(do_QueryInterface(node));
-  if (obj)
+  nsCOMPtr<nsIDOMHTMLObjectElement> obj(do_QueryInterface(content));
+  if (obj) {
+    nsCOMPtr<nsIDOMDocument> domDoc;
     obj->GetContentDocument(getter_AddRefs(domDoc));
-  else
-    domDoc = do_QueryInterface(node);
-  if (domDoc)
-    return CreateOuterDocAccessible(node, aAccessible);
+    if (domDoc) {
+      nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(content));
+      return CreateOuterDocAccessible(DOMNode, aAccessible);
+    }
+  }
 
 #ifdef XP_WIN
   // 2) for plugins
   nsCOMPtr<nsIPluginInstance> pluginInstance ;
   aFrame->GetPluginInstance(*getter_AddRefs(pluginInstance));
   if (pluginInstance) {
     // Note: pluginPort will be null if windowless.
     HWND pluginPort = nsnull;
     aFrame->GetPluginPort(&pluginPort);
 
     *aAccessible =
-      new nsHTMLWin32ObjectOwnerAccessible(node, weakShell, pluginPort);
+      new nsHTMLWin32ObjectOwnerAccessible(content, weakShell, pluginPort);
     NS_ENSURE_TRUE(*aAccessible, NS_ERROR_OUT_OF_MEMORY);
 
     NS_ADDREF(*aAccessible);
     return NS_OK;
   }
 #endif
 
   // 3) for images and imagemaps, or anything else with a child frame
@@ -598,209 +584,285 @@ nsAccessibilityService::CreateHTMLObject
   nsIFrame *frame = aFrame->GetFirstChild(nsnull);
   if (frame)
     return frame->GetAccessible(aAccessible);
 
   return NS_OK;
 }
 
 nsresult
-nsAccessibilityService::CreateHTMLRadioButtonAccessible(nsIFrame *aFrame, nsIAccessible **_retval)
+nsAccessibilityService::CreateHTMLRadioButtonAccessible(nsIFrame *aFrame,
+                                                        nsIAccessible **aAccessible)
 {
-  nsCOMPtr<nsIDOMNode> node;
+  nsCOMPtr<nsIContent> content;
   nsCOMPtr<nsIWeakReference> weakShell;
-  nsresult rv = GetInfo(aFrame, getter_AddRefs(weakShell), getter_AddRefs(node));
+  nsresult rv = GetInfo(aFrame, getter_AddRefs(weakShell),
+                        getter_AddRefs(content));
   if (NS_FAILED(rv))
     return rv;
 
-  *_retval = new nsHTMLRadioButtonAccessible(node, weakShell);
-  if (! *_retval) 
+  *aAccessible = new nsHTMLRadioButtonAccessible(content, weakShell);
+  if (!*aAccessible)
     return NS_ERROR_OUT_OF_MEMORY;
 
-  NS_ADDREF(*_retval);
+  NS_ADDREF(*aAccessible);
   return NS_OK;
 }
 
 nsresult
-nsAccessibilityService::CreateHTMLSelectOptionAccessible(nsIDOMNode* aDOMNode, 
+nsAccessibilityService::CreateHTMLSelectOptionAccessible(nsIDOMNode *aDOMNode,
                                                          nsIAccessible *aParent, 
-                                                         nsIWeakReference* aPresShell, 
-                                                         nsIAccessible **_retval)
+                                                         nsIWeakReference *aPresShell,
+                                                         nsIAccessible **aAccessible)
 {
-  *_retval = new nsHTMLSelectOptionAccessible(aDOMNode, aPresShell);
-  if (! *_retval) 
+  nsCOMPtr<nsIContent> content(do_QueryInterface(aDOMNode));
+  *aAccessible = new nsHTMLSelectOptionAccessible(content, aPresShell);
+  if (!*aAccessible)
     return NS_ERROR_OUT_OF_MEMORY;
 
-  NS_ADDREF(*_retval);
+  NS_ADDREF(*aAccessible);
   return NS_OK;
 }
 
 nsresult
-nsAccessibilityService::CreateHTMLTableAccessible(nsIFrame *aFrame, nsIAccessible **_retval)
+nsAccessibilityService::CreateHTMLTableAccessible(nsIFrame *aFrame,
+                                                  nsIAccessible **aAccessible)
 {
-  nsCOMPtr<nsIDOMNode> node;
+  nsCOMPtr<nsIContent> content;
   nsCOMPtr<nsIWeakReference> weakShell;
-  nsresult rv = GetInfo(aFrame, getter_AddRefs(weakShell), getter_AddRefs(node));
+  nsresult rv = GetInfo(aFrame, getter_AddRefs(weakShell),
+                        getter_AddRefs(content));
   if (NS_FAILED(rv))
     return rv;
 
-  *_retval = new nsHTMLTableAccessibleWrap(node, weakShell);
-  if (! *_retval) 
+  *aAccessible = new nsHTMLTableAccessibleWrap(content, weakShell);
+  if (!*aAccessible)
     return NS_ERROR_OUT_OF_MEMORY;
 
-  NS_ADDREF(*_retval);
+  NS_ADDREF(*aAccessible);
   return NS_OK;
 }
 
 nsresult
 nsAccessibilityService::CreateHTMLTableCellAccessible(nsIFrame *aFrame,
                                                       nsIAccessible **aAccessible)
 {
-  nsCOMPtr<nsIDOMNode> node;
+  NS_ENSURE_ARG_POINTER(aAccessible);
+  *aAccessible = nsnull;
+
+  nsCOMPtr<nsIContent> content;
   nsCOMPtr<nsIWeakReference> weakShell;
-  nsresult rv = GetInfo(aFrame, getter_AddRefs(weakShell), getter_AddRefs(node));
+  nsresult rv = GetInfo(aFrame, getter_AddRefs(weakShell),
+                        getter_AddRefs(content));
   if (NS_FAILED(rv))
     return rv;
 
-  *aAccessible = new nsHTMLTableCellAccessibleWrap(node, weakShell);
-  if (!*aAccessible) 
+  *aAccessible = new nsHTMLTableCellAccessibleWrap(content, weakShell);
+  if (!*aAccessible)
+    return NS_ERROR_OUT_OF_MEMORY;
+
+  NS_ADDREF(*aAccessible);
+  return NS_OK;
+}
+
+nsresult
+nsAccessibilityService::CreateHTMLTextAccessible(nsIFrame *aFrame,
+                                                 nsIAccessible **aAccessible)
+{
+  *aAccessible = nsnull;
+
+  nsCOMPtr<nsIContent> content;
+  nsCOMPtr<nsIWeakReference> weakShell;
+  nsresult rv = GetInfo(aFrame, getter_AddRefs(weakShell),
+                        getter_AddRefs(content));
+  if (NS_FAILED(rv))
+    return rv;
+
+  // XXX Don't create ATK objects for these
+  *aAccessible = new nsHTMLTextAccessible(content, weakShell);
+  if (!*aAccessible)
     return NS_ERROR_OUT_OF_MEMORY;
 
   NS_ADDREF(*aAccessible);
   return NS_OK;
 }
 
 nsresult
-nsAccessibilityService::CreateHTMLTextAccessible(nsIFrame *aFrame, nsIAccessible **_retval)
+nsAccessibilityService::CreateHTMLTextFieldAccessible(nsIFrame *aFrame,
+                                                      nsIAccessible **aAccessible)
 {
-  *_retval = nsnull;
-
-  nsCOMPtr<nsIDOMNode> node;
+  nsCOMPtr<nsIContent> content;
   nsCOMPtr<nsIWeakReference> weakShell;
-  nsresult rv = GetInfo(aFrame, getter_AddRefs(weakShell), getter_AddRefs(node));
+  nsresult rv = GetInfo(aFrame, getter_AddRefs(weakShell),
+                        getter_AddRefs(content));
   if (NS_FAILED(rv))
     return rv;
 
-  // XXX Don't create ATK objects for these
-  *_retval = new nsHTMLTextAccessible(node, weakShell);
-  if (! *_retval) 
+  *aAccessible = new nsHTMLTextFieldAccessible(content, weakShell);
+  if (!*aAccessible)
     return NS_ERROR_OUT_OF_MEMORY;
 
-  NS_ADDREF(*_retval);
+  NS_ADDREF(*aAccessible);
   return NS_OK;
 }
 
 nsresult
-nsAccessibilityService::CreateHTMLTextFieldAccessible(nsIFrame *aFrame, nsIAccessible **_retval)
+nsAccessibilityService::CreateHTMLLabelAccessible(nsIFrame *aFrame,
+                                                  nsIAccessible **aAccessible)
 {
-  nsCOMPtr<nsIDOMNode> node;
+  nsCOMPtr<nsIContent> content;
   nsCOMPtr<nsIWeakReference> weakShell;
-  nsresult rv = GetInfo(aFrame, getter_AddRefs(weakShell), getter_AddRefs(node));
+  nsresult rv = GetInfo(aFrame, getter_AddRefs(weakShell),
+                        getter_AddRefs(content));
   if (NS_FAILED(rv))
     return rv;
 
-  *_retval = new nsHTMLTextFieldAccessible(node, weakShell);
-  if (! *_retval) 
+  *aAccessible = new nsHTMLLabelAccessible(content, weakShell);
+  if (!*aAccessible)
     return NS_ERROR_OUT_OF_MEMORY;
 
-  NS_ADDREF(*_retval);
+  NS_ADDREF(*aAccessible);
   return NS_OK;
 }
 
 nsresult
-nsAccessibilityService::CreateHTMLLabelAccessible(nsIFrame *aFrame, nsIAccessible **_retval)
+nsAccessibilityService::CreateHTMLHRAccessible(nsIFrame *aFrame,
+                                               nsIAccessible **aAccessible)
 {
-  nsCOMPtr<nsIDOMNode> node;
+  nsCOMPtr<nsIContent> content;
   nsCOMPtr<nsIWeakReference> weakShell;
-  nsresult rv = GetInfo(aFrame, getter_AddRefs(weakShell), getter_AddRefs(node));
+  nsresult rv = GetInfo(aFrame, getter_AddRefs(weakShell),
+                        getter_AddRefs(content));
   if (NS_FAILED(rv))
     return rv;
 
-  *_retval = new nsHTMLLabelAccessible(node, weakShell);
-  if (! *_retval) 
+  *aAccessible = new nsHTMLHRAccessible(content, weakShell);
+  if (!*aAccessible)
     return NS_ERROR_OUT_OF_MEMORY;
 
-  NS_ADDREF(*_retval);
+  NS_ADDREF(*aAccessible);
   return NS_OK;
 }
 
 nsresult
-nsAccessibilityService::CreateHTMLHRAccessible(nsIFrame *aFrame, nsIAccessible **_retval)
+nsAccessibilityService::CreateHTMLBRAccessible(nsIFrame *aFrame,
+                                               nsIAccessible **aAccessible)
 {
-  nsCOMPtr<nsIDOMNode> node;
+  nsCOMPtr<nsIContent> content;
   nsCOMPtr<nsIWeakReference> weakShell;
-  nsresult rv = GetInfo(aFrame, getter_AddRefs(weakShell), getter_AddRefs(node));
+  nsresult rv = GetInfo(aFrame, getter_AddRefs(weakShell),
+                        getter_AddRefs(content));
   if (NS_FAILED(rv))
     return rv;
 
-  *_retval = new nsHTMLHRAccessible(node, weakShell);
-  if (! *_retval) 
+  *aAccessible = new nsHTMLBRAccessible(content, weakShell);
+  if (!*aAccessible)
     return NS_ERROR_OUT_OF_MEMORY;
 
-  NS_ADDREF(*_retval);
+  NS_ADDREF(*aAccessible);
   return NS_OK;
 }
 
 nsresult
-nsAccessibilityService::CreateHTMLBRAccessible(nsIFrame *aFrame, nsIAccessible **_retval)
+nsAccessibilityService::CreateHTMLCaptionAccessible(nsIFrame *aFrame,
+                                                    nsIAccessible **aAccessible)
 {
-  nsCOMPtr<nsIDOMNode> node;
+  nsCOMPtr<nsIContent> content;
   nsCOMPtr<nsIWeakReference> weakShell;
-  nsresult rv = GetInfo(aFrame, getter_AddRefs(weakShell), getter_AddRefs(node));
+  nsresult rv = GetInfo(aFrame, getter_AddRefs(weakShell),
+                        getter_AddRefs(content));
   if (NS_FAILED(rv))
     return rv;
 
-  *_retval = new nsHTMLBRAccessible(node, weakShell);
-  if (! *_retval) 
+  *aAccessible = new nsHTMLCaptionAccessible(content, weakShell);
+  if (!*aAccessible)
     return NS_ERROR_OUT_OF_MEMORY;
 
-  NS_ADDREF(*_retval);
+  NS_ADDREF(*aAccessible);
   return NS_OK;
 }
 
-nsresult
-nsAccessibilityService::CreateHTMLCaptionAccessible(nsIFrame *aFrame, nsIAccessible **_retval)
+void
+nsAccessibilityService::PresShellDestroyed(nsIPresShell *aPresShell)
 {
-  nsCOMPtr<nsIDOMNode> node;
-  nsCOMPtr<nsIWeakReference> weakShell;
-  nsresult rv = GetInfo(aFrame, getter_AddRefs(weakShell), getter_AddRefs(node));
-  if (NS_FAILED(rv))
-    return rv;
+  // Presshell destruction will automatically destroy shells for descendant
+  // documents, so no need to worry about those. Just shut down the accessible
+  // for this one document. That keeps us from having bad behavior in case of
+  // deep bushy subtrees.
+  // When document subtree containing iframe is hidden then we don't get
+  // pagehide event for the iframe's underlying document and its presshell is
+  // destroyed before we're notified styles were changed. Shutdown the document
+  // accessible early.
+  nsIDocument* doc = aPresShell->GetDocument();
+  if (!doc)
+    return;
 
-  *_retval = new nsHTMLCaptionAccessible(node, weakShell);
-  if (! *_retval) 
-    return NS_ERROR_OUT_OF_MEMORY;
-
-  NS_ADDREF(*_retval);
-  return NS_OK;
+  NS_LOG_ACCDOCDESTROY("presshell destroyed", doc)
+  ShutdownDocAccessible(doc);
 }
 
-// nsAccessibilityService public
-nsAccessNode*
-nsAccessibilityService::GetCachedAccessNode(nsIDOMNode *aNode, 
+// nsAccessibilityService protected
+nsAccessible *
+nsAccessibilityService::GetCachedAccessible(nsINode *aNode,
                                             nsIWeakReference *aWeakShell)
 {
-  nsDocAccessible *docAccessible = nsAccUtils::GetDocAccessibleFor(aWeakShell);
+  nsDocAccessible *docAccessible = GetDocAccessible(aNode->GetOwnerDoc());
   return docAccessible ?
-    docAccessible->GetCachedAccessNode(static_cast<void*>(aNode)) : nsnull;
+    docAccessible->GetCachedAccessible(static_cast<void*>(aNode)) : nsnull;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsIAccessibleRetrieval
 
 NS_IMETHODIMP
 nsAccessibilityService::GetApplicationAccessible(nsIAccessible **aAccessibleApplication)
 {
   NS_ENSURE_ARG_POINTER(aAccessibleApplication);
 
   NS_IF_ADDREF(*aAccessibleApplication = nsAccessNode::GetApplicationAccessible());
   return NS_OK;
 }
 
 NS_IMETHODIMP
+nsAccessibilityService::GetAccessibleFor(nsIDOMNode *aNode,
+                                         nsIAccessible **aAccessible)
+{
+  NS_ENSURE_ARG_POINTER(aAccessible);
+
+  nsCOMPtr<nsINode> node(do_QueryInterface(aNode));
+  NS_IF_ADDREF(*aAccessible = GetAccessible(node));
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsAccessibilityService::GetAttachedAccessibleFor(nsIDOMNode *aDOMNode,
+                                                 nsIAccessible **aAccessible)
+{
+  NS_ENSURE_ARG(aDOMNode);
+  NS_ENSURE_ARG_POINTER(aAccessible);
+
+  nsCOMPtr<nsINode> node(do_QueryInterface(aDOMNode));
+  NS_IF_ADDREF(*aAccessible = GetAttachedAccessibleFor(node));
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsAccessibilityService::GetRelevantContentNodeFor(nsIDOMNode *aNode,
+                                                  nsIDOMNode **aRelevantNode)
+{
+  NS_ENSURE_ARG(aNode);
+  NS_ENSURE_ARG_POINTER(aRelevantNode);
+
+  nsCOMPtr<nsINode> node(do_QueryInterface(aNode));
+  nsINode *relevantNode = GetRelevantContentNodeFor(node);
+  CallQueryInterface(relevantNode, aRelevantNode);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
 nsAccessibilityService::GetStringRole(PRUint32 aRole, nsAString& aString)
 {
   if ( aRole >= NS_ARRAY_LENGTH(kRoleNames)) {
     aString.AssignLiteral("unknown");
     return NS_OK;
   }
 
   CopyUTF8toUTF16(kRoleNames[aRole], aString);
@@ -949,150 +1011,141 @@ nsAccessibilityService::GetStringRelatio
     aString.AssignLiteral("unknown");
     return NS_OK;
   }
 
   CopyUTF8toUTF16(kRelationTypeNames[aRelationType], aString);
   return NS_OK;
 }
 
-
-/**
-  * GetAccessibleFor - get an nsIAccessible from a DOM node
-  */
-
 NS_IMETHODIMP
-nsAccessibilityService::GetAccessibleFor(nsIDOMNode *aNode,
-                                         nsIAccessible **aAccessible)
+nsAccessibilityService::GetAccessibleFromCache(nsIDOMNode* aNode,
+                                               nsIAccessible** aAccessible)
 {
   NS_ENSURE_ARG_POINTER(aAccessible);
 
-  NS_IF_ADDREF(*aAccessible = GetAccessible(aNode));
+  // Search for an accessible in each of our per document accessible object
+  // caches. If we don't find it, and the given node is itself a document, check
+  // our cache of document accessibles (document cache). Note usually shutdown
+  // document accessibles are not stored in the document cache, however an
+  // "unofficially" shutdown document (i.e. not from nsAccDocManager) can still
+  // exist in the document cache.
+  nsCOMPtr<nsINode> node(do_QueryInterface(aNode));
+  nsAccessible* accessible = FindAccessibleInCache(static_cast<void*>(node));
+  if (!accessible) {
+    nsCOMPtr<nsIDocument> document(do_QueryInterface(node));
+    if (document)
+      accessible = GetDocAccessibleFromCache(document);
+  }
+
+  NS_IF_ADDREF(*aAccessible = accessible);
   return NS_OK;
 }
 
-NS_IMETHODIMP
-nsAccessibilityService::GetAttachedAccessibleFor(nsIDOMNode *aNode,
-                                                 nsIAccessible **aAccessible)
-{
-  NS_ENSURE_ARG(aNode);
-  NS_ENSURE_ARG_POINTER(aAccessible);
-
-  *aAccessible = nsnull;
-
-  nsCOMPtr<nsIDOMNode> relevantNode;
-  nsresult rv = GetRelevantContentNodeFor(aNode, getter_AddRefs(relevantNode));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  if (relevantNode != aNode)
-    return NS_OK;
-
-  return GetAccessibleFor(aNode, aAccessible);
-}
-
+// nsIAccesibilityService
 nsAccessible*
 nsAccessibilityService::GetAccessibleInShell(nsIDOMNode *aNode, 
                                              nsIPresShell *aPresShell) 
 {
   if (!aNode || !aPresShell)
     return nsnull;
 
+  nsCOMPtr<nsINode> node(do_QueryInterface(aNode));
   nsCOMPtr<nsIWeakReference> weakShell(do_GetWeakReference(aPresShell));
   nsRefPtr<nsAccessible> accessible =
-    GetAccessible(aNode, aPresShell, weakShell);
+    GetAccessible(node, aPresShell, weakShell);
   return accessible;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccessibilityService public
 
 nsAccessible *
-nsAccessibilityService::GetAccessible(nsIDOMNode *aNode)
+nsAccessibilityService::GetAccessible(nsINode *aNode)
 {
   if (!aNode)
     return nsnull;
 
   nsIPresShell *presShell = nsCoreUtils::GetPresShellFor(aNode);
   if (!presShell)
     return nsnull;
 
   nsCOMPtr<nsIWeakReference> weakShell(do_GetWeakReference(presShell));
   nsRefPtr<nsAccessible> accessible = GetAccessible(aNode, presShell,
                                                     weakShell);
   return accessible;
 }
 
 nsAccessible *
-nsAccessibilityService::GetAccessibleInWeakShell(nsIDOMNode *aNode, 
+nsAccessibilityService::GetAccessibleInWeakShell(nsINode *aNode,
                                                  nsIWeakReference *aWeakShell) 
 {
   if (!aNode || !aWeakShell)
     return nsnull;
 
   nsCOMPtr<nsIPresShell> presShell(do_QueryReferent(aWeakShell));
   nsRefPtr<nsAccessible> accessible = GetAccessible(aNode, presShell,
                                                     aWeakShell);
   return accessible;
 }
 
 nsAccessible *
-nsAccessibilityService::GetContainerAccessible(nsIDOMNode *aNode,
+nsAccessibilityService::GetContainerAccessible(nsINode *aNode,
                                                PRBool aCanCreate)
 {
   if (!aNode)
     return nsnull;
 
-  nsCOMPtr<nsINode> currNode(do_QueryInterface(aNode));
-  nsIDocument *document = currNode->GetCurrentDoc();
+  nsIDocument *document = aNode->GetCurrentDoc();
   if (!document)
     return nsnull;
 
   nsIPresShell *presShell = document->GetPrimaryShell();
   if (!presShell)
     return nsnull;
 
+  nsINode *currNode = aNode;
   nsCOMPtr<nsIWeakReference> weakShell(do_GetWeakReference(presShell));
 
   nsAccessible *accessible = nsnull;
   while (!accessible && (currNode = currNode->GetNodeParent())) {
-    nsCOMPtr<nsIDOMNode> currDOMNode(do_QueryInterface(currNode));
-
-    nsCOMPtr<nsIDOMNode> relevantDOMNode;
-    GetAccService()->GetRelevantContentNodeFor(currDOMNode,
-                                               getter_AddRefs(relevantDOMNode));
-    if (relevantDOMNode) {
-      currNode = do_QueryInterface(relevantDOMNode);
-      currDOMNode.swap(relevantDOMNode);
-    }
+    currNode = GetAccService()->GetRelevantContentNodeFor(currNode);
 
     if (aCanCreate) {
-      accessible =
-        GetAccService()->GetAccessibleInWeakShell(currDOMNode, weakShell);
+      accessible = GetAccService()->GetAccessibleInWeakShell(currNode,
+                                                             weakShell);
 
     } else {
       // Only return cached accessible, don't create anything.
-      nsRefPtr<nsAccessible> cachedAcc =
-        do_QueryObject(GetCachedAccessNode(currDOMNode, weakShell));
-
-      accessible = cachedAcc;
+      accessible = GetCachedAccessible(currNode, weakShell);
     }
   }
 
   return accessible;
 }
 
+nsAccessible *
+nsAccessibilityService::GetAttachedAccessibleFor(nsINode *aNode)
+{
+  nsINode *relevantNode = GetRelevantContentNodeFor(aNode);
+  if (relevantNode != aNode)
+    return nsnull;
+
+  return GetAccessible(relevantNode);
+}
+
 PRBool
 nsAccessibilityService::InitAccessible(nsAccessible *aAccessible,
                                        nsRoleMapEntry *aRoleMapEntry)
 {
   if (!aAccessible)
     return PR_FALSE;
 
-  nsresult rv = aAccessible->Init(); // Add to cache, etc.
-  if (NS_FAILED(rv)) {
+  // Add to cache an accessible, etc.
+  if (!aAccessible->Init()) {
     NS_ERROR("Failed to initialize an accessible!");
 
     aAccessible->Shutdown();
     return PR_FALSE;
   }
 
   NS_ASSERTION(aAccessible->IsInCache(),
                "Initialized accessible not in the cache!");
@@ -1125,84 +1178,60 @@ static PRBool HasRelatedContent(nsIConte
       return PR_TRUE;
     }
   }
 
   return PR_FALSE;
 }
 
 already_AddRefed<nsAccessible>
-nsAccessibilityService::GetAccessible(nsIDOMNode *aNode,
+nsAccessibilityService::GetAccessible(nsINode *aNode,
                                       nsIPresShell *aPresShell,
                                       nsIWeakReference *aWeakShell,
                                       PRBool *aIsHidden)
 {
-  if (!aPresShell || !aWeakShell || gIsShutdown)
+  if (!aPresShell || !aWeakShell || !aNode || gIsShutdown)
     return nsnull;
 
-  NS_ASSERTION(aNode, "GetAccessible() called with no node.");
-
   if (aIsHidden)
     *aIsHidden = PR_FALSE;
 
-#ifdef DEBUG_A11Y
-  // Please leave this in for now, it's a convenient debugging method
-  nsAutoString name;
-  aNode->GetLocalName(name);
-  if (name.LowerCaseEqualsLiteral("h1")) 
-    printf("## aaronl debugging tag name\n");
-
-  nsAutoString attrib;
-  nsCOMPtr<nsIDOMElement> element(do_QueryInterface(aNode));
-  if (element) {
-    element->GetAttribute(NS_LITERAL_STRING("type"), attrib);
-    if (attrib.EqualsLiteral("statusbarpanel"))
-      printf("## aaronl debugging attribute\n");
-  }
-#endif
-
   // Check to see if we already have an accessible for this node in the cache.
-  nsAccessNode* cachedAccessNode = GetCachedAccessNode(aNode, aWeakShell);
-  if (cachedAccessNode) {
-    // XXX: the cache might contain the access node for the DOM node that is not
-    // accessible because of wrong cache update. In this case try to create new
-    // accessible.
-    nsRefPtr<nsAccessible> cachedAccessible = do_QueryObject(cachedAccessNode);
-
-    if (cachedAccessible)
-      return cachedAccessible.forget();
+  nsAccessible *cachedAccessible = GetCachedAccessible(aNode, aWeakShell);
+  if (cachedAccessible) {
+    NS_ADDREF(cachedAccessible);
+    return cachedAccessible;
   }
 
   // No cache entry, so we must create the accessible.
 
-  nsCOMPtr<nsIContent> content(do_QueryInterface(aNode));
-  if (!content) {
+  if (aNode->IsNodeOfType(nsINode::eDOCUMENT)) {
     // If it's document node then ask accessible document loader for
     // document accessible, otherwise return null.
     nsCOMPtr<nsIDocument> document(do_QueryInterface(aNode));
-    if (document) {
-      nsAccessible *accessible = GetDocAccessible(document);
-      NS_IF_ADDREF(accessible);
-      return accessible;
-    }
-
-    return nsnull;
+    nsAccessible *accessible = GetDocAccessible(document);
+    NS_IF_ADDREF(accessible);
+    return accessible;
   }
 
   // We have a content node.
-  if (!content->IsInDoc()) {
+  if (!aNode->IsInDoc()) {
     NS_WARNING("Creating accessible for node with no document");
     return nsnull;
   }
 
-  if (content->GetOwnerDoc() != aPresShell->GetDocument()) {
+  if (aNode->GetOwnerDoc() != aPresShell->GetDocument()) {
     NS_ERROR("Creating accessible for wrong pres shell");
     return nsnull;
   }
 
+  nsCOMPtr<nsIContent> content(do_QueryInterface(aNode));
+  if (!content)
+    return nsnull;
+
   // Frames can be deallocated when we flush layout, or when we call into code
   // that can flush layout, either directly, or via DOM manipulation, or some
   // CSS styles like :hover. We use the weak frame checks to avoid calling
   // methods on a dead frame pointer.
   nsWeakFrame weakFrame = content->GetPrimaryFrame();
 
   // Check frame to see if it is hidden.
   if (!weakFrame.GetFrame() ||
@@ -1266,17 +1295,17 @@ nsAccessibilityService::GetAccessible(ns
     content->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::name, name);
     if (!name.IsEmpty()) {
       if (aIsHidden)
         *aIsHidden = PR_TRUE;
 
       return nsnull;
     }
 
-    newAcc = new nsHyperTextAccessibleWrap(aNode, aWeakShell);
+    newAcc = new nsHyperTextAccessibleWrap(content, aWeakShell);
     if (InitAccessible(newAcc, nsAccUtils::GetRoleMapEntry(aNode)))
       return newAcc.forget();
     return nsnull;
   }
 
   nsRoleMapEntry *roleMapEntry = nsAccUtils::GetRoleMapEntry(aNode);
   if (roleMapEntry && !nsCRT::strcmp(roleMapEntry->roleString, "presentation") &&
       !content->IsFocusable()) { // For presentation only
@@ -1303,19 +1332,18 @@ nsAccessibilityService::GetAccessible(ns
       // accessibles
       nsIContent *tableContent = content;
       while ((tableContent = tableContent->GetParent()) != nsnull) {
         nsIFrame *tableFrame = tableContent->GetPrimaryFrame();
         if (!tableFrame)
           continue;
 
         if (tableFrame->GetType() == nsAccessibilityAtoms::tableOuterFrame) {
-          nsCOMPtr<nsIDOMNode> tableNode(do_QueryInterface(tableContent));
           nsAccessible *tableAccessible =
-            GetAccessibleInWeakShell(tableNode, aWeakShell);
+            GetAccessibleInWeakShell(tableContent, aWeakShell);
 
           if (tableAccessible) {
             if (!roleMapEntry) {
               PRUint32 role = nsAccUtils::Role(tableAccessible);
               if (role != nsIAccessibleRole::ROLE_TABLE &&
                   role != nsIAccessibleRole::ROLE_TREE_TABLE) {
                 // No ARIA role and not in table: override role. For example,
                 // <table role="label"><td>content</td></table>
@@ -1323,17 +1351,17 @@ nsAccessibilityService::GetAccessible(ns
               }
             }
 
             break;
           }
 
 #ifdef DEBUG
           nsRoleMapEntry *tableRoleMapEntry =
-            nsAccUtils::GetRoleMapEntry(tableNode);
+            nsAccUtils::GetRoleMapEntry(tableContent);
           NS_ASSERTION(tableRoleMapEntry &&
                        !nsCRT::strcmp(tableRoleMapEntry->roleString, "presentation"),
                        "No accessible for parent table and it didn't have role of presentation");
 #endif
 
           if (!roleMapEntry && !content->IsFocusable()) {
             // Table-related descendants of presentation table are also
             // presentation if they aren't focusable and have not explicit ARIA
@@ -1362,22 +1390,22 @@ nsAccessibilityService::GetAccessible(ns
     if (roleMapEntry) {
       // Create ARIA grid/treegrid accessibles if node is not of a child or
       // valid child of HTML table and is not a HTML table.
       if ((!partOfHTMLTable || !tryTagNameOrFrame) &&
           frameType != nsAccessibilityAtoms::tableOuterFrame) {
 
         if (roleMapEntry->role == nsIAccessibleRole::ROLE_TABLE ||
             roleMapEntry->role == nsIAccessibleRole::ROLE_TREE_TABLE) {
-          newAcc = new nsARIAGridAccessibleWrap(aNode, aWeakShell);
+          newAcc = new nsARIAGridAccessibleWrap(content, aWeakShell);
 
         } else if (roleMapEntry->role == nsIAccessibleRole::ROLE_GRID_CELL ||
             roleMapEntry->role == nsIAccessibleRole::ROLE_ROWHEADER ||
             roleMapEntry->role == nsIAccessibleRole::ROLE_COLUMNHEADER) {
-          newAcc = new nsARIAGridCellAccessibleWrap(aNode, aWeakShell);
+          newAcc = new nsARIAGridCellAccessibleWrap(content, aWeakShell);
         }
       }
     }
 
     if (!newAcc && tryTagNameOrFrame) {
       // Prefer to use markup (mostly tag name, perhaps attributes) to
       // decide if and what kind of accessible to create.
       // The method creates accessibles for table related content too therefore
@@ -1413,35 +1441,35 @@ nsAccessibilityService::GetAccessible(ns
         newAcc = do_QueryObject(newAccessible);
       }
     }
   }
 
   if (!newAcc) {
     // Elements may implement nsIAccessibleProvider via XBL. This allows them to
     // say what kind of accessible to create.
-    newAcc = CreateAccessibleByType(aNode, aWeakShell);
+    newAcc = CreateAccessibleByType(content, aWeakShell);
   }
 
   if (!newAcc) {
     // Create generic accessibles for SVG and MathML nodes.
     if (content->GetNameSpaceID() == kNameSpaceID_SVG &&
         content->Tag() == nsAccessibilityAtoms::svg) {
-      newAcc = new nsEnumRoleAccessible(aNode, aWeakShell,
+      newAcc = new nsEnumRoleAccessible(content, aWeakShell,
                                         nsIAccessibleRole::ROLE_DIAGRAM);
     }
     else if (content->GetNameSpaceID() == kNameSpaceID_MathML &&
              content->Tag() == nsAccessibilityAtoms::math) {
-      newAcc = new nsEnumRoleAccessible(aNode, aWeakShell,
+      newAcc = new nsEnumRoleAccessible(content, aWeakShell,
                                         nsIAccessibleRole::ROLE_EQUATION);
     }
   }
 
   if (!newAcc) {
-    newAcc = CreateAccessibleForDeckChild(weakFrame.GetFrame(), aNode,
+    newAcc = CreateAccessibleForDeckChild(weakFrame.GetFrame(), content,
                                           aWeakShell);
   }
 
   // If no accessible, see if we need to create a generic accessible because
   // of some property that makes this object interesting
   // We don't do this for <body>, <html>, <window>, <dialog> etc. which 
   // correspond to the doc accessible and will be created in any case
   if (!newAcc && content->Tag() != nsAccessibilityAtoms::body && content->GetParent() && 
@@ -1449,21 +1477,21 @@ nsAccessibilityService::GetAccessible(ns
        (isHTML && nsCoreUtils::HasClickListener(content)) ||
        HasUniversalAriaProperty(content) || roleMapEntry ||
        HasRelatedContent(content) || nsCoreUtils::IsXLink(content))) {
     // This content is focusable or has an interesting dynamic content accessibility property.
     // If it's interesting we need it in the accessibility hierarchy so that events or
     // other accessibles can point to it, or so that it can hold a state, etc.
     if (isHTML) {
       // Interesting HTML container which may have selectable text and/or embedded objects
-      newAcc = new nsHyperTextAccessibleWrap(aNode, aWeakShell);
+      newAcc = new nsHyperTextAccessibleWrap(content, aWeakShell);
     }
     else {  // XUL, SVG, MathML etc.
       // Interesting generic non-HTML container
-      newAcc = new nsAccessibleWrap(aNode, aWeakShell);
+      newAcc = new nsAccessibleWrap(content, aWeakShell);
     }
   }
 
   if (InitAccessible(newAcc, roleMapEntry))
     return newAcc.forget();
   return nsnull;
 }
 
@@ -1534,20 +1562,18 @@ nsAccessibilityService::HasUniversalAria
          nsAccUtils::HasDefinedARIAToken(aContent, nsAccessibilityAtoms::aria_invalid) ||
          aContent->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_label) ||
          aContent->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_labelledby) ||
          nsAccUtils::HasDefinedARIAToken(aContent, nsAccessibilityAtoms::aria_live) ||
          nsAccUtils::HasDefinedARIAToken(aContent, nsAccessibilityAtoms::aria_owns) ||
          nsAccUtils::HasDefinedARIAToken(aContent, nsAccessibilityAtoms::aria_relevant);
 }
 
-// nsIAccessibleRetrieval
-NS_IMETHODIMP
-nsAccessibilityService::GetRelevantContentNodeFor(nsIDOMNode *aNode,
-                                                  nsIDOMNode **aRelevantNode)
+nsINode *
+nsAccessibilityService::GetRelevantContentNodeFor(nsINode *aNode)
 {
   // The method returns node that is relevant for attached accessible check.
   // Sometimes element that is XBL widget hasn't accessible children in
   // anonymous content. This method check whether given node can be accessible
   // by looking through all nested bindings that given node is anonymous for. If
   // there is XBL widget that deniedes to be accessible for given node then the
   // method returns that XBL widget otherwise it returns given node.
 
@@ -1558,337 +1584,315 @@ nsAccessibilityService::GetRelevantConte
   // 2. xul:texbox has html:input in anonymous content. When given node is
   // html:input elmement then we return xul:textbox since xul:textbox doesn't
   // allow accessible nodes in anonymous content.
   // 3. xforms:input that is hosted in xul document contains xul:textbox
   // element. When given node is html:input or xul:textbox then we return
   // xforms:input element since xforms:input hasn't accessible anonymous
   // children.
 
-  NS_ENSURE_ARG(aNode);
-  NS_ENSURE_ARG_POINTER(aRelevantNode);
+  if (!aNode)
+    return nsnull;
 
   nsCOMPtr<nsIContent> content(do_QueryInterface(aNode));
   if (content) {
     // Build stack of binding parents so we can walk it in reverse.
     nsIContent *bindingParent;
     nsCOMArray<nsIContent> bindingsStack;
 
     for (bindingParent = content->GetBindingParent(); bindingParent != nsnull &&
          bindingParent != bindingParent->GetBindingParent();
          bindingParent = bindingParent->GetBindingParent()) {
       bindingsStack.AppendObject(bindingParent);
     }
 
     PRInt32 bindingsCount = bindingsStack.Count();
     for (PRInt32 index = bindingsCount - 1; index >= 0 ; index--) {
       bindingParent = bindingsStack[index];
-      nsCOMPtr<nsIDOMNode> bindingNode(do_QueryInterface(bindingParent));
-      if (bindingNode) {
-        // Try to get an accessible by type since XBL widget can be accessible
-        // only if it implements nsIAccessibleProvider interface.
-        nsCOMPtr<nsIWeakReference> weakShell;
-        GetShellFromNode(bindingNode, getter_AddRefs(weakShell));
+
+      // Try to get an accessible by type since XBL widget can be accessible
+      // only if it implements nsIAccessibleProvider interface.
+      nsCOMPtr<nsIWeakReference> weakShell =
+        nsCoreUtils::GetWeakShellFor(bindingParent);
 
-        // XXX: it's a hack we should try the cache before, otherwise to cache
-        // the accessible.
-        nsRefPtr<nsAccessible> accessible =
-          CreateAccessibleByType(bindingNode, weakShell);
+      // XXX: it's a hack we should try the cache before, otherwise to cache
+      // the accessible.
+      nsRefPtr<nsAccessible> accessible =
+        CreateAccessibleByType(bindingParent, weakShell);
 
-        if (accessible) {
-          if (!accessible->GetAllowsAnonChildAccessibles()) {
-            NS_ADDREF(*aRelevantNode = bindingNode);
-            return NS_OK;
-          }
-        }
+      if (accessible) {
+        if (!accessible->GetAllowsAnonChildAccessibles())
+          return bindingParent;
       }
     }
   }
 
-  NS_ADDREF(*aRelevantNode = aNode);
-  return NS_OK;
+  return aNode;
 }
 
 already_AddRefed<nsAccessible>
 nsAccessibilityService::GetAreaAccessible(nsIFrame *aImageFrame,
-                                          nsIDOMNode *aAreaNode,
+                                          nsINode *aAreaNode,
                                           nsIWeakReference *aWeakShell)
 {
   // Check if frame is an image frame, and content is <area>.
   nsIImageFrame *imageFrame = do_QueryFrame(aImageFrame);
   if (!imageFrame)
     return nsnull;
 
   nsCOMPtr<nsIDOMHTMLAreaElement> areaElmt = do_QueryInterface(aAreaNode);
   if (!areaElmt)
     return nsnull;
 
   // Try to get image map accessible from the global cache or create it
   // if failed.
-  nsRefPtr<nsAccessible> imageAcc;
-
-  nsCOMPtr<nsIDOMNode> imageNode(do_QueryInterface(aImageFrame->GetContent()));
-  nsAccessNode *cachedImgAcc = GetCachedAccessNode(imageNode, aWeakShell);
-  if (cachedImgAcc)
-    imageAcc = do_QueryObject(cachedImgAcc);
-
+  nsRefPtr<nsAccessible> imageAcc =
+    GetCachedAccessible(aImageFrame->GetContent(), aWeakShell);
   if (!imageAcc) {
     nsCOMPtr<nsIAccessible> imageAccessible;
     CreateHTMLImageAccessible(aImageFrame,
                               getter_AddRefs(imageAccessible));
 
     imageAcc = do_QueryObject(imageAccessible);
     if (!InitAccessible(imageAcc, nsnull))
       return nsnull;
   }
 
   // Make sure <area> accessible children of the image map are cached so
   // that they should be available in global cache.
   imageAcc->EnsureChildren();
 
-  nsAccessNode *cachedAreaAcc = GetCachedAccessNode(aAreaNode, aWeakShell);
-  if (!cachedAreaAcc)
-    return nsnull;
-
-  nsRefPtr<nsAccessible> areaAcc = do_QueryObject(cachedAreaAcc);
-  return areaAcc.forget();
+  nsAccessible *cachedAreaAcc = GetCachedAccessible(aAreaNode, aWeakShell);
+  NS_IF_ADDREF(cachedAreaAcc);
+  return cachedAreaAcc;
 }
 
 already_AddRefed<nsAccessible>
-nsAccessibilityService::CreateAccessibleByType(nsIDOMNode *aNode,
+nsAccessibilityService::CreateAccessibleByType(nsIContent *aContent,
                                                nsIWeakReference *aWeakShell)
 {
-  nsCOMPtr<nsIAccessibleProvider> accessibleProvider(do_QueryInterface(aNode));
+  nsCOMPtr<nsIAccessibleProvider> accessibleProvider(do_QueryInterface(aContent));
   if (!accessibleProvider)
     return nsnull;
 
   PRInt32 type;
   nsresult rv = accessibleProvider->GetAccessibleType(&type);
   if (NS_FAILED(rv))
     return nsnull;
 
   nsRefPtr<nsAccessible> accessible;
   if (type == nsIAccessibleProvider::OuterDoc) {
-    accessible = new nsOuterDocAccessible(aNode, aWeakShell);
+    accessible = new nsOuterDocAccessible(aContent, aWeakShell);
     return accessible.forget();
   }
 
   switch (type)
   {
 #ifdef MOZ_XUL
     case nsIAccessibleProvider::NoAccessible:
       return nsnull;
 
     // XUL controls
     case nsIAccessibleProvider::XULAlert:
-      accessible = new nsXULAlertAccessible(aNode, aWeakShell);
+      accessible = new nsXULAlertAccessible(aContent, aWeakShell);
       break;
     case nsIAccessibleProvider::XULButton:
-      accessible = new nsXULButtonAccessible(aNode, aWeakShell);
+      accessible = new nsXULButtonAccessible(aContent, aWeakShell);
       break;
     case nsIAccessibleProvider::XULCheckbox:
-      accessible = new nsXULCheckboxAccessible(aNode, aWeakShell);
+      accessible = new nsXULCheckboxAccessible(aContent, aWeakShell);
       break;
     case nsIAccessibleProvider::XULColorPicker:
-      accessible = new nsXULColorPickerAccessible(aNode, aWeakShell);
+      accessible = new nsXULColorPickerAccessible(aContent, aWeakShell);
       break;
     case nsIAccessibleProvider::XULColorPickerTile:
-      accessible = new nsXULColorPickerTileAccessible(aNode, aWeakShell);
+      accessible = new nsXULColorPickerTileAccessible(aContent, aWeakShell);
       break;
     case nsIAccessibleProvider::XULCombobox:
-      accessible = new nsXULComboboxAccessible(aNode, aWeakShell);
+      accessible = new nsXULComboboxAccessible(aContent, aWeakShell);
       break;
     case nsIAccessibleProvider::XULDropmarker:
-      accessible = new nsXULDropmarkerAccessible(aNode, aWeakShell);
+      accessible = new nsXULDropmarkerAccessible(aContent, aWeakShell);
       break;
     case nsIAccessibleProvider::XULGroupbox:
-      accessible = new nsXULGroupboxAccessible(aNode, aWeakShell);
+      accessible = new nsXULGroupboxAccessible(aContent, aWeakShell);
       break;
     case nsIAccessibleProvider::XULImage:
     {
-      // Don't include nameless images in accessible tree
-      nsCOMPtr<nsIDOMElement> elt(do_QueryInterface(aNode));
-      if (!elt)
+      // Don't include nameless images in accessible tree.
+      if (!aContent->HasAttr(kNameSpaceID_None,
+                             nsAccessibilityAtoms::tooltiptext))
         return nsnull;
 
-      PRBool hasTextEquivalent;
-      // Prefer value over tooltiptext
-      elt->HasAttribute(NS_LITERAL_STRING("tooltiptext"), &hasTextEquivalent);
-      if (!hasTextEquivalent)
-        return nsnull;
-
-      accessible = new nsHTMLImageAccessibleWrap(aNode, aWeakShell);
+      accessible = new nsHTMLImageAccessibleWrap(aContent, aWeakShell);
       break;
     }
     case nsIAccessibleProvider::XULLink:
-      accessible = new nsXULLinkAccessible(aNode, aWeakShell);
+      accessible = new nsXULLinkAccessible(aContent, aWeakShell);
       break;
     case nsIAccessibleProvider::XULListbox:
-      accessible = new nsXULListboxAccessibleWrap(aNode, aWeakShell);
+      accessible = new nsXULListboxAccessibleWrap(aContent, aWeakShell);
       break;
     case nsIAccessibleProvider::XULListCell:
-      accessible = new nsXULListCellAccessibleWrap(aNode, aWeakShell);
+      accessible = new nsXULListCellAccessibleWrap(aContent, aWeakShell);
       break;
     case nsIAccessibleProvider::XULListHead:
-      accessible = new nsXULColumnsAccessible(aNode, aWeakShell);
+      accessible = new nsXULColumnsAccessible(aContent, aWeakShell);
       break;
     case nsIAccessibleProvider::XULListHeader:
-      accessible = new nsXULColumnItemAccessible(aNode, aWeakShell);
+      accessible = new nsXULColumnItemAccessible(aContent, aWeakShell);
       break;
     case nsIAccessibleProvider::XULListitem:
-      accessible = new nsXULListitemAccessible(aNode, aWeakShell);
+      accessible = new nsXULListitemAccessible(aContent, aWeakShell);
       break;
     case nsIAccessibleProvider::XULMenubar:
-      accessible = new nsXULMenubarAccessible(aNode, aWeakShell);
+      accessible = new nsXULMenubarAccessible(aContent, aWeakShell);
       break;
     case nsIAccessibleProvider::XULMenuitem:
-      accessible = new nsXULMenuitemAccessibleWrap(aNode, aWeakShell);
+      accessible = new nsXULMenuitemAccessibleWrap(aContent, aWeakShell);
       break;
     case nsIAccessibleProvider::XULMenupopup:
     {
 #ifdef MOZ_ACCESSIBILITY_ATK
       // ATK considers this node to be redundant when within menubars, and it makes menu
       // navigation with assistive technologies more difficult
       // XXX In the future we will should this for consistency across the nsIAccessible
       // implementations on each platform for a consistent scripting environment, but
       // then strip out redundant accessibles in the nsAccessibleWrap class for each platform.
-      nsCOMPtr<nsIContent> content = do_QueryInterface(aNode);
-      if (content) {
-        nsIContent *parent = content->GetParent();
-        if (parent && parent->NodeInfo()->Equals(nsAccessibilityAtoms::menu, kNameSpaceID_XUL)) {
-          return nsnull;
-        }
-      }
+      nsIContent *parent = aContent->GetParent();
+      if (parent && parent->NodeInfo()->Equals(nsAccessibilityAtoms::menu,
+                                               kNameSpaceID_XUL))
+        return nsnull;
 #endif
-      accessible = new nsXULMenupopupAccessible(aNode, aWeakShell);
+      accessible = new nsXULMenupopupAccessible(aContent, aWeakShell);
       break;
     }
     case nsIAccessibleProvider::XULMenuSeparator:
-      accessible = new nsXULMenuSeparatorAccessible(aNode, aWeakShell);
+      accessible = new nsXULMenuSeparatorAccessible(aContent, aWeakShell);
       break;
     case nsIAccessibleProvider::XULPane:
-      accessible = new nsEnumRoleAccessible(aNode, aWeakShell,
+      accessible = new nsEnumRoleAccessible(aContent, aWeakShell,
                                             nsIAccessibleRole::ROLE_PANE);
       break;
     case nsIAccessibleProvider::XULProgressMeter:
-      accessible = new nsXULProgressMeterAccessible(aNode, aWeakShell);
+      accessible = new nsXULProgressMeterAccessible(aContent, aWeakShell);
       break;
     case nsIAccessibleProvider::XULStatusBar:
-      accessible = new nsXULStatusBarAccessible(aNode, aWeakShell);
+      accessible = new nsXULStatusBarAccessible(aContent, aWeakShell);
       break;
     case nsIAccessibleProvider::XULScale:
-      accessible = new nsXULSliderAccessible(aNode, aWeakShell);
+      accessible = new nsXULSliderAccessible(aContent, aWeakShell);
       break;
     case nsIAccessibleProvider::XULRadioButton:
-      accessible = new nsXULRadioButtonAccessible(aNode, aWeakShell);
+      accessible = new nsXULRadioButtonAccessible(aContent, aWeakShell);
       break;
     case nsIAccessibleProvider::XULRadioGroup:
-      accessible = new nsXULRadioGroupAccessible(aNode, aWeakShell);
+      accessible = new nsXULRadioGroupAccessible(aContent, aWeakShell);
       break;
     case nsIAccessibleProvider::XULTab:
-      accessible = new nsXULTabAccessible(aNode, aWeakShell);
+      accessible = new nsXULTabAccessible(aContent, aWeakShell);
       break;
     case nsIAccessibleProvider::XULTabs:
-      accessible = new nsXULTabsAccessible(aNode, aWeakShell);
+      accessible = new nsXULTabsAccessible(aContent, aWeakShell);
       break;
     case nsIAccessibleProvider::XULTabpanels:
-      accessible = new nsXULTabpanelsAccessible(aNode, aWeakShell);
+      accessible = new nsXULTabpanelsAccessible(aContent, aWeakShell);
       break;
     case nsIAccessibleProvider::XULText:
-      accessible = new nsXULTextAccessible(aNode, aWeakShell);
+      accessible = new nsXULTextAccessible(aContent, aWeakShell);
       break;
     case nsIAccessibleProvider::XULTextBox:
-      accessible = new nsXULTextFieldAccessible(aNode, aWeakShell);
+      accessible = new nsXULTextFieldAccessible(aContent, aWeakShell);
       break;
     case nsIAccessibleProvider::XULThumb:
-      accessible = new nsXULThumbAccessible(aNode, aWeakShell);
+      accessible = new nsXULThumbAccessible(aContent, aWeakShell);
       break;
     case nsIAccessibleProvider::XULTree:
-      return CreateAccessibleForXULTree(aNode, aWeakShell);
+      return CreateAccessibleForXULTree(aContent, aWeakShell);
 
     case nsIAccessibleProvider::XULTreeColumns:
-      accessible = new nsXULTreeColumnsAccessible(aNode, aWeakShell);
+      accessible = new nsXULTreeColumnsAccessible(aContent, aWeakShell);
       break;
     case nsIAccessibleProvider::XULTreeColumnItem:
-      accessible = new nsXULColumnItemAccessible(aNode, aWeakShell);
+      accessible = new nsXULColumnItemAccessible(aContent, aWeakShell);
       break;
     case nsIAccessibleProvider::XULToolbar:
-      accessible = new nsXULToolbarAccessible(aNode, aWeakShell);
+      accessible = new nsXULToolbarAccessible(aContent, aWeakShell);
       break;
     case nsIAccessibleProvider::XULToolbarSeparator:
-      accessible = new nsXULToolbarSeparatorAccessible(aNode, aWeakShell);
+      accessible = new nsXULToolbarSeparatorAccessible(aContent, aWeakShell);
       break;
     case nsIAccessibleProvider::XULTooltip:
-      accessible = new nsXULTooltipAccessible(aNode, aWeakShell);
+      accessible = new nsXULTooltipAccessible(aContent, aWeakShell);
       break;
     case nsIAccessibleProvider::XULToolbarButton:
-      accessible = new nsXULToolbarButtonAccessible(aNode, aWeakShell);
+      accessible = new nsXULToolbarButtonAccessible(aContent, aWeakShell);
       break;
 #endif // MOZ_XUL
 
 #ifndef DISABLE_XFORMS_HOOKS
     // XForms elements
     case nsIAccessibleProvider::XFormsContainer:
-      accessible = new nsXFormsContainerAccessible(aNode, aWeakShell);
+      accessible = new nsXFormsContainerAccessible(aContent, aWeakShell);
       break;
 
     case nsIAccessibleProvider::XFormsLabel:
-      accessible = new nsXFormsLabelAccessible(aNode, aWeakShell);
+      accessible = new nsXFormsLabelAccessible(aContent, aWeakShell);
       break;
     case nsIAccessibleProvider::XFormsOutput:
-      accessible = new nsXFormsOutputAccessible(aNode, aWeakShell);
+      accessible = new nsXFormsOutputAccessible(aContent, aWeakShell);
       break;
     case nsIAccessibleProvider::XFormsTrigger:
-      accessible = new nsXFormsTriggerAccessible(aNode, aWeakShell);
+      accessible = new nsXFormsTriggerAccessible(aContent, aWeakShell);
       break;
     case nsIAccessibleProvider::XFormsInput:
-      accessible = new nsXFormsInputAccessible(aNode, aWeakShell);
+      accessible = new nsXFormsInputAccessible(aContent, aWeakShell);
       break;
     case nsIAccessibleProvider::XFormsInputBoolean:
-      accessible = new nsXFormsInputBooleanAccessible(aNode, aWeakShell);
+      accessible = new nsXFormsInputBooleanAccessible(aContent, aWeakShell);
       break;
     case nsIAccessibleProvider::XFormsInputDate:
-      accessible = new nsXFormsInputDateAccessible(aNode, aWeakShell);
+      accessible = new nsXFormsInputDateAccessible(aContent, aWeakShell);
       break;
     case nsIAccessibleProvider::XFormsSecret:
-      accessible = new nsXFormsSecretAccessible(aNode, aWeakShell);
+      accessible = new nsXFormsSecretAccessible(aContent, aWeakShell);
       break;
     case nsIAccessibleProvider::XFormsSliderRange:
-      accessible = new nsXFormsRangeAccessible(aNode, aWeakShell);
+      accessible = new nsXFormsRangeAccessible(aContent, aWeakShell);
       break;
     case nsIAccessibleProvider::XFormsSelect:
-      accessible = new nsXFormsSelectAccessible(aNode, aWeakShell);
+      accessible = new nsXFormsSelectAccessible(aContent, aWeakShell);
       break;
     case nsIAccessibleProvider::XFormsChoices:
-      accessible = new nsXFormsChoicesAccessible(aNode, aWeakShell);
+      accessible = new nsXFormsChoicesAccessible(aContent, aWeakShell);
       break;
     case nsIAccessibleProvider::XFormsSelectFull:
-      accessible = new nsXFormsSelectFullAccessible(aNode, aWeakShell);
+      accessible = new nsXFormsSelectFullAccessible(aContent, aWeakShell);
       break;
     case nsIAccessibleProvider::XFormsItemCheckgroup:
-      accessible = new nsXFormsItemCheckgroupAccessible(aNode, aWeakShell);
+      accessible = new nsXFormsItemCheckgroupAccessible(aContent, aWeakShell);
       break;
     case nsIAccessibleProvider::XFormsItemRadiogroup:
-      accessible = new nsXFormsItemRadiogroupAccessible(aNode, aWeakShell);
+      accessible = new nsXFormsItemRadiogroupAccessible(aContent, aWeakShell);
       break;
     case nsIAccessibleProvider::XFormsSelectCombobox:
-      accessible = new nsXFormsSelectComboboxAccessible(aNode, aWeakShell);
+      accessible = new nsXFormsSelectComboboxAccessible(aContent, aWeakShell);
       break;
     case nsIAccessibleProvider::XFormsItemCombobox:
-      accessible = new nsXFormsItemComboboxAccessible(aNode, aWeakShell);
+      accessible = new nsXFormsItemComboboxAccessible(aContent, aWeakShell);
       break;
 
     case nsIAccessibleProvider::XFormsDropmarkerWidget:
-      accessible = new nsXFormsDropmarkerWidgetAccessible(aNode, aWeakShell);
+      accessible = new nsXFormsDropmarkerWidgetAccessible(aContent, aWeakShell);
       break;
     case nsIAccessibleProvider::XFormsCalendarWidget:
-      accessible = new nsXFormsCalendarWidgetAccessible(aNode, aWeakShell);
+      accessible = new nsXFormsCalendarWidgetAccessible(aContent, aWeakShell);
       break;
     case nsIAccessibleProvider::XFormsComboboxPopupWidget:
-      accessible = new nsXFormsComboboxPopupWidgetAccessible(aNode, aWeakShell);
+      accessible = new nsXFormsComboboxPopupWidgetAccessible(aContent, aWeakShell);
       break;
 #endif
 
     default:
       return nsnull;
   }
 
   return accessible.forget();
@@ -1994,63 +1998,62 @@ NS_GetAccessibilityService(nsIAccessibil
   return NS_OK;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccessibilityService private (DON'T put methods here)
 
 already_AddRefed<nsAccessible>
 nsAccessibilityService::CreateAccessibleForDeckChild(nsIFrame* aFrame,
-                                                     nsIDOMNode *aNode,
+                                                     nsIContent *aContent,
                                                      nsIWeakReference *aWeakShell)
 {
   nsRefPtr<nsAccessible> accessible;
 
   if (aFrame->GetType() == nsAccessibilityAtoms::boxFrame ||
       aFrame->GetType() == nsAccessibilityAtoms::scrollFrame) {
 
     nsIFrame* parentFrame = aFrame->GetParent();
     if (parentFrame && parentFrame->GetType() == nsAccessibilityAtoms::deckFrame) {
       // If deck frame is for xul:tabpanels element then the given node has
       // tabpanel accessible.
       nsCOMPtr<nsIContent> parentContent = parentFrame->GetContent();
 #ifdef MOZ_XUL
       if (parentContent->NodeInfo()->Equals(nsAccessibilityAtoms::tabpanels,
                                             kNameSpaceID_XUL)) {
-        accessible = new nsXULTabpanelAccessible(aNode, aWeakShell);
+        accessible = new nsXULTabpanelAccessible(aContent, aWeakShell);
       } else
 #endif
         accessible =
-          new nsEnumRoleAccessible(aNode, aWeakShell,
+          new nsEnumRoleAccessible(aContent, aWeakShell,
                                    nsIAccessibleRole::ROLE_PROPERTYPAGE);
     }
   }
 
   return accessible.forget();
 }
 
 #ifdef MOZ_XUL
 already_AddRefed<nsAccessible>
-nsAccessibilityService::CreateAccessibleForXULTree(nsIDOMNode *aNode,
+nsAccessibilityService::CreateAccessibleForXULTree(nsIContent *aContent,
                                                    nsIWeakReference *aWeakShell)
 {
-  nsCOMPtr<nsITreeBoxObject> treeBoxObj;
-  nsCoreUtils::GetTreeBoxObject(aNode, getter_AddRefs(treeBoxObj));
+  nsCOMPtr<nsITreeBoxObject> treeBoxObj = nsCoreUtils::GetTreeBoxObject(aContent);
   if (!treeBoxObj)
     return nsnull;
 
   nsCOMPtr<nsITreeColumns> treeColumns;
   treeBoxObj->GetColumns(getter_AddRefs(treeColumns));
   if (!treeColumns)
     return nsnull;
 
   nsRefPtr<nsAccessible> accessible;
 
   PRInt32 count = 0;
   treeColumns->GetCount(&count);
   if (count == 1) // outline of list accessible
-    accessible = new nsXULTreeAccessible(aNode, aWeakShell);
+    accessible = new nsXULTreeAccessible(aContent, aWeakShell);
   else // table or tree table accessible
-    accessible = new nsXULTreeGridAccessibleWrap(aNode, aWeakShell);
+    accessible = new nsXULTreeGridAccessibleWrap(aContent, aWeakShell);
 
   return accessible.forget();
 }
 #endif
--- a/accessible/src/base/nsAccessibilityService.h
+++ b/accessible/src/base/nsAccessibilityService.h
@@ -39,30 +39,18 @@
 #ifndef __nsAccessibilityService_h__
 #define __nsAccessibilityService_h__
 
 #include "nsIAccessibilityService.h"
 
 #include "a11yGeneric.h"
 #include "nsAccDocManager.h"
 
-#include "nsCOMArray.h"
 #include "nsIObserver.h"
 
-class nsAccessNode;
-class nsAccessible;
-class nsIFrame;
-class nsIWeakReference;
-class nsIDOMNode;
-class nsObjectFrame;
-class nsIDocShell;
-class nsIPresShell;
-class nsIContent;
-struct nsRoleMapEntry;
-
 class nsAccessibilityService : public nsAccDocManager,
                                public nsIAccessibilityService,
                                public nsIObserver
 {
 public:
   virtual ~nsAccessibilityService();
 
   NS_DECL_ISUPPORTS_INHERITED
@@ -131,93 +119,114 @@ public:
   virtual nsresult RemoveNativeRootAccessible(nsIAccessible *aRootAccessible);
 
   virtual nsresult InvalidateSubtreeFor(nsIPresShell *aPresShell,
                                         nsIContent *aContent,
                                         PRUint32 aChangeType);
 
   virtual void NotifyOfAnchorJumpTo(nsIContent *aTarget);
 
+  virtual void PresShellDestroyed(nsIPresShell* aPresShell);
+
   virtual nsresult FireAccessibleEvent(PRUint32 aEvent, nsIAccessible *aTarget);
 
   // nsAccessibiltiyService
 
   /**
-   * Return presentation shell for the given node.
-   *
-   * @param aNode - the given DOM node.
-   */
-  static nsresult GetShellFromNode(nsIDOMNode *aNode,
-                                   nsIWeakReference **weakShell);
-
-  /**
    * Return true if accessibility service has been shutdown.
    */
   static PRBool IsShutdown() { return gIsShutdown; }
 
   /**
    * Return an accessible for the given DOM node.
    *
    * @param  aNode       [in] the given node
    * @param  aPresShell  [in] the pres shell of the node
    * @param  aWeakShell  [in] the weak shell for the pres shell
    * @param  aIsHidden   [out, optional] indicates whether the node's frame is
    *                       hidden
    */
   already_AddRefed<nsAccessible>
-    GetAccessible(nsIDOMNode *aNode, nsIPresShell *aPresShell,
+    GetAccessible(nsINode *aNode, nsIPresShell *aPresShell,
                   nsIWeakReference *aWeakShell, PRBool *aIsHidden = nsnull);
 
   /**
    * Return an accessible for the given DOM node.
    */
-  nsAccessible *GetAccessible(nsIDOMNode *aNode);
+  nsAccessible *GetAccessible(nsINode *aNode);
 
   /**
    * Return an accessible for a DOM node in the given pres shell.
    * 
    * @param aNode       [in] the given node.
    * @param aPresShell  [in] the presentation shell of the given node.
    */
-  nsAccessible *GetAccessibleInWeakShell(nsIDOMNode *aNode,
+  nsAccessible *GetAccessibleInWeakShell(nsINode *aNode,
                                          nsIWeakReference *aPresShell);
 
   /**
    * Return the first accessible parent of a DOM node.
    *
    * @param aDOMNode    [in] the DOM node to get an accessible for
    * @param aCanCreate  [in] specifies if accessible can be created if it didn't
    *                     exist
    */
-  nsAccessible *GetContainerAccessible(nsIDOMNode *aNode, PRBool aCanCreate);
+  nsAccessible *GetContainerAccessible(nsINode *aNode, PRBool aCanCreate);
 
   /**
-   * Return an access node for the DOM node in the given presentation shell if
-   * the access node already exists, otherwise null.
+   * The same as getAccessibleFor method except it returns accessible only if
+   * it is attached, i.e. accessible is certified to be a descendant of the root
+   * accessible.
+   *
+   * XXX: this method must go away once we'll implement correct accessible tree.
    *
-   * @param  aNode       [in] the DOM node to get an access node for
-   * @param  aPresShell  [in] the presentation shell which contains layout info
-   *                       for the DOM node
+   * @param  aNode  [in] the DOM node to get an accessible for
+   * @return         the accessible for the given DOM node
    */
-  nsAccessNode* GetCachedAccessNode(nsIDOMNode *aNode,
-                                    nsIWeakReference *aShell);
+  nsAccessible *GetAttachedAccessibleFor(nsINode *aNode);
+
+  /**
+   * Return an DOM node that is relevant to attached accessible check. This
+   * node is either from bindings chain if given node is anonymous and owner
+   * binding denies accessible in anonymous content or given node (it's not
+   * important whether it is accessible or not). This method doesn't create
+   * accessible object for returned node.
+   *
+   * XXX: this method must go away once we'll implement correct accessible tree.
+   *
+   * @param  aNode  [in] the DOM node to get relevant content node
+   * @return         the DOM node for parent attached accessible
+   */
+  nsINode *GetRelevantContentNodeFor(nsINode *aNode);
 
   /**
    * Initialize an accessible and cache it. The method should be called for
    * every created accessible.
    *
    * @param  aAccessible    [in] accessible to initialize.
    * @param  aRoleMapEntry  [in] the role map entry role the ARIA role or nsnull
    *                          if none
    *
    * @return true if the accessible was initialized, otherwise false
    */
   PRBool InitAccessible(nsAccessible *aAccessible,
                         nsRoleMapEntry *aRoleMapEntry);
 
+protected:
+  /**
+   * Return an accessible for the DOM node in the given presentation shell if
+   * the accessible already exists, otherwise null.
+   *
+   * @param  aNode       [in] the DOM node to get an access node for
+   * @param  aPresShell  [in] the presentation shell which contains layout info
+   *                       for the DOM node
+   */
+  nsAccessible *GetCachedAccessible(nsINode *aNode,
+                                    nsIWeakReference *aShell);
+
 private:
   // nsAccessibilityService creation is controlled by friend
   // NS_GetAccessibilityService, keep constructors private.
   nsAccessibilityService();
   nsAccessibilityService(const nsAccessibilityService&);
   nsAccessibilityService& operator =(const nsAccessibilityService&);
 
 private:
@@ -229,59 +238,59 @@ private:
   /**
    * Shutdowns accessibility service.
    */
   void Shutdown();
 
   /**
    * Return presentation shell, DOM node for the given frame.
    *
-   * @param aFrame - the given frame
-   * @param aShell [out] - presentation shell for DOM node associated with the
-   *                 given frame
-   * @param aContent [out] - DOM node associated with the given frame
+   * @param aFrame    [in] the given frame
+   * @param aShell    [out] presentation shell for DOM node associated with the
+   *                    given frame
+   * @param aContent  [out] DOM node associated with the given frame
    */
-  nsresult GetInfo(nsIFrame *aFrame,
-                   nsIWeakReference **aShell,
-                   nsIDOMNode **aContent);
+  nsresult GetInfo(nsIFrame *aFrame, nsIWeakReference **aShell,
+                   nsIContent **aContent);
 
   /**
    * Return accessible for HTML area element associated with an image map.
    */
   already_AddRefed<nsAccessible>
-    GetAreaAccessible(nsIFrame *aImageFrame, nsIDOMNode *aAreaNode,
+    GetAreaAccessible(nsIFrame *aImageFrame, nsINode *aAreaNode,
                       nsIWeakReference *aWeakShell);
 
   /**
    * Create accessible for the element implementing nsIAccessibleProvider
    * interface.
    */
   already_AddRefed<nsAccessible>
-    CreateAccessibleByType(nsIDOMNode *aNode, nsIWeakReference *aWeakShell);
+    CreateAccessibleByType(nsIContent *aContent, nsIWeakReference *aWeakShell);
 
   /**
    * Create accessible for HTML node by tag name.
    */
   already_AddRefed<nsAccessible>
     CreateHTMLAccessibleByMarkup(nsIFrame *aFrame, nsIWeakReference *aWeakShell,
-                                 nsIDOMNode *aNode);
+                                 nsINode *aNode);
 
   /**
    * Create accessible if parent is a deck frame.
    */
   already_AddRefed<nsAccessible>
-    CreateAccessibleForDeckChild(nsIFrame *aFrame, nsIDOMNode *aNode,
+    CreateAccessibleForDeckChild(nsIFrame *aFrame, nsIContent *aContent,
                                  nsIWeakReference *aWeakShell);
 
 #ifdef MOZ_XUL
   /**
    * Create accessible for XUL tree element.
    */
   already_AddRefed<nsAccessible>
-    CreateAccessibleForXULTree(nsIDOMNode *aNode, nsIWeakReference *aWeakShell);
+    CreateAccessibleForXULTree(nsIContent *aContent,
+                               nsIWeakReference *aWeakShell);
 #endif
 
   /**
    * Reference for accessibility service.
    */
   static nsAccessibilityService *gAccessibilityService;
 
   /**
--- a/accessible/src/base/nsAccessible.cpp
+++ b/accessible/src/base/nsAccessible.cpp
@@ -36,17 +36,17 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsAccessible.h"
 
 #include "nsIXBLAccessible.h"
 
-#include "nsAccIterator.h"
+#include "AccIterator.h"
 #include "nsAccUtils.h"
 #include "nsARIAMap.h"
 #include "nsDocAccessible.h"
 #include "nsEventShell.h"
 
 #include "nsAccessibilityService.h"
 #include "nsAccTreeWalker.h"
 #include "nsRelUtils.h"
@@ -185,19 +185,19 @@ nsresult nsAccessible::QueryInterface(RE
       return NS_OK;
     }
     return NS_ERROR_NO_INTERFACE;
   }
 
   return nsAccessNodeWrap::QueryInterface(aIID, aInstancePtr);
 }
 
-nsAccessible::nsAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell): nsAccessNodeWrap(aNode, aShell), 
-  mParent(nsnull), mRoleMapEntry(nsnull),
-  mAreChildrenInitialized(PR_FALSE)
+nsAccessible::nsAccessible(nsIContent *aContent, nsIWeakReference *aShell) :
+  nsAccessNodeWrap(aContent, aShell),
+  mParent(nsnull), mAreChildrenInitialized(PR_FALSE), mRoleMapEntry(nsnull)
 {
 #ifdef NS_DEBUG_X
    {
      nsCOMPtr<nsIPresShell> shell(do_QueryReferent(aShell));
      printf(">>> %p Created Acc - DOM: %p  PS: %p", 
             (void*)static_cast<nsIAccessible*>(this), (void*)aNode,
             (void*)shell.get());
     nsCOMPtr<nsIContent> content = do_QueryInterface(aNode);
@@ -235,46 +235,42 @@ nsAccessible::GetName(nsAString& aName)
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
   GetARIAName(aName);
   if (!aName.IsEmpty())
     return NS_OK;
 
-  nsCOMPtr<nsIXBLAccessible> xblAccessible(do_QueryInterface(mDOMNode));
+  nsCOMPtr<nsIXBLAccessible> xblAccessible(do_QueryInterface(mContent));
   if (xblAccessible) {
     xblAccessible->GetAccessibleName(aName);
     if (!aName.IsEmpty())
       return NS_OK;
   }
 
   nsresult rv = GetNameInternal(aName);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (!aName.IsEmpty())
     return NS_OK;
 
   // In the end get the name from tooltip.
-  nsCOMPtr<nsIContent> content = nsCoreUtils::GetRoleContent(mDOMNode);
-  if (!content)
-    return NS_OK;
-
   nsIAtom *tooltipAttr = nsnull;
 
-  if (content->IsHTML())
+  if (mContent->IsHTML())
     tooltipAttr = nsAccessibilityAtoms::title;
-  else if (content->IsXUL())
+  else if (mContent->IsXUL())
     tooltipAttr = nsAccessibilityAtoms::tooltiptext;
   else
     return NS_OK;
 
   // XXX: if CompressWhiteSpace worked on nsAString we could avoid a copy.
   nsAutoString name;
-  if (content->GetAttr(kNameSpaceID_None, tooltipAttr, name)) {
+  if (mContent->GetAttr(kNameSpaceID_None, tooltipAttr, name)) {
     name.CompressWhitespace();
     aName = name;
     return NS_OK_NAME_FROM_TOOLTIP;
   }
 
   if (rv != NS_OK_EMPTY_NAME)
     aName.SetIsVoid(PR_TRUE);
 
@@ -286,47 +282,43 @@ NS_IMETHODIMP nsAccessible::GetDescripti
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
   // There are 4 conditions that make an accessible have no accDescription:
   // 1. it's a text node; or
   // 2. It has no DHTML describedby property
   // 3. it doesn't have an accName; or
   // 4. its title attribute already equals to its accName nsAutoString name; 
-  nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
-  NS_ASSERTION(content, "No content of valid accessible!");
-  if (!content)
-    return NS_ERROR_FAILURE;
-
-  if (!content->IsNodeOfType(nsINode::eTEXT)) {
+
+  if (!mContent->IsNodeOfType(nsINode::eTEXT)) {
     nsAutoString description;
     nsresult rv = nsTextEquivUtils::
       GetTextEquivFromIDRefs(this, nsAccessibilityAtoms::aria_describedby,
                              description);
     NS_ENSURE_SUCCESS(rv, rv);
 
     if (description.IsEmpty()) {
-      PRBool isXUL = content->IsXUL();
+      PRBool isXUL = mContent->IsXUL();
       if (isXUL) {
         // Try XUL <description control="[id]">description text</description>
         nsIContent *descriptionContent =
-          nsCoreUtils::FindNeighbourPointingToNode(content,
+          nsCoreUtils::FindNeighbourPointingToNode(mContent,
                                                    nsAccessibilityAtoms::control,
                                                    nsAccessibilityAtoms::description);
 
         if (descriptionContent) {
           // We have a description content node
           nsTextEquivUtils::
             AppendTextEquivFromContent(this, descriptionContent, &description);
         }
       }
       if (description.IsEmpty()) {
         nsIAtom *descAtom = isXUL ? nsAccessibilityAtoms::tooltiptext :
                                     nsAccessibilityAtoms::title;
-        if (content->GetAttr(kNameSpaceID_None, descAtom, description)) {
+        if (mContent->GetAttr(kNameSpaceID_None, descAtom, description)) {
           nsAutoString name;
           GetName(name);
           if (name.IsEmpty() || description == name) {
             // Don't use tooltip for a description if this object
             // has no name or the tooltip is the same as the name
             description.Truncate();
           }
         }
@@ -396,38 +388,36 @@ GetAccessModifierMask(nsIContent* aConte
   return NS_SUCCEEDED(rv) ? accessModifierMask : 0;
 }
 
 NS_IMETHODIMP
 nsAccessible::GetKeyboardShortcut(nsAString& aAccessKey)
 {
   aAccessKey.Truncate();
 
-  nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
-  if (!content)
+  if (IsDefunct())
     return NS_ERROR_FAILURE;
 
-  PRUint32 key = nsCoreUtils::GetAccessKeyFor(content);
-  if (!key && content->IsElement()) {
+  PRUint32 key = nsCoreUtils::GetAccessKeyFor(mContent);
+  if (!key && mContent->IsElement()) {
     // Copy access key from label node unless it is labeled
     // via an ancestor <label>, in which case that would be redundant
-    nsCOMPtr<nsIContent> labelContent(nsCoreUtils::GetLabelContent(content));
-    nsCOMPtr<nsINode> thisNode = do_QueryInterface(mDOMNode);
-    if (labelContent && !nsCoreUtils::IsAncestorOf(labelContent, thisNode))
+    nsCOMPtr<nsIContent> labelContent(nsCoreUtils::GetLabelContent(mContent));
+    if (labelContent && !nsCoreUtils::IsAncestorOf(labelContent, mContent))
       key = nsCoreUtils::GetAccessKeyFor(labelContent);
   }
 
   if (!key)
     return NS_OK;
 
   nsAutoString accesskey(key);
 
   // Append the modifiers in reverse order, result: Control+Alt+Shift+Meta+<key>
   nsAutoString propertyKey;
-  PRInt32 modifierMask = GetAccessModifierMask(content);
+  PRInt32 modifierMask = GetAccessModifierMask(mContent);
   if (modifierMask & NS_MODIFIER_META) {
     propertyKey.AssignLiteral("VK_META");
     nsAccessible::GetFullKeyName(propertyKey, accesskey, accesskey);
   }
   if (modifierMask & NS_MODIFIER_SHIFT) {
     propertyKey.AssignLiteral("VK_SHIFT");
     nsAccessible::GetFullKeyName(propertyKey, accesskey, accesskey);
   }
@@ -439,30 +429,16 @@ nsAccessible::GetKeyboardShortcut(nsAStr
     propertyKey.AssignLiteral("VK_CONTROL");
     nsAccessible::GetFullKeyName(propertyKey, accesskey, accesskey);
   }
 
   aAccessKey = accesskey;
   return NS_OK;
 }
 
-nsresult
-nsAccessible::Shutdown()
-{
-  // Invalidate the child count and pointers to other accessibles, also make
-  // sure none of its children point to this parent
-  InvalidateChildren();
-  if (mParent) {
-    mParent->InvalidateChildren();
-    mParent = nsnull;
-  }
-
-  return nsAccessNodeWrap::Shutdown();
-}
-
 NS_IMETHODIMP
 nsAccessible::GetParent(nsIAccessible **aParent)
 {
   NS_ENSURE_ARG_POINTER(aParent);
 
   NS_IF_ADDREF(*aParent = GetParent());
   return *aParent ? NS_OK : NS_ERROR_FAILURE;
 }
@@ -624,19 +600,18 @@ nsresult nsAccessible::GetFullKeyName(co
 
 PRBool nsAccessible::IsVisible(PRBool *aIsOffscreen) 
 {
   // We need to know if at least a kMinPixels around the object is visible
   // Otherwise it will be marked nsIAccessibleStates::STATE_OFFSCREEN
   // The STATE_INVISIBLE flag is for elements which are programmatically hidden
   
   *aIsOffscreen = PR_TRUE;
-  if (!mDOMNode) {
-    return PR_FALSE; // Defunct object
-  }
+  if (IsDefunct())
+    return PR_FALSE;
 
   const PRUint16 kMinPixels  = 12;
    // Set up the variables we need, return false if we can't get at them all
   nsCOMPtr<nsIPresShell> shell(GetPresShell());
   if (!shell) 
     return PR_FALSE;
 
   nsIFrame *frame = GetFrame();
@@ -681,19 +656,17 @@ PRBool nsAccessible::IsVisible(PRBool *a
     if (isEmpty && !(frame->GetStateBits() & NS_FRAME_OUT_OF_FLOW)) {
       // Consider zero area objects hidden unless they are absolutely positioned
       // or floating and may have descendants that have a non-zero size
       return PR_FALSE;
     }
   }
 
   // The frame intersects the viewport, but we need to check the parent view chain :(
-  nsCOMPtr<nsIDOMDocument> domDoc;
-  mDOMNode->GetOwnerDocument(getter_AddRefs(domDoc));
-  nsCOMPtr<nsIDocument> doc(do_QueryInterface(domDoc));
+  nsIDocument* doc = mContent->GetOwnerDoc();
   if (!doc)  {
     return PR_FALSE;
   }
 
   nsIFrame* frameWithView =
     frame->HasView() ? frame : frame->GetAncestorWithViewExternal();
   nsIView* view = frameWithView->GetViewExternal();
   PRBool isVisible = CheckVisibilityInParentChain(doc, view);
@@ -713,47 +686,43 @@ nsAccessible::GetStateInternal(PRUint32 
       *aExtraState = nsIAccessibleStates::EXT_STATE_DEFUNCT;
 
     return NS_OK_DEFUNCT_OBJECT;
   }
 
   if (aExtraState)
     *aExtraState = 0;
 
-  nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
-  if (!content) {
-    return NS_OK;  // On document, this is not an error
-  }
-
   // Set STATE_UNAVAILABLE state based on disabled attribute
   // The disabled attribute is mostly used in XUL elements and HTML forms, but
   // if someone sets it on another attribute, 
   // it seems reasonable to consider it unavailable
   PRBool isDisabled;
-  if (content->IsHTML()) {
+  if (mContent->IsHTML()) {
     // In HTML, just the presence of the disabled attribute means it is disabled,
     // therefore disabled="false" indicates disabled!
-    isDisabled = content->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::disabled);
+    isDisabled = mContent->HasAttr(kNameSpaceID_None,
+                                   nsAccessibilityAtoms::disabled);
   }
   else {
-    isDisabled = content->AttrValueIs(kNameSpaceID_None,
-                                      nsAccessibilityAtoms::disabled,
-                                      nsAccessibilityAtoms::_true,
-                                      eCaseMatters);
+    isDisabled = mContent->AttrValueIs(kNameSpaceID_None,
+                                       nsAccessibilityAtoms::disabled,
+                                       nsAccessibilityAtoms::_true,
+                                       eCaseMatters);
   }
   if (isDisabled) {
     *aState |= nsIAccessibleStates::STATE_UNAVAILABLE;
   }
-  else if (content->IsElement()) {
+  else if (mContent->IsElement()) {
     nsIFrame *frame = GetFrame();
     if (frame && frame->IsFocusable()) {
       *aState |= nsIAccessibleStates::STATE_FOCUSABLE;
     }
 
-    if (gLastFocusedNode == mDOMNode) {
+    if (gLastFocusedNode == mContent) {
       *aState |= nsIAccessibleStates::STATE_FOCUSED;
     }
   }
 
   // Check if nsIAccessibleStates::STATE_INVISIBLE and
   // STATE_OFFSCREEN flags should be turned on for this object.
   PRBool isOffscreen;
   if (!IsVisible(&isOffscreen)) {
@@ -763,44 +732,39 @@ nsAccessible::GetStateInternal(PRUint32 
     *aState |= nsIAccessibleStates::STATE_OFFSCREEN;
   }
 
   nsIFrame *frame = GetFrame();
   if (frame && (frame->GetStateBits() & NS_FRAME_OUT_OF_FLOW))
     *aState |= nsIAccessibleStates::STATE_FLOATING;
 
   // Check if a XUL element has the popup attribute (an attached popup menu).
-  if (content->IsXUL())
-    if (content->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::popup))
+  if (mContent->IsXUL())
+    if (mContent->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::popup))
       *aState |= nsIAccessibleStates::STATE_HASPOPUP;
 
   // Add 'linked' state for simple xlink.
-  if (nsCoreUtils::IsXLink(content))
+  if (nsCoreUtils::IsXLink(mContent))
     *aState |= nsIAccessibleStates::STATE_LINKED;
 
   return NS_OK;
 }
 
   /* readonly attribute boolean focusedChild; */
-NS_IMETHODIMP nsAccessible::GetFocusedChild(nsIAccessible **aFocusedChild) 
+NS_IMETHODIMP
+nsAccessible::GetFocusedChild(nsIAccessible **aFocusedChild) 
 { 
-  nsCOMPtr<nsIAccessible> focusedChild;
-  if (gLastFocusedNode == mDOMNode) {
+  nsAccessible *focusedChild = nsnull;
+  if (gLastFocusedNode == mContent) {
     focusedChild = this;
   }
   else if (gLastFocusedNode) {
-    GetAccService()->GetAccessibleFor(gLastFocusedNode,
-                                      getter_AddRefs(focusedChild));
-    if (focusedChild) {
-      nsCOMPtr<nsIAccessible> focusedParentAccessible;
-      focusedChild->GetParent(getter_AddRefs(focusedParentAccessible));
-      if (focusedParentAccessible != this) {
-        focusedChild = nsnull;
-      }
-    }
+    focusedChild = GetAccService()->GetAccessible(gLastFocusedNode);
+    if (focusedChild && focusedChild->GetParent() != this)
+      focusedChild = nsnull;
   }
 
   NS_IF_ADDREF(*aFocusedChild = focusedChild);
   return NS_OK;
 }
 
 // nsAccessible::GetChildAtPoint()
 nsresult
@@ -844,26 +808,17 @@ nsAccessible::GetChildAtPoint(PRInt32 aX
   nsIFrame *foundFrame = presShell->GetFrameForPoint(frame, offset);
 
   nsIContent* content = nsnull;
   if (!foundFrame || !(content = foundFrame->GetContent())) {
     NS_IF_ADDREF(*aChild = fallbackAnswer);
     return NS_OK;
   }
 
-  nsCOMPtr<nsIDOMNode> node(do_QueryInterface(content));
-
-  nsCOMPtr<nsIDOMNode> relevantNode;
-  GetAccService()->GetRelevantContentNodeFor(node,
-                                             getter_AddRefs(relevantNode));
-  if (!relevantNode) {
-    NS_IF_ADDREF(*aChild = fallbackAnswer);
-    return NS_OK;
-  }
-
+  nsINode *relevantNode = GetAccService()->GetRelevantContentNodeFor(content);
   nsAccessible *accessible = GetAccService()->GetAccessible(relevantNode);
   if (!accessible) {
     // No accessible for the node with the point, so find the first
     // accessible in the DOM parent chain
     accessible = GetAccService()->GetContainerAccessible(relevantNode, PR_TRUE);
     if (!accessible) {
       NS_IF_ADDREF(*aChild = fallbackAnswer);
       return NS_OK;
@@ -982,17 +937,17 @@ void nsAccessible::GetBoundsRect(nsRect&
                                          nsAccessibilityAtoms::inlineFrame) &&
         !nsCoreUtils::IsCorrectFrameType(ancestorFrame,
                                          nsAccessibilityAtoms::textFrame))
       break;
     ancestorFrame = ancestorFrame->GetParent();
   }
 
   nsIFrame *iterFrame = firstFrame;
-  nsCOMPtr<nsIContent> firstContent(do_QueryInterface(mDOMNode));
+  nsCOMPtr<nsIContent> firstContent(mContent);
   nsIContent* iterContent = firstContent;
   PRInt32 depth = 0;
 
   // Look only at frames below this depth, or at this depth (if we're still on the content node we started with)
   while (iterContent == firstContent || depth > 0) {
     // Coordinates will come back relative to parent frame
     nsRect currFrameBounds = iterFrame->GetRect();
     
@@ -1082,54 +1037,52 @@ nsIFrame* nsAccessible::GetBoundsFrame()
 {
   return GetFrame();
 }
 
 /* void removeSelection (); */
 NS_IMETHODIMP nsAccessible::SetSelected(PRBool aSelect)
 {
   // Add or remove selection
-  if (!mDOMNode) {
+  if (IsDefunct())
     return NS_ERROR_FAILURE;
-  }
 
   PRUint32 state = nsAccUtils::State(this);
   if (state & nsIAccessibleStates::STATE_SELECTABLE) {
     nsCOMPtr<nsIAccessible> multiSelect =
-      nsAccUtils::GetMultiSelectableContainer(mDOMNode);
+      nsAccUtils::GetMultiSelectableContainer(mContent);
     if (!multiSelect) {
       return aSelect ? TakeFocus() : NS_ERROR_FAILURE;
     }
-    nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
-    NS_ASSERTION(content, "Called for dead accessible");
 
     if (mRoleMapEntry) {
       if (aSelect) {
-        return content->SetAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_selected,
-                                NS_LITERAL_STRING("true"), PR_TRUE);
+        return mContent->SetAttr(kNameSpaceID_None,
+                                 nsAccessibilityAtoms::aria_selected,
+                                 NS_LITERAL_STRING("true"), PR_TRUE);
       }
-      return content->UnsetAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_selected, PR_TRUE);
+      return mContent->UnsetAttr(kNameSpaceID_None,
+                                 nsAccessibilityAtoms::aria_selected, PR_TRUE);
     }
   }
 
-  return NS_ERROR_FAILURE;
+  return NS_OK;
 }
 
 /* void takeSelection (); */
 NS_IMETHODIMP nsAccessible::TakeSelection()
 {
   // Select only this item
-  if (!mDOMNode) {
+  if (IsDefunct())
     return NS_ERROR_FAILURE;
-  }
 
   PRUint32 state = nsAccUtils::State(this);
   if (state & nsIAccessibleStates::STATE_SELECTABLE) {
     nsCOMPtr<nsIAccessible> multiSelect =
-      nsAccUtils::GetMultiSelectableContainer(mDOMNode);
+      nsAccUtils::GetMultiSelectableContainer(mContent);
     if (multiSelect) {
       nsCOMPtr<nsIAccessibleSelectable> selectable = do_QueryInterface(multiSelect);
       selectable->ClearSelection();
     }
     return SetSelected(PR_TRUE);
   }
 
   return NS_ERROR_FAILURE;
@@ -1137,68 +1090,61 @@ NS_IMETHODIMP nsAccessible::TakeSelectio
 
 /* void takeFocus (); */
 NS_IMETHODIMP
 nsAccessible::TakeFocus()
 {
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
-  nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
-
   nsIFrame *frame = GetFrame();
   NS_ENSURE_STATE(frame);
 
+  nsIContent* focusContent = mContent;
+
   // If the current element can't take real DOM focus and if it has an ID and
   // ancestor with a the aria-activedescendant attribute present, then set DOM
   // focus to that ancestor and set aria-activedescendant on the ancestor to
   // the ID of the desired element.
   if (!frame->IsFocusable()) {
     nsAutoString id;
-    if (content && nsCoreUtils::GetID(content, id)) {
-
-      nsCOMPtr<nsIContent> ancestorContent = content;
+    if (nsCoreUtils::GetID(mContent, id)) {
+
+      nsIContent* ancestorContent = mContent;
       while ((ancestorContent = ancestorContent->GetParent()) &&
              !ancestorContent->HasAttr(kNameSpaceID_None,
                                        nsAccessibilityAtoms::aria_activedescendant));
 
       if (ancestorContent) {
         nsCOMPtr<nsIPresShell> presShell(do_QueryReferent(mWeakShell));
         if (presShell) {
           nsIFrame *frame = ancestorContent->GetPrimaryFrame();
           if (frame && frame->IsFocusable()) {
-
-            content = ancestorContent;            
-            content->SetAttr(kNameSpaceID_None,
-                             nsAccessibilityAtoms::aria_activedescendant,
-                             id, PR_TRUE);
+            focusContent = ancestorContent;
+            focusContent->SetAttr(kNameSpaceID_None,
+                                  nsAccessibilityAtoms::aria_activedescendant,
+                                  id, PR_TRUE);
           }
         }
       }
     }
   }
 
-  nsCOMPtr<nsIDOMElement> element(do_QueryInterface(content));
+  nsCOMPtr<nsIDOMElement> element(do_QueryInterface(focusContent));
   nsCOMPtr<nsIFocusManager> fm = do_GetService(FOCUSMANAGER_CONTRACTID);
   if (fm)
     fm->SetFocus(element, 0);
 
   return NS_OK;
 }
 
 nsresult
 nsAccessible::GetHTMLName(nsAString& aLabel)
 {
-  nsCOMPtr<nsIContent> content = nsCoreUtils::GetRoleContent(mDOMNode);
-  if (!content) {
-    aLabel.SetIsVoid(PR_TRUE);
-    return NS_OK;
-  }
-
-  nsIContent *labelContent = nsCoreUtils::GetHTMLLabelContent(content);
+  nsIContent *labelContent = nsCoreUtils::GetHTMLLabelContent(mContent);
   if (labelContent) {
     nsAutoString label;
     nsresult rv =
       nsTextEquivUtils::AppendTextEquivFromContent(this, labelContent, &label);
     NS_ENSURE_SUCCESS(rv, rv);
 
     label.CompressWhitespace();
     if (!label.IsEmpty()) {
@@ -1224,47 +1170,44 @@ nsAccessible::GetHTMLName(nsAString& aLa
   */
 nsresult
 nsAccessible::GetXULName(nsAString& aLabel)
 {
   // CASE #1 (via label attribute) -- great majority of the cases
   nsresult rv = NS_OK;
 
   nsAutoString label;
-  nsCOMPtr<nsIDOMXULLabeledControlElement> labeledEl(do_QueryInterface(mDOMNode));
+  nsCOMPtr<nsIDOMXULLabeledControlElement> labeledEl(do_QueryInterface(mContent));
   if (labeledEl) {
     rv = labeledEl->GetLabel(label);
   }
   else {
-    nsCOMPtr<nsIDOMXULSelectControlItemElement> itemEl(do_QueryInterface(mDOMNode));
+    nsCOMPtr<nsIDOMXULSelectControlItemElement> itemEl(do_QueryInterface(mContent));
     if (itemEl) {
       rv = itemEl->GetLabel(label);
     }
     else {
-      nsCOMPtr<nsIDOMXULSelectControlElement> select(do_QueryInterface(mDOMNode));
+      nsCOMPtr<nsIDOMXULSelectControlElement> select(do_QueryInterface(mContent));
       // Use label if this is not a select control element which 
       // uses label attribute to indicate which option is selected
       if (!select) {
-        nsCOMPtr<nsIDOMXULElement> xulEl(do_QueryInterface(mDOMNode));
+        nsCOMPtr<nsIDOMXULElement> xulEl(do_QueryInterface(mContent));
         if (xulEl) {
           rv = xulEl->GetAttribute(NS_LITERAL_STRING("label"), label);
         }
       }
     }
   }
 
   // CASES #2 and #3 ------ label as a child or <label control="id" ... > </label>
-  nsCOMPtr<nsIContent> content = nsCoreUtils::GetRoleContent(mDOMNode);
-  if (!content)
-    return NS_OK;
-
   if (NS_FAILED(rv) || label.IsEmpty()) {
     label.Truncate();
     nsIContent *labelContent =
-      nsCoreUtils::FindNeighbourPointingToNode(content, nsAccessibilityAtoms::control,
+      nsCoreUtils::FindNeighbourPointingToNode(mContent,
+                                               nsAccessibilityAtoms::control,
                                                nsAccessibilityAtoms::label);
 
     nsCOMPtr<nsIDOMXULLabelElement> xulLabel(do_QueryInterface(labelContent));
     // Check if label's value attribute is used
     if (xulLabel && NS_SUCCEEDED(xulLabel->GetValue(label)) && label.IsEmpty()) {
       // If no value attribute, a non-empty label must contain
       // children that define its text -- possibly using HTML
       nsTextEquivUtils::AppendTextEquivFromContent(this, labelContent, &label);
@@ -1274,19 +1217,19 @@ nsAccessible::GetXULName(nsAString& aLab
   // XXX If CompressWhiteSpace worked on nsAString we could avoid a copy
   label.CompressWhitespace();
   if (!label.IsEmpty()) {
     aLabel = label;
     return NS_OK;
   }
 
   // Can get text from title of <toolbaritem> if we're a child of a <toolbaritem>
-  nsIContent *bindingParent = content->GetBindingParent();
+  nsIContent *bindingParent = mContent->GetBindingParent();
   nsIContent *parent = bindingParent? bindingParent->GetParent() :
-                                      content->GetParent();
+                                      mContent->GetParent();
   while (parent) {
     if (parent->Tag() == nsAccessibilityAtoms::toolbaritem &&
         parent->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::title, label)) {
       label.CompressWhitespace();
       aLabel = label;
       return NS_OK;
     }
     parent = parent->GetParent();
@@ -1294,55 +1237,54 @@ nsAccessible::GetXULName(nsAString& aLab
 
   return nsTextEquivUtils::GetNameFromSubtree(this, aLabel);
 }
 
 nsresult
 nsAccessible::HandleAccEvent(nsAccEvent *aEvent)
 {
   NS_ENSURE_ARG_POINTER(aEvent);
-  nsCOMPtr<nsIDOMNode> eventNode;
-  aEvent->GetDOMNode(getter_AddRefs(eventNode));
-  NS_ENSURE_TRUE(nsAccUtils::IsNodeRelevant(eventNode), NS_ERROR_FAILURE);
+  NS_ENSURE_TRUE(nsAccUtils::IsNodeRelevant(aEvent->GetNode()),
+                 NS_ERROR_FAILURE);
 
   nsCOMPtr<nsIObserverService> obsService =
     mozilla::services::GetObserverService();
   NS_ENSURE_TRUE(obsService, NS_ERROR_FAILURE);
 
   return obsService->NotifyObservers(aEvent, NS_ACCESSIBLE_EVENT_TOPIC, nsnull);
 }
 
 NS_IMETHODIMP
 nsAccessible::GetRole(PRUint32 *aRole)
 {
   NS_ENSURE_ARG_POINTER(aRole);
-
   *aRole = nsIAccessibleRole::ROLE_NOTHING;
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
   if (mRoleMapEntry) {
     *aRole = mRoleMapEntry->role;
 
     // These unfortunate exceptions don't fit into the ARIA table
     // This is where the nsIAccessible role depends on both the role and ARIA state
     if (*aRole == nsIAccessibleRole::ROLE_PUSHBUTTON) {
-      nsCOMPtr<nsIContent> content = do_QueryInterface(mDOMNode);
-      if (content) {
-        if (nsAccUtils::HasDefinedARIAToken(content, nsAccessibilityAtoms::aria_pressed)) {
-          // For simplicity, any existing pressed attribute except "", or "undefined"
-          // indicates a toggle
-          *aRole = nsIAccessibleRole::ROLE_TOGGLE_BUTTON;
-        }
-        else if (content->AttrValueIs(kNameSpaceID_None, nsAccessibilityAtoms::aria_haspopup,
-                                      nsAccessibilityAtoms::_true, eCaseMatters)) {
-          // For button with aria-haspopup="true"
-          *aRole = nsIAccessibleRole::ROLE_BUTTONMENU;
-        }
+
+      if (nsAccUtils::HasDefinedARIAToken(mContent,
+                                          nsAccessibilityAtoms::aria_pressed)) {
+        // For simplicity, any existing pressed attribute except "", or "undefined"
+        // indicates a toggle.
+        *aRole = nsIAccessibleRole::ROLE_TOGGLE_BUTTON;
+
+      } else if (mContent->AttrValueIs(kNameSpaceID_None,
+                                       nsAccessibilityAtoms::aria_haspopup,
+                                       nsAccessibilityAtoms::_true,
+                                       eCaseMatters)) {
+        // For button with aria-haspopup="true".
+        *aRole = nsIAccessibleRole::ROLE_BUTTONMENU;
       }
     }
     else if (*aRole == nsIAccessibleRole::ROLE_LISTBOX) {
       // A listbox inside of a combo box needs a special role because of ATK mapping to menu
       nsCOMPtr<nsIAccessible> possibleCombo;
       GetParent(getter_AddRefs(possibleCombo));
       if (nsAccUtils::Role(possibleCombo) == nsIAccessibleRole::ROLE_COMBOBOX) {
         *aRole = nsIAccessibleRole::ROLE_COMBOBOX_LIST;
@@ -1350,19 +1292,17 @@ nsAccessible::GetRole(PRUint32 *aRole)
       else {   // Check to see if combo owns the listbox instead
         possibleCombo = nsRelUtils::
           GetRelatedAccessible(this, nsIAccessibleRelation::RELATION_NODE_CHILD_OF);
         if (nsAccUtils::Role(possibleCombo) == nsIAccessibleRole::ROLE_COMBOBOX)
           *aRole = nsIAccessibleRole::ROLE_COMBOBOX_LIST;
       }
     }
     else if (*aRole == nsIAccessibleRole::ROLE_OPTION) {
-      nsCOMPtr<nsIAccessible> parent;
-      GetParent(getter_AddRefs(parent));
-      if (nsAccUtils::Role(parent) == nsIAccessibleRole::ROLE_COMBOBOX_LIST)
+      if (nsAccUtils::Role(GetParent()) == nsIAccessibleRole::ROLE_COMBOBOX_LIST)
         *aRole = nsIAccessibleRole::ROLE_COMBOBOX_OPTION;
     }
 
     // We are done if the mapped role trumps native semantics
     if (mRoleMapEntry->roleRule == kUseMapRole)
       return NS_OK;
   }
 
@@ -1372,42 +1312,37 @@ nsAccessible::GetRole(PRUint32 *aRole)
 NS_IMETHODIMP
 nsAccessible::GetAttributes(nsIPersistentProperties **aAttributes)
 {
   NS_ENSURE_ARG_POINTER(aAttributes);  // In/out param. Created if necessary.
   
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
-  nsCOMPtr<nsIContent> content = nsCoreUtils::GetRoleContent(mDOMNode);
-  if (!content) {
-    return NS_ERROR_FAILURE;
-  }
-
   nsCOMPtr<nsIPersistentProperties> attributes = *aAttributes;
   if (!attributes) {
     // Create only if an array wasn't already passed in
     attributes = do_CreateInstance(NS_PERSISTENTPROPERTIES_CONTRACTID);
     NS_ENSURE_TRUE(attributes, NS_ERROR_OUT_OF_MEMORY);
     NS_ADDREF(*aAttributes = attributes);
   }
  
   nsresult rv = GetAttributesInternal(attributes);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsAutoString id;
   nsAutoString oldValueUnused;
-  if (nsCoreUtils::GetID(content, id)) {
+  if (nsCoreUtils::GetID(mContent, id)) {
     // Expose ID. If an <iframe id> exists override the one on the <body> of the source doc,
     // because the specific instance is what makes the ID useful for scripts
     attributes->SetStringProperty(NS_LITERAL_CSTRING("id"), id, oldValueUnused);
   }
   
   nsAutoString xmlRoles;
-  if (content->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::role, xmlRoles)) {
+  if (mContent->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::role, xmlRoles)) {
     attributes->SetStringProperty(NS_LITERAL_CSTRING("xml-roles"),  xmlRoles, oldValueUnused);          
   }
 
   nsCOMPtr<nsIAccessibleValue> supportsValue = do_QueryInterface(static_cast<nsIAccessible*>(this));
   if (supportsValue) {
     // We support values, so expose the string value as well, via the valuetext object attribute
     // We test for the value interface because we don't want to expose traditional get_accValue()
     // information such as URL's on links and documents, or text in an input
@@ -1422,32 +1357,32 @@ nsAccessible::GetAttributes(nsIPersisten
 
   // Group attributes (level/setsize/posinset)
   PRInt32 level = 0, posInSet = 0, setSize = 0;
   rv = GroupPosition(&level, &setSize, &posInSet);
   if (NS_SUCCEEDED(rv))
     nsAccUtils::SetAccGroupAttrs(attributes, level, setSize, posInSet);
 
   // Expose object attributes from ARIA attributes.
-  PRUint32 numAttrs = content->GetAttrCount();
+  PRUint32 numAttrs = mContent->GetAttrCount();
   for (PRUint32 count = 0; count < numAttrs; count ++) {
-    const nsAttrName *attr = content->GetAttrNameAt(count);
+    const nsAttrName *attr = mContent->GetAttrNameAt(count);
     if (attr && attr->NamespaceEquals(kNameSpaceID_None)) {
       nsIAtom *attrAtom = attr->Atom();
       nsDependentAtomString attrStr(attrAtom);
       if (!StringBeginsWith(attrStr, NS_LITERAL_STRING("aria-"))) 
         continue; // Not ARIA
       PRUint8 attrFlags = nsAccUtils::GetAttributeCharacteristics(attrAtom);
       if (attrFlags & ATTR_BYPASSOBJ)
         continue; // No need to handle exposing as obj attribute here
       if ((attrFlags & ATTR_VALTOKEN) &&
-          !nsAccUtils::HasDefinedARIAToken(content, attrAtom))
+          !nsAccUtils::HasDefinedARIAToken(mContent, attrAtom))
         continue; // only expose token based attributes if they are defined
       nsAutoString value;
-      if (content->GetAttr(kNameSpaceID_None, attrAtom, value)) {
+      if (mContent->GetAttr(kNameSpaceID_None, attrAtom, value)) {
         attributes->SetStringProperty(NS_ConvertUTF16toUTF8(Substring(attrStr, 5)), value, oldValueUnused);
       }
     }
   }
 
   // If there is no aria-live attribute then expose default value of 'live'
   // object attribute used for ARIA role of this accessible.
   if (mRoleMapEntry) {
@@ -1462,53 +1397,48 @@ nsAccessible::GetAttributes(nsIPersisten
   return NS_OK;
 }
 
 nsresult
 nsAccessible::GetAttributesInternal(nsIPersistentProperties *aAttributes)
 {
   // Attributes set by this method will not be used to override attributes on a sub-document accessible
   // when there is a <frame>/<iframe> element that spawned the sub-document
-  nsIContent *content = nsCoreUtils::GetRoleContent(mDOMNode);
-  nsCOMPtr<nsIDOMElement> element(do_QueryInterface(content));
-  NS_ENSURE_TRUE(element, NS_ERROR_UNEXPECTED);
+  nsCOMPtr<nsIDOMElement> element(do_QueryInterface(mContent));
 
   nsAutoString tagName;
   element->GetTagName(tagName);
   if (!tagName.IsEmpty()) {
     nsAutoString oldValueUnused;
     aAttributes->SetStringProperty(NS_LITERAL_CSTRING("tag"), tagName,
                                    oldValueUnused);
   }
 
-  nsEventShell::GetEventAttributes(mDOMNode, aAttributes);
+  nsEventShell::GetEventAttributes(GetNode(), aAttributes);
  
   // Expose class because it may have useful microformat information
   // Let the class from an iframe's document be exposed, don't override from <iframe class>
   nsAutoString _class;
-  if (content->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::_class, _class))
+  if (mContent->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::_class, _class))
     nsAccUtils::SetAccAttr(aAttributes, nsAccessibilityAtoms::_class, _class);
 
   // Get container-foo computed live region properties based on the closest container with
   // the live region attribute. 
   // Inner nodes override outer nodes within the same document --
   //   The inner nodes can be used to override live region behavior on more general outer nodes
   // However, nodes in outer documents override nodes in inner documents:
   //   Outer doc author may want to override properties on a widget they used in an iframe
-  nsCOMPtr<nsIDOMNode> startNode = mDOMNode;
-  nsIContent *startContent = content;
+  nsIContent *startContent = mContent;
   while (PR_TRUE) {
     NS_ENSURE_STATE(startContent);
     nsIDocument *doc = startContent->GetDocument();
-    nsCOMPtr<nsIDOMNode> docNode = do_QueryInterface(doc);
-    NS_ENSURE_STATE(docNode);
-    nsIContent *topContent = nsCoreUtils::GetRoleContent(docNode);
-    NS_ENSURE_STATE(topContent);
+    nsIContent* rootContent = nsCoreUtils::GetRoleContent(doc);
+    NS_ENSURE_STATE(rootContent);
     nsAccUtils::SetLiveContainerAttributes(aAttributes, startContent,
-                                           topContent);
+                                           rootContent);
 
     // Allow ARIA live region markup from outer documents to override
     nsCOMPtr<nsISupports> container = doc->GetContainer(); 
     nsCOMPtr<nsIDocShellTreeItem> docShellTreeItem =
       do_QueryInterface(container);
     if (!docShellTreeItem)
       break;
 
@@ -1543,17 +1473,17 @@ nsAccessible::GetAttributesInternal(nsIP
   // Expose 'text-indent' attribute.
   rv = GetComputedStyleValue(EmptyString(), NS_LITERAL_STRING("text-indent"),
                              value);
   if (NS_SUCCEEDED(rv))
     nsAccUtils::SetAccAttr(aAttributes, nsAccessibilityAtoms::textIndent,
                            value);
 
   // Expose draggable object attribute?
-  nsCOMPtr<nsIDOMNSHTMLElement> htmlElement = do_QueryInterface(content);
+  nsCOMPtr<nsIDOMNSHTMLElement> htmlElement = do_QueryInterface(mContent);
   if (htmlElement) {
     PRBool draggable = PR_FALSE;
     htmlElement->GetDraggable(&draggable);
     if (draggable) {
       nsAccUtils::SetAccAttr(aAttributes, nsAccessibilityAtoms::draggable,
                              NS_LITERAL_STRING("true"));
     }
   }
@@ -1574,25 +1504,21 @@ nsAccessible::GroupPosition(PRInt32 *aGr
 
   NS_ENSURE_ARG_POINTER(aPositionInGroup);
   *aPositionInGroup = 0;
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
   // Get group position from ARIA attributes.
-  nsCOMPtr<nsIContent> content = nsCoreUtils::GetRoleContent(mDOMNode);
-  if (!content)
-    return NS_OK;
-
-  nsCoreUtils::GetUIntAttr(content, nsAccessibilityAtoms::aria_level,
+  nsCoreUtils::GetUIntAttr(mContent, nsAccessibilityAtoms::aria_level,
                            aGroupLevel);
-  nsCoreUtils::GetUIntAttr(content, nsAccessibilityAtoms::aria_posinset,
+  nsCoreUtils::GetUIntAttr(mContent, nsAccessibilityAtoms::aria_posinset,
                            aPositionInGroup);
-  nsCoreUtils::GetUIntAttr(content, nsAccessibilityAtoms::aria_setsize,
+  nsCoreUtils::GetUIntAttr(mContent, nsAccessibilityAtoms::aria_setsize,
                            aSimilarItemsInGroup);
 
   // If ARIA is missed and the accessible is visible then calculate group
   // position from hierarchy.
   if (nsAccUtils::State(this) & nsIAccessibleStates::STATE_INVISIBLE)
     return NS_OK;
 
   // Calculate group level if ARIA is missed.
@@ -1642,24 +1568,19 @@ nsAccessible::GetState(PRUint32 *aState,
       *aState |= nsIAccessibleStates::STATE_SELECTED;
     } else {
       // Expose 'selected' state on ARIA tab if the focus is on internal element
       // of related tabpanel.
       nsCOMPtr<nsIAccessible> tabPanel = nsRelUtils::
         GetRelatedAccessible(this, nsIAccessibleRelation::RELATION_LABEL_FOR);
 
       if (nsAccUtils::Role(tabPanel) == nsIAccessibleRole::ROLE_PROPERTYPAGE) {
-        nsCOMPtr<nsIAccessNode> tabPanelAccessNode(do_QueryInterface(tabPanel));
-        nsCOMPtr<nsIDOMNode> tabPanelDOMNode;
-        tabPanelAccessNode->GetDOMNode(getter_AddRefs(tabPanelDOMNode));
-        NS_ENSURE_STATE(tabPanelDOMNode);
-
-        nsCOMPtr<nsINode> tabPanelNode(do_QueryInterface(tabPanelDOMNode));
-        nsCOMPtr<nsINode> lastFocusedNode(do_QueryInterface(gLastFocusedNode));
-        if (nsCoreUtils::IsAncestorOf(tabPanelNode, lastFocusedNode))
+        nsRefPtr<nsAccessible> tabPanelAcc(do_QueryObject(tabPanel));
+        nsINode *tabPanelNode = tabPanelAcc->GetNode();
+        if (nsCoreUtils::IsAncestorOf(tabPanelNode, gLastFocusedNode))
           *aState |= nsIAccessibleStates::STATE_SELECTED;
       }
     }
   }
 
   const PRUint32 kExpandCollapseStates =
     nsIAccessibleStates::STATE_COLLAPSED | nsIAccessibleStates::STATE_EXPANDED;
   if ((*aState & kExpandCollapseStates) == kExpandCollapseStates) {
@@ -1684,20 +1605,19 @@ nsAccessible::GetState(PRUint32 *aState,
       (*aState & nsIAccessibleStates::STATE_EXPANDED))
     *aExtraState |= nsIAccessibleStates::EXT_STATE_EXPANDABLE;
 
   if (mRoleMapEntry) {
     // If an object has an ancestor with the activedescendant property
     // pointing at it, we mark it as ACTIVE even if it's not currently focused.
     // This allows screen reader virtual buffer modes to know which descendant
     // is the current one that would get focus if the user navigates to the container widget.
-    nsCOMPtr<nsIContent> content = do_QueryInterface(mDOMNode);
     nsAutoString id;
-    if (content && nsCoreUtils::GetID(content, id)) {
-      nsIContent *ancestorContent = content;
+    if (nsCoreUtils::GetID(mContent, id)) {
+      nsIContent *ancestorContent = mContent;
       nsAutoString activeID;
       while ((ancestorContent = ancestorContent->GetParent()) != nsnull) {
         if (ancestorContent->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_activedescendant, activeID)) {
           if (id == activeID) {
             *aExtraState |= nsIAccessibleStates::EXT_STATE_ACTIVE;
           }
           break;
         }
@@ -1738,110 +1658,105 @@ nsAccessible::GetState(PRUint32 *aState,
  
   return NS_OK;
 }
 
 nsresult
 nsAccessible::GetARIAState(PRUint32 *aState, PRUint32 *aExtraState)
 {
   // Test for universal states first
-  nsIContent *content = nsCoreUtils::GetRoleContent(mDOMNode);
-  if (!content) {
-    return NS_OK;
-  }
-
   PRUint32 index = 0;
-  while (nsStateMapEntry::MapToStates(content, aState, aExtraState,
+  while (nsStateMapEntry::MapToStates(mContent, aState, aExtraState,
                                       nsARIAMap::gWAIUnivStateMap[index])) {
     ++ index;
   }
 
   if (mRoleMapEntry) {
 
     // We only force the readonly bit off if we have a real mapping for the aria
     // role. This preserves the ability for screen readers to use readonly
     // (primarily on the document) as the hint for creating a virtual buffer.
     if (mRoleMapEntry->role != nsIAccessibleRole::ROLE_NOTHING)
       *aState &= ~nsIAccessibleStates::STATE_READONLY;
 
-    if (content->HasAttr(kNameSpaceID_None, content->GetIDAttributeName())) {
+    if (mContent->HasAttr(kNameSpaceID_None, mContent->GetIDAttributeName())) {
       // If has a role & ID and aria-activedescendant on the container, assume focusable
-      nsIContent *ancestorContent = content;
+      nsIContent *ancestorContent = mContent;
       while ((ancestorContent = ancestorContent->GetParent()) != nsnull) {
         if (ancestorContent->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_activedescendant)) {
             // ancestor has activedescendant property, this content could be active
           *aState |= nsIAccessibleStates::STATE_FOCUSABLE;
           break;
         }
       }
     }
   }
 
   if (*aState & nsIAccessibleStates::STATE_FOCUSABLE) {
     // Special case: aria-disabled propagates from ancestors down to any focusable descendant
-    nsIContent *ancestorContent = content;
+    nsIContent *ancestorContent = mContent;
     while ((ancestorContent = ancestorContent->GetParent()) != nsnull) {
       if (ancestorContent->AttrValueIs(kNameSpaceID_None, nsAccessibilityAtoms::aria_disabled,
                                        nsAccessibilityAtoms::_true, eCaseMatters)) {
           // ancestor has aria-disabled property, this is disabled
         *aState |= nsIAccessibleStates::STATE_UNAVAILABLE;
         break;
       }
     }    
   }
 
   if (!mRoleMapEntry)
     return NS_OK;
 
   // Note: the readonly bitflag will be overridden later if content is editable
   *aState |= mRoleMapEntry->state;
-  if (nsStateMapEntry::MapToStates(content, aState, aExtraState,
+  if (nsStateMapEntry::MapToStates(mContent, aState, aExtraState,
                                    mRoleMapEntry->attributeMap1) &&
-      nsStateMapEntry::MapToStates(content, aState, aExtraState,
+      nsStateMapEntry::MapToStates(mContent, aState, aExtraState,
                                    mRoleMapEntry->attributeMap2)) {
-    nsStateMapEntry::MapToStates(content, aState, aExtraState,
+    nsStateMapEntry::MapToStates(mContent, aState, aExtraState,
                                  mRoleMapEntry->attributeMap3);
   }
 
   return NS_OK;
 }
 
 // Not implemented by this class
 
 /* DOMString getValue (); */
 NS_IMETHODIMP
 nsAccessible::GetValue(nsAString& aValue)
 {
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
-  nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
-  if (!content)
-    return NS_OK;
-
   if (mRoleMapEntry) {
     if (mRoleMapEntry->valueRule == eNoValue) {
       return NS_OK;
     }
 
     // aria-valuenow is a number, and aria-valuetext is the optional text equivalent
     // For the string value, we will try the optional text equivalent first
-    if (!content->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_valuetext, aValue)) {
-      content->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_valuenow, aValue);
+    if (!mContent->GetAttr(kNameSpaceID_None,
+                           nsAccessibilityAtoms::aria_valuetext, aValue)) {
+      mContent->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_valuenow,
+                        aValue);
     }
   }
 
   if (!aValue.IsEmpty())
     return NS_OK;
 
   // Check if it's a simple xlink.
-  if (nsCoreUtils::IsXLink(content)) {
+  if (nsCoreUtils::IsXLink(mContent)) {
     nsCOMPtr<nsIPresShell> presShell(do_QueryReferent(mWeakShell));
-    if (presShell)
-      return presShell->GetLinkLocation(mDOMNode, aValue);
+    if (presShell) {
+      nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent));
+      return presShell->GetLinkLocation(DOMNode, aValue);
+    }
   }
 
   return NS_OK;
 }
 
 // nsIAccessibleValue
 NS_IMETHODIMP
 nsAccessible::GetMaximumValue(double *aMaximumValue)
@@ -1869,18 +1784,18 @@ NS_IMETHODIMP
 nsAccessible::GetCurrentValue(double *aValue)
 {
   return GetAttrValue(nsAccessibilityAtoms::aria_valuenow, aValue);
 }
 
 NS_IMETHODIMP
 nsAccessible::SetCurrentValue(double aValue)
 {
-  if (!mDOMNode)
-    return NS_ERROR_FAILURE;  // Node already shut down
+  if (IsDefunct())
+    return NS_ERROR_FAILURE;
 
   if (!mRoleMapEntry || mRoleMapEntry->valueRule == eNoValue)
     return NS_OK_NO_ARIA_VALUE;
 
   const PRUint32 kValueCannotChange = nsIAccessibleStates::STATE_READONLY |
                                       nsIAccessibleStates::STATE_UNAVAILABLE;
 
   if (nsAccUtils::State(this) & kValueCannotChange)
@@ -1889,23 +1804,21 @@ nsAccessible::SetCurrentValue(double aVa
   double minValue = 0;
   if (NS_SUCCEEDED(GetMinimumValue(&minValue)) && aValue < minValue)
     return NS_ERROR_INVALID_ARG;
 
   double maxValue = 0;
   if (NS_SUCCEEDED(GetMaximumValue(&maxValue)) && aValue > maxValue)
     return NS_ERROR_INVALID_ARG;
 
-  nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
-  NS_ENSURE_STATE(content);
-
   nsAutoString newValue;
   newValue.AppendFloat(aValue);
-  return content->SetAttr(kNameSpaceID_None,
-                          nsAccessibilityAtoms::aria_valuenow, newValue, PR_TRUE);
+  return mContent->SetAttr(kNameSpaceID_None,
+                           nsAccessibilityAtoms::aria_valuenow, newValue,
+                           PR_TRUE);
 }
 
 /* void setName (in DOMString name); */
 NS_IMETHODIMP nsAccessible::SetName(const nsAString& name)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
@@ -1941,18 +1854,17 @@ nsAccessible::GetKeyBindings(PRUint8 aAc
 nsresult
 nsAccessible::GetRoleInternal(PRUint32 *aRole)
 {
   *aRole = nsIAccessibleRole::ROLE_NOTHING;
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
-  nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
-  if (nsCoreUtils::IsXLink(content))
+  if (nsCoreUtils::IsXLink(mContent))
     *aRole = nsIAccessibleRole::ROLE_LINK;
 
   return NS_OK;
 }
 
 // readonly attribute PRUint8 numActions
 NS_IMETHODIMP
 nsAccessible::GetNumActions(PRUint8 *aNumActions)
@@ -2095,18 +2007,17 @@ NS_IMETHODIMP nsAccessible::GetAccessibl
 /* nsIAccessible getAccessibleBelow(); */
 NS_IMETHODIMP nsAccessible::GetAccessibleBelow(nsIAccessible **_retval)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 nsIDOMNode* nsAccessible::GetAtomicRegion()
 {
-  nsCOMPtr<nsIContent> content = nsCoreUtils::GetRoleContent(mDOMNode);
-  nsIContent *loopContent = content;
+  nsIContent *loopContent = mContent;
   nsAutoString atomic;
   while (loopContent && !loopContent->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_atomic, atomic)) {
     loopContent = loopContent->GetParent();
   }
 
   nsCOMPtr<nsIDOMNode> atomicRegion;
   if (atomic.EqualsLiteral("true")) {
     atomicRegion = do_QueryInterface(loopContent);
@@ -2122,114 +2033,109 @@ nsAccessible::GetRelationByType(PRUint32
   NS_ENSURE_ARG_POINTER(aRelation);
   *aRelation = nsnull;
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
   // Relationships are defined on the same content node that the role would be
   // defined on.
-  nsIContent *content = nsCoreUtils::GetRoleContent(mDOMNode);
-  if (!content)
-    return NS_OK;
-
   nsresult rv;
-
   switch (aRelationType)
   {
   case nsIAccessibleRelation::RELATION_LABEL_FOR:
     {
-      if (content->Tag() == nsAccessibilityAtoms::label) {
-        nsIAtom *IDAttr = content->IsHTML() ?
+      if (mContent->Tag() == nsAccessibilityAtoms::label) {
+        nsIAtom *IDAttr = mContent->IsHTML() ?
           nsAccessibilityAtoms::_for : nsAccessibilityAtoms::control;
         rv = nsRelUtils::
-          AddTargetFromIDRefAttr(aRelationType, aRelation, content, IDAttr);
+          AddTargetFromIDRefAttr(aRelationType, aRelation, mContent, IDAttr);
         NS_ENSURE_SUCCESS(rv, rv);
 
         if (rv != NS_OK_NO_RELATION_TARGET)
           return NS_OK; // XXX bug 381599, avoid performance problems
       }
 
       return nsRelUtils::
-        AddTargetFromNeighbour(aRelationType, aRelation, content,
+        AddTargetFromNeighbour(aRelationType, aRelation, mContent,
                                nsAccessibilityAtoms::aria_labelledby);
     }
 
   case nsIAccessibleRelation::RELATION_LABELLED_BY:
     {
       rv = nsRelUtils::
-        AddTargetFromIDRefsAttr(aRelationType, aRelation, content,
+        AddTargetFromIDRefsAttr(aRelationType, aRelation, mContent,
                                 nsAccessibilityAtoms::aria_labelledby);
       NS_ENSURE_SUCCESS(rv, rv);
 
       if (rv != NS_OK_NO_RELATION_TARGET)
         return NS_OK; // XXX bug 381599, avoid performance problems
 
       return nsRelUtils::
         AddTargetFromContent(aRelationType, aRelation,
-                             nsCoreUtils::GetLabelContent(content));
+                             nsCoreUtils::GetLabelContent(mContent));
     }
 
   case nsIAccessibleRelation::RELATION_DESCRIBED_BY:
     {
       rv = nsRelUtils::
-        AddTargetFromIDRefsAttr(aRelationType, aRelation, content,
+        AddTargetFromIDRefsAttr(aRelationType, aRelation, mContent,
                                 nsAccessibilityAtoms::aria_describedby);
       NS_ENSURE_SUCCESS(rv, rv);
 
       if (rv != NS_OK_NO_RELATION_TARGET)
         return NS_OK; // XXX bug 381599, avoid performance problems
 
       return nsRelUtils::
-        AddTargetFromNeighbour(aRelationType, aRelation, content,
+        AddTargetFromNeighbour(aRelationType, aRelation, mContent,
                                nsAccessibilityAtoms::control,
                                nsAccessibilityAtoms::description);
     }
 
   case nsIAccessibleRelation::RELATION_DESCRIPTION_FOR:
     {
       rv = nsRelUtils::
-        AddTargetFromNeighbour(aRelationType, aRelation, content,
+        AddTargetFromNeighbour(aRelationType, aRelation, mContent,
                                nsAccessibilityAtoms::aria_describedby);
       NS_ENSURE_SUCCESS(rv, rv);
 
       if (rv != NS_OK_NO_RELATION_TARGET)
         return NS_OK; // XXX bug 381599, avoid performance problems
 
-      if (content->Tag() == nsAccessibilityAtoms::description &&
-          content->IsXUL()) {
+      if (mContent->Tag() == nsAccessibilityAtoms::description &&
+          mContent->IsXUL()) {
         // This affectively adds an optional control attribute to xul:description,
         // which only affects accessibility, by allowing the description to be
         // tied to a control.
         return nsRelUtils::
-          AddTargetFromIDRefAttr(aRelationType, aRelation, content,
+          AddTargetFromIDRefAttr(aRelationType, aRelation, mContent,
                                  nsAccessibilityAtoms::control);
       }
 
       return NS_OK;
     }
 
   case nsIAccessibleRelation::RELATION_NODE_CHILD_OF:
     {
       rv = nsRelUtils::
-        AddTargetFromNeighbour(aRelationType, aRelation, content,
+        AddTargetFromNeighbour(aRelationType, aRelation, mContent,
                                nsAccessibilityAtoms::aria_owns);
       NS_ENSURE_SUCCESS(rv, rv);
 
       if (rv != NS_OK_NO_RELATION_TARGET)
         return NS_OK; // XXX bug 381599, avoid performance problems
 
       // This is an ARIA tree or treegrid that doesn't use owns, so we need to
       // get the parent the hard way.
       if (mRoleMapEntry &&
           (mRoleMapEntry->role == nsIAccessibleRole::ROLE_OUTLINEITEM ||
            mRoleMapEntry->role == nsIAccessibleRole::ROLE_ROW)) {
 
         nsCOMPtr<nsIAccessible> accTarget;
-        nsAccUtils::GetARIATreeItemParent(this, content,
+        nsAccUtils::GetARIATreeItemParent(this, mContent,
                                           getter_AddRefs(accTarget));
 
         return nsRelUtils::AddTarget(aRelationType, aRelation, accTarget);
       }
 
       // If accessible is in its own Window, or is the root of a document,
       // then we should provide NODE_CHILD_OF relation so that MSAA clients
       // can easily get to true parent instead of getting to oleacc's
@@ -2248,61 +2154,62 @@ nsAccessible::GetRelationByType(PRUint32
       }
 
       return NS_OK;
     }
 
   case nsIAccessibleRelation::RELATION_CONTROLLED_BY:
     {
       return nsRelUtils::
-        AddTargetFromNeighbour(aRelationType, aRelation, content,
+        AddTargetFromNeighbour(aRelationType, aRelation, mContent,
                                nsAccessibilityAtoms::aria_controls);
     }
 
   case nsIAccessibleRelation::RELATION_CONTROLLER_FOR:
     {
       return nsRelUtils::
-        AddTargetFromIDRefsAttr(aRelationType, aRelation, content,
+        AddTargetFromIDRefsAttr(aRelationType, aRelation, mContent,
                                 nsAccessibilityAtoms::aria_controls);
     }
 
   case nsIAccessibleRelation::RELATION_FLOWS_TO:
     {
       return nsRelUtils::
-        AddTargetFromIDRefsAttr(aRelationType, aRelation, content,
+        AddTargetFromIDRefsAttr(aRelationType, aRelation, mContent,
                                 nsAccessibilityAtoms::aria_flowto);
     }
 
   case nsIAccessibleRelation::RELATION_FLOWS_FROM:
     {
       return nsRelUtils::
-        AddTargetFromNeighbour(aRelationType, aRelation, content,
+        AddTargetFromNeighbour(aRelationType, aRelation, mContent,
                                nsAccessibilityAtoms::aria_flowto);
     }
 
   case nsIAccessibleRelation::RELATION_DEFAULT_BUTTON:
     {
-      if (content->IsHTML()) {
+      if (mContent->IsHTML()) {
         // HTML form controls implements nsIFormControl interface.
-        nsCOMPtr<nsIFormControl> control(do_QueryInterface(content));
+        nsCOMPtr<nsIFormControl> control(do_QueryInterface(mContent));
         if (control) {
           nsCOMPtr<nsIDOMHTMLFormElement> htmlform;
           control->GetForm(getter_AddRefs(htmlform));
           nsCOMPtr<nsIForm> form(do_QueryInterface(htmlform));
           if (form) {
             nsCOMPtr<nsIContent> formContent =
               do_QueryInterface(form->GetDefaultSubmitElement());
             return nsRelUtils::AddTargetFromContent(aRelationType, aRelation,
                                                     formContent);
           }
         }
       }
       else {
         // In XUL, use first <button default="true" .../> in the document
-        nsCOMPtr<nsIDOMXULDocument> xulDoc = do_QueryInterface(content->GetDocument());
+        nsCOMPtr<nsIDOMXULDocument> xulDoc =
+          do_QueryInterface(mContent->GetOwnerDoc());
         nsCOMPtr<nsIDOMXULButtonElement> buttonEl;
         if (xulDoc) {
           nsCOMPtr<nsIDOMNodeList> possibleDefaultButtons;
           xulDoc->GetElementsByAttribute(NS_LITERAL_STRING("default"),
                                          NS_LITERAL_STRING("true"),
                                          getter_AddRefs(possibleDefaultButtons));
           if (possibleDefaultButtons) {
             PRUint32 length;
@@ -2431,22 +2338,19 @@ NS_IMETHODIMP nsAccessible::ExtendSelect
 NS_IMETHODIMP nsAccessible::GetNativeInterface(void **aOutAccessible)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 void
 nsAccessible::DoCommand(nsIContent *aContent, PRUint32 aActionIndex)
 {
-  nsCOMPtr<nsIContent> content = aContent;
-  if (!content)
-    content = nsCoreUtils::GetRoleContent(mDOMNode);
-
-  NS_DISPATCH_RUNNABLEMETHOD_ARG2(DispatchClickEvent, this,
-                                  content, aActionIndex)
+  nsIContent* content = aContent ? aContent : mContent.get();
+  NS_DISPATCH_RUNNABLEMETHOD_ARG2(DispatchClickEvent, this, content,
+                                  aActionIndex);
 }
 
 void
 nsAccessible::DispatchClickEvent(nsIContent *aContent, PRUint32 aActionIndex)
 {
   if (IsDefunct())
     return;
 
@@ -2469,17 +2373,17 @@ nsAccessible::DispatchClickEvent(nsICont
 NS_IMETHODIMP nsAccessible::GetSelectedChildren(nsIArray **aSelectedAccessibles)
 {
   *aSelectedAccessibles = nsnull;
 
   nsCOMPtr<nsIMutableArray> selectedAccessibles =
     do_CreateInstance(NS_ARRAY_CONTRACTID);
   NS_ENSURE_STATE(selectedAccessibles);
 
-  nsAccIterator iter(this, nsAccIterator::GetSelected, nsAccIterator::eTreeNav);
+  AccIterator iter(this, filters::GetSelected, AccIterator::eTreeNav);
   nsIAccessible *selected = nsnull;
   while ((selected = iter.GetNext()))
     selectedAccessibles->AppendElement(selected, PR_FALSE);
 
   PRUint32 length = 0;
   selectedAccessibles->GetLength(&length); 
   if (length) { // length of nsIArray containing selected options
     *aSelectedAccessibles = selectedAccessibles;
@@ -2494,17 +2398,17 @@ NS_IMETHODIMP nsAccessible::RefSelection
 {
   NS_ENSURE_ARG_POINTER(aSelected);
   *aSelected = nsnull;
 
   if (aIndex < 0) {
     return NS_ERROR_INVALID_ARG;
   }
 
-  nsAccIterator iter(this, nsAccIterator::GetSelected, nsAccIterator::eTreeNav);
+  AccIterator iter(this, filters::GetSelected, AccIterator::eTreeNav);
   nsAccessible *selected = nsnull;
 
   PRInt32 count = 0;
   while (count ++ <= aIndex) {
     selected = iter.GetNext();
     if (!selected) {
       // The index is out of range.
       return NS_ERROR_INVALID_ARG;
@@ -2514,17 +2418,17 @@ NS_IMETHODIMP nsAccessible::RefSelection
   return NS_OK;
 }
 
 NS_IMETHODIMP nsAccessible::GetSelectionCount(PRInt32 *aSelectionCount)
 {
   NS_ENSURE_ARG_POINTER(aSelectionCount);
   *aSelectionCount = 0;
 
-  nsAccIterator iter(this, nsAccIterator::GetSelected, nsAccIterator::eTreeNav);
+  AccIterator iter(this, filters::GetSelected, AccIterator::eTreeNav);
   nsAccessible *selected = nsnull;
   while ((selected = iter.GetNext()))
     ++(*aSelectionCount);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP nsAccessible::AddChildToSelection(PRInt32 aIndex)
@@ -2576,27 +2480,27 @@ NS_IMETHODIMP nsAccessible::IsChildSelec
     *aIsSelected = PR_TRUE;
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsAccessible::ClearSelection()
 {
-  nsAccIterator iter(this, nsAccIterator::GetSelected, nsAccIterator::eTreeNav);
+  AccIterator iter(this, filters::GetSelected, AccIterator::eTreeNav);
   nsAccessible *selected = nsnull;
   while ((selected = iter.GetNext()))
     selected->SetSelected(PR_FALSE);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP nsAccessible::SelectAllSelection(PRBool *_retval)
 {
-  nsAccIterator iter(this, nsAccIterator::GetSelectable, nsAccIterator::eTreeNav);
+  AccIterator iter(this, filters::GetSelectable, AccIterator::eTreeNav);
   nsAccessible *selectable = nsnull;
   while((selectable = iter.GetNext()))
     selectable->SetSelected(PR_TRUE);
 
   return NS_OK;
 }
 
 // nsIAccessibleHyperLink
@@ -2646,23 +2550,22 @@ nsAccessible::GetURI(PRInt32 aIndex, nsI
 {
   NS_ENSURE_ARG_POINTER(aURI);
   *aURI = nsnull;
 
   if (aIndex != 0)
     return NS_ERROR_INVALID_ARG;
 
   // Check if it's a simple xlink.
-  nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
-  if (nsCoreUtils::IsXLink(content)) {
+  if (nsCoreUtils::IsXLink(mContent)) {
     nsAutoString href;
-    content->GetAttr(kNameSpaceID_XLink, nsAccessibilityAtoms::href, href);
-
-    nsCOMPtr<nsIURI> baseURI = content->GetBaseURI();
-    nsCOMPtr<nsIDocument> document = content->GetOwnerDoc();
+    mContent->GetAttr(kNameSpaceID_XLink, nsAccessibilityAtoms::href, href);
+
+    nsCOMPtr<nsIURI> baseURI = mContent->GetBaseURI();
+    nsCOMPtr<nsIDocument> document = mContent->GetOwnerDoc();
     return NS_NewURI(aURI, href,
                      document ? document->GetDocumentCharacterSet().get() : nsnull,
                      baseURI);
   }
 
   return NS_OK;
 }
 
@@ -2696,17 +2599,18 @@ nsAccessible::GetValid(PRBool *aValid)
   return NS_OK;
 }
 
 // readonly attribute boolean nsIAccessibleHyperLink::selected
 NS_IMETHODIMP
 nsAccessible::GetSelected(PRBool *aSelected)
 {
   NS_ENSURE_ARG_POINTER(aSelected);
-  *aSelected = (gLastFocusedNode == mDOMNode);
+
+  *aSelected = (gLastFocusedNode == GetNode());
   return NS_OK;
 }
 
 nsresult
 nsAccessible::GetLinkOffset(PRInt32 *aStartOffset, PRInt32 *aEndOffset)
 {
   nsAccessible *parent = GetParent();
   NS_ENSURE_STATE(parent);
@@ -2749,28 +2653,75 @@ nsAccessible::AppendTextTo(nsAString& aT
   } else {
     aText += kEmbeddedObjectChar;
   }
 
   return NS_OK;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
+// nsAccessNode public methods
+
+PRBool
+nsAccessible::Init()
+{
+  if (!nsAccessNodeWrap::Init())
+    return PR_FALSE;
+
+  nsDocAccessible *docAcc =
+    GetAccService()->GetDocAccessible(mContent->GetOwnerDoc());
+  NS_ASSERTION(docAcc, "Cannot cache new nsAccessible!");
+  if (!docAcc)
+    return PR_FALSE;
+
+  void *uniqueID = nsnull;
+  GetUniqueID(&uniqueID);
+
+  if (!docAcc->CacheAccessible(uniqueID, this))
+    return PR_FALSE;
+
+  // Make sure an ancestor in real content is cached so that
+  // nsDocAccessible::RefreshNodes() can find the anonymous subtree to release
+  // when the root node goes away. /Specific examples of where this is used:
+  // <input type="file"> and <xul:findbar>.
+  // XXX: remove this once we create correct accessible tree.
+  if (mContent && mContent->IsInAnonymousSubtree()) {
+    nsAccessible *parent = GetAccService()->GetContainerAccessible(mContent,
+                                                                   PR_TRUE);
+    if (parent)
+      parent->EnsureChildren();
+  }
+
+  return PR_TRUE;
+}
+
+void
+nsAccessible::Shutdown()
+{
+  // Invalidate the child count and pointers to other accessibles, also make
+  // sure none of its children point to this parent
+  InvalidateChildren();
+  if (mParent) {
+    mParent->InvalidateChildren();
+    mParent = nsnull;
+  }
+
+  nsAccessNodeWrap::Shutdown();
+}
+
+////////////////////////////////////////////////////////////////////////////////
 // nsAccessible public methods
 
 nsresult
 nsAccessible::GetARIAName(nsAString& aName)
 {
-  nsCOMPtr<nsIContent> content = nsCoreUtils::GetRoleContent(mDOMNode);
-  if (!content)
-    return NS_OK;
-
   // First check for label override via aria-label property
   nsAutoString label;
-  if (content->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_label, label)) {
+  if (mContent->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_label,
+                        label)) {
     label.CompressWhitespace();
     aName = label;
     return NS_OK;
   }
   
   // Second check for label override via aria-labelledby relationship
   nsresult rv = nsTextEquivUtils::
     GetTextEquivFromIDRefs(this, nsAccessibilityAtoms::aria_labelledby, label);
@@ -2780,24 +2731,20 @@ nsAccessible::GetARIAName(nsAString& aNa
   }
 
   return rv;
 }
 
 nsresult
 nsAccessible::GetNameInternal(nsAString& aName)
 {
-  nsCOMPtr<nsIContent> content = nsCoreUtils::GetRoleContent(mDOMNode);
-  if (!content)
-    return NS_OK;
-
-  if (content->IsHTML())
+  if (mContent->IsHTML())
     return GetHTMLName(aName);
 
-  if (content->IsXUL())
+  if (mContent->IsXUL())
     return GetXULName(aName);
 
   return NS_OK;
 }
 
 void
 nsAccessible::SetParent(nsAccessible *aParent)
 {
@@ -2838,17 +2785,17 @@ nsAccessible::GetParent()
   if (mParent)
     return mParent;
 
 #ifdef DEBUG
   nsDocAccessible *docAccessible = GetDocAccessible();
   NS_ASSERTION(docAccessible, "No document accessible for valid accessible!");
 #endif
 
-  nsAccessible *parent = GetAccService()->GetContainerAccessible(mDOMNode,
+  nsAccessible *parent = GetAccService()->GetContainerAccessible(mContent,
                                                                  PR_TRUE);
   NS_ASSERTION(parent, "No accessible parent for valid accessible!");
   if (!parent)
     return nsnull;
 
 #ifdef DEBUG
   NS_ASSERTION(!parent->IsDefunct(), "Defunct parent!");
 
@@ -2912,24 +2859,40 @@ nsAccessible::GetCachedFirstChild()
 {
   if (IsDefunct())
     return nsnull;
 
   return mChildren.SafeElementAt(0, nsnull);
 }
 
 
+#ifdef DEBUG
+PRBool
+nsAccessible::IsInCache()
+{
+  nsDocAccessible *docAccessible =
+    GetAccService()->GetDocAccessible(mContent->GetOwnerDoc());
+  if (!docAccessible)
+    return nsnull;
+
+  void *uniqueID = nsnull;
+  GetUniqueID(&uniqueID);
+
+  return docAccessible->GetCachedAccessible(uniqueID) ? PR_TRUE : PR_FALSE;
+}
+#endif
+
+
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccessible protected methods
 
 void
 nsAccessible::CacheChildren()
 {
-  nsAccTreeWalker walker(mWeakShell, nsCoreUtils::GetRoleContent(mDOMNode),
-                         GetAllowsAnonChildAccessibles());
+  nsAccTreeWalker walker(mWeakShell, mContent, GetAllowsAnonChildAccessibles());
 
   nsRefPtr<nsAccessible> child;
   while ((child = walker.GetNextChild())) {
     mChildren.AppendElement(child);
     child->SetParent(this);
   }
 }
 
@@ -3010,45 +2973,27 @@ nsAccessible::GetSiblingAtOffset(PRInt32
   nsAccessible *child = parent->GetChildAt(indexInParent + aOffset);
   if (aError && !child)
     *aError = NS_ERROR_UNEXPECTED;
 
   return child;
 }
 
 nsAccessible *
-nsAccessible::GetFirstAvailableAccessible(nsIDOMNode *aStartNode) const
+nsAccessible::GetFirstAvailableAccessible(nsINode *aStartNode) const
 {
-  nsCOMPtr<nsIDOMTreeWalker> walker; 
-  nsCOMPtr<nsIDOMNode> currentNode(aStartNode);
-
-  while (currentNode) {
-    nsAccessible *accessible =
-      GetAccService()->GetAccessibleInWeakShell(currentNode, mWeakShell);
-    if (accessible)
-      return accessible;
-
-    if (!walker) {
-      // Instantiate walker lazily since we won't need it in 90% of the cases
-      // where the first DOM node we're given provides an accessible
-      nsCOMPtr<nsIDOMDocument> document;
-      currentNode->GetOwnerDocument(getter_AddRefs(document));
-      nsCOMPtr<nsIDOMDocumentTraversal> trav = do_QueryInterface(document);
-      NS_ASSERTION(trav, "No DOM document traversal for document");
-      NS_ENSURE_TRUE(trav, nsnull);
-      trav->CreateTreeWalker(mDOMNode, nsIDOMNodeFilter::SHOW_ELEMENT | nsIDOMNodeFilter::SHOW_TEXT,
-                            nsnull, PR_FALSE, getter_AddRefs(walker));
-      NS_ENSURE_TRUE(walker, nsnull);
-      walker->SetCurrentNode(currentNode);
-    }
-
-    walker->NextNode(getter_AddRefs(currentNode));
-  }
-
-  return nsnull;
+  nsAccessible *accessible =
+    GetAccService()->GetAccessibleInWeakShell(aStartNode, mWeakShell);
+  if (accessible)
+    return accessible;
+
+  nsIContent *content = nsCoreUtils::GetRoleContent(aStartNode);
+  nsAccTreeWalker walker(mWeakShell, content, PR_FALSE);
+  nsRefPtr<nsAccessible> childAccessible = walker.GetNextChild();
+  return childAccessible;
 }
 
 PRBool nsAccessible::CheckVisibilityInParentChain(nsIDocument* aDocument, nsIView* aView)
 {
   nsIDocument* document = aDocument;
   nsIView* view = aView;
   // both view chain and widget chain are broken between chrome and content
   while (document != nsnull) {
@@ -3091,21 +3036,18 @@ nsAccessible::GetAttrValue(nsIAtom *aPro
   *aValue = 0;
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;  // Node already shut down
 
  if (!mRoleMapEntry || mRoleMapEntry->valueRule == eNoValue)
     return NS_OK_NO_ARIA_VALUE;
 
-  nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
-  NS_ENSURE_STATE(content);
-
   nsAutoString attrValue;
-  content->GetAttr(kNameSpaceID_None, aProperty, attrValue);
+  mContent->GetAttr(kNameSpaceID_None, aProperty, attrValue);
 
   // Return zero value if there is no attribute or its value is empty.
   if (attrValue.IsEmpty())
     return NS_OK;
 
   PRInt32 error = NS_OK;
   double value = attrValue.ToFloat(&error);
   if (NS_SUCCEEDED(error))
@@ -3114,44 +3056,40 @@ nsAccessible::GetAttrValue(nsIAtom *aPro
   return NS_OK;
 }
 
 PRUint32
 nsAccessible::GetActionRule(PRUint32 aStates)
 {
   if (aStates & nsIAccessibleStates::STATE_UNAVAILABLE)
     return eNoAction;
-
-  nsIContent* content = nsCoreUtils::GetRoleContent(mDOMNode);
-  if (!content)
-    return eNoAction;
   
   // Check if it's simple xlink.
-  if (nsCoreUtils::IsXLink(content))
+  if (nsCoreUtils::IsXLink(mContent))
     return eJumpAction;
 
   // Return "click" action on elements that have an attached popup menu.
-  if (content->IsXUL())
-    if (content->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::popup))
+  if (mContent->IsXUL())
+    if (mContent->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::popup))
       return eClickAction;
 
   // Has registered 'click' event handler.
-  PRBool isOnclick = nsCoreUtils::HasClickListener(content);
+  PRBool isOnclick = nsCoreUtils::HasClickListener(mContent);
 
   if (isOnclick)
     return eClickAction;
   
   // Get an action based on ARIA role.
   if (mRoleMapEntry &&
       mRoleMapEntry->actionRule != eNoAction)
     return mRoleMapEntry->actionRule;
 
   // Get an action based on ARIA attribute.
-  if (nsAccUtils::HasDefinedARIAToken(content,
-                                   nsAccessibilityAtoms::aria_expanded))
+  if (nsAccUtils::HasDefinedARIAToken(mContent,
+                                      nsAccessibilityAtoms::aria_expanded))
     return eExpandAction;
 
   return eNoAction;
 }
 
 void
 nsAccessible::GetPositionAndSizeInternal(PRInt32 *aPosInSet, PRInt32 *aSetSize)
 {
@@ -3179,17 +3117,17 @@ nsAccessible::GetPositionAndSizeInternal
   PRInt32 indexInParent = parent->GetIndexOf(this);
   PRInt32 level = nsAccUtils::GetARIAOrDefaultLevel(this);
 
   // Compute 'posinset'.
   PRInt32 positionInGroup = 1;
   for (PRInt32 idx = indexInParent - 1; idx >= 0; idx--) {
     nsAccessible* sibling = parent->GetChildAt(idx);
 
-    PRUint32 siblingRole = siblingRole = nsAccUtils::Role(sibling);
+    PRUint32 siblingRole = nsAccUtils::Role(sibling);
 
     // If the sibling is separator then the group is ended.
     if (siblingRole == nsIAccessibleRole::ROLE_SEPARATOR)
       break;
 
     PRUint32 siblingBaseRole = siblingRole;
     if (siblingRole == nsIAccessibleRole::ROLE_CHECK_MENU_ITEM ||
         siblingRole == nsIAccessibleRole::ROLE_RADIO_MENU_ITEM)
--- a/accessible/src/base/nsAccessible.h
+++ b/accessible/src/base/nsAccessible.h
@@ -45,16 +45,17 @@
 #include "nsIAccessibleHyperLink.h"
 #include "nsIAccessibleSelectable.h"
 #include "nsIAccessibleValue.h"
 #include "nsIAccessibleRole.h"
 #include "nsIAccessibleStates.h"
 
 #include "nsStringGlue.h"
 #include "nsTArray.h"
+#include "nsRefPtrHashtable.h"
 
 class nsAccessible;
 class nsAccEvent;
 struct nsRoleMapEntry;
 
 struct nsRect;
 class nsIContent;
 class nsIFrame;
@@ -87,32 +88,33 @@ NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODUL
 
 class nsAccessible : public nsAccessNodeWrap, 
                      public nsIAccessible, 
                      public nsIAccessibleHyperLink,
                      public nsIAccessibleSelectable,
                      public nsIAccessibleValue
 {
 public:
-  nsAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell);
+  nsAccessible(nsIContent *aContent, nsIWeakReference *aShell);
   virtual ~nsAccessible();
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsAccessible, nsAccessNode)
 
   NS_DECL_NSIACCESSIBLE
   NS_DECL_NSIACCESSIBLEHYPERLINK
   NS_DECL_NSIACCESSIBLESELECTABLE
   NS_DECL_NSIACCESSIBLEVALUE
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_ACCESSIBLE_IMPL_IID)
 
   //////////////////////////////////////////////////////////////////////////////
   // nsAccessNode
 
-  virtual nsresult Shutdown();
+  virtual PRBool Init();
+  virtual void Shutdown();
 
   //////////////////////////////////////////////////////////////////////////////
   // Public methods
 
   /**
    * Returns the accessible name specified by ARIA.
    */
   nsresult GetARIAName(nsAString& aName);
@@ -265,16 +267,23 @@ public:
    */
   nsAccessible* GetCachedParent();
 
   /**
    * Return first child accessible only if cached.
    */
   nsAccessible* GetCachedFirstChild();
 
+#ifdef DEBUG
+  /**
+   * Return true if the access node is cached.
+   */
+  PRBool IsInCache();
+#endif
+
   //////////////////////////////////////////////////////////////////////////////
   // Miscellaneous methods
 
   /**
    * Handle accessible event, i.e. process it, notifies observers and fires
    * platform specific event.
    */
   virtual nsresult HandleAccEvent(nsAccEvent *aAccEvent);
@@ -344,17 +353,17 @@ protected:
   /**
    * Return an accessible for the given DOM node, or if that node isn't
    * accessible, return the accessible for the next DOM node which has one
    * (based on forward depth first search).
    *
    * @param  aStartNode  [in] the DOM node to start from
    * @return              the resulting accessible
    */
-  nsAccessible *GetFirstAvailableAccessible(nsIDOMNode *aStartNode) const;
+  nsAccessible *GetFirstAvailableAccessible(nsINode *aStartNode) const;
 
   // Hyperlink helpers
   virtual nsresult GetLinkOffset(PRInt32* aStartOffset, PRInt32* aEndOffset);
 
   //////////////////////////////////////////////////////////////////////////////
   // Action helpers
 
   /**
--- a/accessible/src/base/nsApplicationAccessible.cpp
+++ b/accessible/src/base/nsApplicationAccessible.cpp
@@ -59,29 +59,41 @@ nsApplicationAccessible::nsApplicationAc
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsISupports
 
 NS_IMPL_ISUPPORTS_INHERITED1(nsApplicationAccessible, nsAccessible,
                              nsIAccessibleApplication)
 
 ////////////////////////////////////////////////////////////////////////////////
-// nsIAccessNode
+// nsIAccessible
 
 NS_IMETHODIMP
-nsApplicationAccessible::GetRootDocument(nsIAccessibleDocument **aRootDocument)
+nsApplicationAccessible::GetParent(nsIAccessible **aAccessible)
 {
-  NS_ENSURE_ARG_POINTER(aRootDocument);
-  *aRootDocument = nsnull;
-
+  NS_ENSURE_ARG_POINTER(aAccessible);
+  *aAccessible = nsnull;
   return NS_OK;
 }
 
-////////////////////////////////////////////////////////////////////////////////
-// nsIAccessible
+NS_IMETHODIMP
+nsApplicationAccessible::GetNextSibling(nsIAccessible **aNextSibling)
+{
+  NS_ENSURE_ARG_POINTER(aNextSibling);
+  *aNextSibling = nsnull;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsApplicationAccessible::GetPreviousSibling(nsIAccessible **aPreviousSibling)
+{
+  NS_ENSURE_ARG_POINTER(aPreviousSibling);
+  *aPreviousSibling = nsnull;
+  return NS_OK;
+}
 
 NS_IMETHODIMP
 nsApplicationAccessible::GetName(nsAString& aName)
 {
   aName.Truncate();
 
   nsCOMPtr<nsIStringBundleService> bundleService =
     mozilla::services::GetStringBundleService();
@@ -102,49 +114,185 @@ nsApplicationAccessible::GetName(nsAStri
     appName.AssignLiteral("Gecko based application");
   }
 
   aName.Assign(appName);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsApplicationAccessible::GetDescription(nsAString& aValue)
+nsApplicationAccessible::GetValue(nsAString &aValue)
 {
   aValue.Truncate();
   return NS_OK;
 }
 
 NS_IMETHODIMP
+nsApplicationAccessible::GetDescription(nsAString &aDescription)
+{
+  aDescription.Truncate();
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsApplicationAccessible::GetKeyboardShortcut(nsAString &aKeyboardShortcut)
+{
+  aKeyboardShortcut.Truncate();
+  return NS_OK;
+}
+
+NS_IMETHODIMP
 nsApplicationAccessible::GetRole(PRUint32 *aRole)
 {
   NS_ENSURE_ARG_POINTER(aRole);
-
   return GetRoleInternal(aRole);
 }
 
 NS_IMETHODIMP
 nsApplicationAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
   NS_ENSURE_ARG_POINTER(aState);
-  *aState = 0;
+  GetStateInternal(aState, aExtraState);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsApplicationAccessible::GetAttributes(nsIPersistentProperties **aAttributes)
+{
+  NS_ENSURE_ARG_POINTER(aAttributes);
+  *aAttributes = nsnull;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsApplicationAccessible::GroupPosition(PRInt32 *aGroupLevel,
+                                       PRInt32 *aSimilarItemsInGroup,
+                                       PRInt32 *aPositionInGroup)
+{
+  NS_ENSURE_ARG_POINTER(aGroupLevel);
+  *aGroupLevel = 0;
+  NS_ENSURE_ARG_POINTER(aSimilarItemsInGroup);
+  *aSimilarItemsInGroup = 0;
+  NS_ENSURE_ARG_POINTER(aPositionInGroup);
+  *aPositionInGroup = 0;
+  return NS_OK;
+}
 
-  if (aExtraState)
-    *aExtraState = 0;
+NS_IMETHODIMP
+nsApplicationAccessible::GetChildAtPoint(PRInt32 aX, PRInt32 aY,
+                                         nsIAccessible **aChild)
+{
+  NS_ENSURE_ARG_POINTER(aChild);
+  *aChild = nsnull;
+  return NS_ERROR_NOT_IMPLEMENTED;
+}
 
+NS_IMETHODIMP
+nsApplicationAccessible::GetDeepestChildAtPoint(PRInt32 aX, PRInt32 aY,
+                                                nsIAccessible **aChild)
+{
+  NS_ENSURE_ARG_POINTER(aChild);
+  *aChild = nsnull;
+  return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsApplicationAccessible::GetRelationByType(PRUint32 aRelationType,
+                                           nsIAccessibleRelation **aRelation)
+{
+  NS_ENSURE_ARG_POINTER(aRelation);
+  *aRelation = nsnull;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsApplicationAccessible::GetRelationsCount(PRUint32 *aCount)
+{
+  NS_ENSURE_ARG_POINTER(aCount);
+  *aCount = 0;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsApplicationAccessible::GetParent(nsIAccessible **aAccessible)
+nsApplicationAccessible::GetRelation(PRUint32 aIndex,
+                                     nsIAccessibleRelation **aRelation)
+{
+  NS_ENSURE_ARG_POINTER(aRelation);
+  *aRelation = nsnull;
+  return NS_ERROR_INVALID_ARG;
+}
+
+NS_IMETHODIMP
+nsApplicationAccessible::GetRelations(nsIArray **aRelations)
+{
+  NS_ENSURE_ARG_POINTER(aRelations);
+  *aRelations = nsnull;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsApplicationAccessible::GetBounds(PRInt32 *aX, PRInt32 *aY,
+                                   PRInt32 *aWidth, PRInt32 *aHeight)
+{
+  NS_ENSURE_ARG_POINTER(aX);
+  *aX = 0;
+  NS_ENSURE_ARG_POINTER(aY);
+  *aY = 0;
+  NS_ENSURE_ARG_POINTER(aWidth);
+  *aWidth = 0;
+  NS_ENSURE_ARG_POINTER(aHeight);
+  *aHeight = 0;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsApplicationAccessible::SetSelected(PRBool aIsSelected)
 {
-  NS_ENSURE_ARG_POINTER(aAccessible);
-  *aAccessible = nsnull;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsApplicationAccessible::TakeSelection()
+{
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsApplicationAccessible::TakeFocus()
+{
+  return NS_OK;
+}
 
-  return IsDefunct() ? NS_ERROR_FAILURE : NS_OK;
+NS_IMETHODIMP
+nsApplicationAccessible::GetNumActions(PRUint8 *aNumActions)
+{
+  NS_ENSURE_ARG_POINTER(aNumActions);
+  *aNumActions = 0;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsApplicationAccessible::GetActionName(PRUint8 aIndex, nsAString &aName)
+{
+  aName.Truncate();
+  return NS_ERROR_INVALID_ARG;
+}
+
+NS_IMETHODIMP
+nsApplicationAccessible::GetActionDescription(PRUint8 aIndex,
+                                              nsAString &aDescription)
+{
+  aDescription.Truncate();
+  return NS_ERROR_INVALID_ARG;
+}
+
+NS_IMETHODIMP
+nsApplicationAccessible::DoAction(PRUint8 aIndex)
+{
+  return NS_OK;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsIAccessibleApplication
 
 NS_IMETHODIMP
 nsApplicationAccessible::GetAppName(nsAString& aName)
 {
@@ -204,45 +352,58 @@ nsApplicationAccessible::GetPlatformVers
 // nsAccessNode public methods
 
 PRBool
 nsApplicationAccessible::IsDefunct()
 {
   return nsAccessibilityService::IsShutdown();
 }
 
-nsresult
+PRBool
 nsApplicationAccessible::Init()
 {
   mAppInfo = do_GetService("@mozilla.org/xre/app-info;1");
-  return NS_OK;
+  return PR_TRUE;
 }
 
-nsresult
+void
 nsApplicationAccessible::Shutdown()
 {
   mAppInfo = nsnull;
-  return NS_OK;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccessible public methods
 
 nsresult
+nsApplicationAccessible::GetARIAState(PRUint32 *aState, PRUint32 *aExtraState)
+{
+  return NS_OK;
+}
+
+nsresult
 nsApplicationAccessible::GetRoleInternal(PRUint32 *aRole)
 {
   *aRole = nsIAccessibleRole::ROLE_APP_ROOT;
   return NS_OK;
 }
 
 nsresult
 nsApplicationAccessible::GetStateInternal(PRUint32 *aState,
                                           PRUint32 *aExtraState)
 {
   *aState = 0;
+
+  if (IsDefunct()) {
+    if (aExtraState)
+      *aExtraState = nsIAccessibleStates::EXT_STATE_DEFUNCT;
+
+    return NS_OK_DEFUNCT_OBJECT;
+  }
+
   if (aExtraState)
     *aExtraState = 0;
 
   return NS_OK;
 }
 
 nsAccessible*
 nsApplicationAccessible::GetParent()
@@ -340,8 +501,96 @@ nsApplicationAccessible::RemoveRootAcces
 {
   NS_ENSURE_ARG_POINTER(aRootAccessible);
 
   // It's not needed to void root accessible parent because this method is
   // called on root accessible shutdown and its parent will be cleared
   // properly.
   return mChildren.RemoveElement(aRootAccessible) ? NS_OK : NS_ERROR_FAILURE;
 }
+
+////////////////////////////////////////////////////////////////////////////////
+// nsIAccessNode
+
+NS_IMETHODIMP
+nsApplicationAccessible::GetDOMNode(nsIDOMNode **aDOMNode)
+{
+  NS_ENSURE_ARG_POINTER(aDOMNode);
+  *aDOMNode = nsnull;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsApplicationAccessible::GetDocument(nsIAccessibleDocument **aDocument)
+{
+  NS_ENSURE_ARG_POINTER(aDocument);
+  *aDocument = nsnull;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsApplicationAccessible::GetRootDocument(nsIAccessibleDocument **aRootDocument)
+{
+  NS_ENSURE_ARG_POINTER(aRootDocument);
+  *aRootDocument = nsnull;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsApplicationAccessible::GetInnerHTML(nsAString &aInnerHTML)
+{
+  aInnerHTML.Truncate();
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsApplicationAccessible::ScrollTo(PRUint32 aScrollType)
+{
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsApplicationAccessible::ScrollToPoint(PRUint32 aCoordinateType,
+                                       PRInt32 aX, PRInt32 aY)
+{
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsApplicationAccessible::GetOwnerWindow(void **aOwnerWindow)
+{
+  NS_ENSURE_ARG_POINTER(aOwnerWindow);
+  *aOwnerWindow = nsnull;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsApplicationAccessible::GetUniqueID(void **aUniqueID)
+{
+  NS_ENSURE_ARG_POINTER(aUniqueID);
+  *aUniqueID = static_cast<void *>(this);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsApplicationAccessible::GetComputedStyleValue(const nsAString &aPseudoElt,
+                                               const nsAString &aPropertyName,
+                                               nsAString &aValue)
+{
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsApplicationAccessible::GetComputedStyleCSSValue(const nsAString &aPseudoElt,
+                                                  const nsAString &aPropertyName,
+                                                  nsIDOMCSSPrimitiveValue **aCSSPrimitiveValue)
+{
+  NS_ENSURE_ARG_POINTER(aCSSPrimitiveValue);
+  *aCSSPrimitiveValue = nsnull;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsApplicationAccessible::GetLanguage(nsAString &aLanguage)
+{
+  aLanguage.Truncate();
+  return NS_OK;
+}
--- a/accessible/src/base/nsApplicationAccessible.h
+++ b/accessible/src/base/nsApplicationAccessible.h
@@ -64,35 +64,58 @@ class nsApplicationAccessible: public ns
 {
 public:
   nsApplicationAccessible();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIAccessNode
-  NS_IMETHOD GetRootDocument(nsIAccessibleDocument **aRootDocument);
+  NS_DECL_NSIACCESSNODE
 
   // nsIAccessible
-  NS_IMETHOD GetName(nsAString& aName);
-  NS_IMETHOD GetDescription(nsAString& aValue);
+  NS_IMETHOD GetParent(nsIAccessible **aParent);
+  NS_IMETHOD GetNextSibling(nsIAccessible **aNextSibling);
+  NS_IMETHOD GetPreviousSibling(nsIAccessible **aPreviousSibling);
+  NS_IMETHOD GetName(nsAString &aName);
+  NS_IMETHOD GetValue(nsAString &aValue);
+  NS_IMETHOD GetDescription(nsAString &aDescription);
+  NS_IMETHOD GetKeyboardShortcut(nsAString &aKeyboardShortcut);
   NS_IMETHOD GetRole(PRUint32 *aRole);
-  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
-
-  NS_IMETHOD GetParent(nsIAccessible **aAccessible);
+  NS_IMETHOD GetState(PRUint32 *aState , PRUint32 *aExtraState );
+  NS_IMETHOD GetAttributes(nsIPersistentProperties **aAttributes);
+  NS_IMETHOD GroupPosition(PRInt32 *aGroupLevel, PRInt32 *aSimilarItemsInGroup,
+                           PRInt32 *aPositionInGroup);
+  NS_IMETHOD GetChildAtPoint(PRInt32 aX, PRInt32 aY, nsIAccessible **aChild);
+  NS_IMETHOD GetDeepestChildAtPoint(PRInt32 aX, PRInt32 aY, nsIAccessible **aChild);
+  NS_IMETHOD GetRelationByType(PRUint32 aRelationType,
+                               nsIAccessibleRelation **aRelation);
+  NS_IMETHOD GetRelationsCount(PRUint32 *aRelationsCount);
+  NS_IMETHOD GetRelation(PRUint32 aIndex, nsIAccessibleRelation **aRelation);
+  NS_IMETHOD GetRelations(nsIArray **aRelations);
+  NS_IMETHOD GetBounds(PRInt32 *aX, PRInt32 *aY,
+                       PRInt32 *aWidth, PRInt32 *aHeight);
+  NS_IMETHOD SetSelected(PRBool aIsSelected);
+  NS_IMETHOD TakeSelection();
+  NS_IMETHOD TakeFocus();
+  NS_IMETHOD GetNumActions(PRUint8 *aNumActions);
+  NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString &aName);
+  NS_IMETHOD GetActionDescription(PRUint8 aIndex, nsAString &aDescription);
+  NS_IMETHOD DoAction(PRUint8 aIndex);
 
   // nsIAccessibleApplication
   NS_DECL_NSIACCESSIBLEAPPLICATION
 
   // nsAccessNode
   virtual PRBool IsDefunct();
-  virtual nsresult Init();
-  virtual nsresult Shutdown();
+  virtual PRBool Init();
+  virtual void Shutdown();
 
   // nsAccessible
+  virtual nsresult GetARIAState(PRUint32 *aState, PRUint32 *aExtraState);
   virtual nsresult GetRoleInternal(PRUint32 *aRole);
   virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
   virtual nsAccessible* GetParent();
 
   virtual void InvalidateChildren();
 
   // nsApplicationAccessible
   virtual nsresult AddRootAccessible(nsIAccessible *aRootAccWrap);
--- a/accessible/src/base/nsBaseWidgetAccessible.cpp
+++ b/accessible/src/base/nsBaseWidgetAccessible.cpp
@@ -51,18 +51,19 @@
 #include "nsIFrame.h"
 #include "nsINameSpaceManager.h"
 #include "nsIURI.h"
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsLeafAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
-nsLeafAccessible::nsLeafAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell):
-nsAccessibleWrap(aNode, aShell)
+nsLeafAccessible::
+  nsLeafAccessible(nsIContent *aContent, nsIWeakReference *aShell) :
+  nsAccessibleWrap(aContent, aShell)
 {
 }
 
 NS_IMPL_ISUPPORTS_INHERITED0(nsLeafAccessible, nsAccessible)
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsLeafAccessible: nsAccessible public
 
@@ -86,18 +87,18 @@ nsLeafAccessible::CacheChildren()
 }
 
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsLinkableAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
 nsLinkableAccessible::
-  nsLinkableAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell) :
-  nsAccessibleWrap(aNode, aShell),
+  nsLinkableAccessible(nsIContent *aContent, nsIWeakReference *aShell) :
+  nsAccessibleWrap(aContent, aShell),
   mActionContent(nsnull),
   mIsLink(PR_FALSE),
   mIsOnclick(PR_FALSE)
 {
 }
 
 NS_IMPL_ISUPPORTS_INHERITED0(nsLinkableAccessible, nsAccessibleWrap)
 
@@ -222,52 +223,49 @@ nsLinkableAccessible::GetURI(PRInt32 aIn
   }
   
   return NS_ERROR_INVALID_ARG;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsLinkableAccessible. nsAccessNode
 
-nsresult
+PRBool
 nsLinkableAccessible::Init()
 {
   CacheActionContent();
   return nsAccessibleWrap::Init();
 }
 
-nsresult
+void
 nsLinkableAccessible::Shutdown()
 {
   mActionContent = nsnull;
-  return nsAccessibleWrap::Shutdown();
+  nsAccessibleWrap::Shutdown();
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsLinkableAccessible
 
 void
 nsLinkableAccessible::CacheActionContent()
 {
-  nsCOMPtr<nsIContent> walkUpContent(do_QueryInterface(mDOMNode));
+  nsIContent* walkUpContent = mContent;
   PRBool isOnclick = nsCoreUtils::HasClickListener(walkUpContent);
 
   if (isOnclick) {
     mActionContent = walkUpContent;
     mIsOnclick = PR_TRUE;
     return;
   }
 
   while ((walkUpContent = walkUpContent->GetParent())) {
     isOnclick = nsCoreUtils::HasClickListener(walkUpContent);
-  
-    nsCOMPtr<nsIDOMNode> walkUpNode(do_QueryInterface(walkUpContent));
-
     nsAccessible *walkUpAcc =
-      GetAccService()->GetAccessibleInWeakShell(walkUpNode, mWeakShell);
+      GetAccService()->GetAccessibleInWeakShell(walkUpContent, mWeakShell);
 
     if (nsAccUtils::Role(walkUpAcc) == nsIAccessibleRole::ROLE_LINK &&
         nsAccUtils::State(walkUpAcc) & nsIAccessibleStates::STATE_LINKED) {
       mIsLink = PR_TRUE;
       mActionContent = walkUpContent;
       return;
     }
 
@@ -281,30 +279,30 @@ nsLinkableAccessible::CacheActionContent
 
 nsAccessible *
 nsLinkableAccessible::GetActionAccessible() const
 {
   // Return accessible for the action content if it's different from node of
   // this accessible. If the action accessible is not null then it is used to
   // redirect methods calls otherwise we use method implementation from the
   // base class.
-  nsCOMPtr<nsIDOMNode> actionNode(do_QueryInterface(mActionContent));
-  if (!actionNode || mDOMNode == actionNode)
+  if (!mActionContent || mContent == mActionContent)
     return nsnull;
 
-  return GetAccService()->GetAccessibleInWeakShell(actionNode, mWeakShell);
+  return GetAccService()->GetAccessibleInWeakShell(mActionContent, mWeakShell);
 }
 
-//---------------------
+////////////////////////////////////////////////////////////////////////////////
 // nsEnumRoleAccessible
-//---------------------
+////////////////////////////////////////////////////////////////////////////////
 
-nsEnumRoleAccessible::nsEnumRoleAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell, PRUint32 aRole) :
-  nsAccessibleWrap(aNode, aShell),
-  mRole(aRole)
+nsEnumRoleAccessible::
+  nsEnumRoleAccessible(nsIContent *aNode, nsIWeakReference *aShell,
+                       PRUint32 aRole) :
+  nsAccessibleWrap(aNode, aShell), mRole(aRole)
 {
 }
 
 NS_IMPL_ISUPPORTS_INHERITED0(nsEnumRoleAccessible, nsAccessible)
 
 nsresult
 nsEnumRoleAccessible::GetRoleInternal(PRUint32 *aRole)
 {
--- a/accessible/src/base/nsBaseWidgetAccessible.h
+++ b/accessible/src/base/nsBaseWidgetAccessible.h
@@ -38,31 +38,29 @@
 
 #ifndef _nsBaseWidgetAccessible_H_
 #define _nsBaseWidgetAccessible_H_
 
 #include "nsAccessibleWrap.h"
 #include "nsHyperTextAccessibleWrap.h"
 #include "nsIContent.h"
 
-class nsIDOMNode;
-
 /**
   * This file contains a number of classes that are used as base
   *  classes for the different accessibility implementations of
   *  the HTML and XUL widget sets.  --jgaunt
   */
 
 /** 
   * Leaf version of DOM Accessible -- has no children
   */
 class nsLeafAccessible : public nsAccessibleWrap
 {
 public:
-  nsLeafAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell);
+  nsLeafAccessible(nsIContent *aContent, nsIWeakReference *aShell);
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsAccessible
   virtual nsresult GetChildAtPoint(PRInt32 aX, PRInt32 aY,
                                    PRBool aDeepestChild,
                                    nsIAccessible **aChild);
@@ -79,34 +77,34 @@ protected:
  * report the state of the host link (traveled or not) and can activate (click)
  * the host accessible programmatically.
  */
 class nsLinkableAccessible : public nsAccessibleWrap
 {
 public:
   enum { eAction_Jump = 0 };
 
-  nsLinkableAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell);
+  nsLinkableAccessible(nsIContent *aContent, nsIWeakReference *aShell);
 
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIAccessible
   NS_IMETHOD GetNumActions(PRUint8 *_retval);
   NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
   NS_IMETHOD DoAction(PRUint8 index);
   NS_IMETHOD GetValue(nsAString& _retval);
   NS_IMETHOD TakeFocus();
   NS_IMETHOD GetKeyboardShortcut(nsAString& _retval);
 
   // nsIAccessibleHyperLink
   NS_IMETHOD GetURI(PRInt32 i, nsIURI **aURI);
 
   // nsAccessNode
-  virtual nsresult Init();
-  virtual nsresult Shutdown();
+  virtual PRBool Init();
+  virtual void Shutdown();
 
   // nsAccessible
   virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
 
 protected:
   /**
    * Return an accessible for cached action node.
    */
@@ -123,17 +121,18 @@ protected:
 };
 
 /**
  * A simple accessible that gets its enumerated role passed into constructor.
  */ 
 class nsEnumRoleAccessible : public nsAccessibleWrap
 {
 public:
-  nsEnumRoleAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell, PRUint32 aRole);
+  nsEnumRoleAccessible(nsIContent *aContent, nsIWeakReference *aShell,
+                       PRUint32 aRole);
   virtual ~nsEnumRoleAccessible() { }
 
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsAccessible
   virtual nsresult GetRoleInternal(PRUint32 *aRole);
 
 protected:
--- a/accessible/src/base/nsCaretAccessible.cpp
+++ b/accessible/src/base/nsCaretAccessible.cpp
@@ -105,36 +105,34 @@ nsresult nsCaretAccessible::ClearControl
   controller->GetSelection(nsISelectionController::SELECTION_SPELLCHECK,
                            getter_AddRefs(spellcheckSel));
   selPrivate = do_QueryInterface(spellcheckSel);
   NS_ENSURE_TRUE(selPrivate, NS_ERROR_FAILURE);
 
   return selPrivate->RemoveSelectionListener(this);
 }
 
-nsresult nsCaretAccessible::SetControlSelectionListener(nsIDOMNode *aCurrentNode)
+nsresult
+nsCaretAccessible::SetControlSelectionListener(nsIContent *aCurrentNode)
 {
   NS_ENSURE_TRUE(mRootAccessible, NS_ERROR_FAILURE);
 
   ClearControlSelectionListener();
 
   mCurrentControl = aCurrentNode;
   mLastTextAccessible = nsnull;
 
   // When focus moves such that the caret is part of a new frame selection
   // this removes the old selection listener and attaches a new one for
   // the current focus.
 
   nsCOMPtr<nsISelectionController> controller =
     GetSelectionControllerForNode(mCurrentControl);
 #ifdef DEBUG
-  PRUint16 nodeType;
-  nsresult result = aCurrentNode->GetNodeType(&nodeType);
-  NS_ASSERTION(NS_SUCCEEDED(result) &&
-               (controller || nodeType == nsIDOMNode::DOCUMENT_NODE),
+  NS_ASSERTION(controller || aCurrentNode->IsNodeOfType(nsINode::eDOCUMENT),
                "No selection controller for non document node!");
 #endif
   if (!controller)
     return NS_OK;
 
   // Register 'this' as selection listener for the normal selection.
   nsCOMPtr<nsISelection> normalSel;
   controller->GetSelection(nsISelectionController::SELECTION_NORMAL,
@@ -242,34 +240,34 @@ nsCaretAccessible::NormalSelectionChange
   nsresult rv = aSel->GetRangeCount(&rangeCount);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (rangeCount == 0) {
     mLastTextAccessible = nsnull;
     return NS_OK; // No selection
   }
 
-  nsCOMPtr<nsIDOMNode> textNode;
-  nsCOMPtr<nsIAccessibleText> textAcc =
+  nsCOMPtr<nsINode> textNode;
+  nsRefPtr<nsHyperTextAccessible> textAcc =
     nsAccUtils::GetTextAccessibleFromSelection(aSel, getter_AddRefs(textNode));
   NS_ENSURE_STATE(textAcc);
 
   PRInt32 caretOffset;
   rv = textAcc->GetCaretOffset(&caretOffset);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (textAcc == mLastTextAccessible && caretOffset == mLastCaretOffset) {
     PRInt32 selectionCount;
     textAcc->GetSelectionCount(&selectionCount);   // Don't swallow similar events when selecting text
     if (!selectionCount) {
       return NS_OK;  // Swallow duplicate caret event
     }
   }
   mLastCaretOffset = caretOffset;
-  mLastTextAccessible = textAcc;
+  mLastTextAccessible.swap(textAcc);
 
   nsRefPtr<nsAccEvent> event =
     new nsAccCaretMoveEvent(textNode);
   NS_ENSURE_TRUE(event, NS_ERROR_OUT_OF_MEMORY);
 
   return mRootAccessible->FireDelayedAccessibleEvent(event);
 }
 
@@ -278,25 +276,23 @@ nsCaretAccessible::SpellcheckSelectionCh
                                               nsISelection *aSel)
 {
   // XXX: fire an event for accessible of focus node of the selection. If
   // spellchecking is enabled then we will fire the number of events for
   // the same accessible for newly appended range of the selection (for every
   // misspelled word). If spellchecking is disabled (for example,
   // @spellcheck="false" on html:body) then we won't fire any event.
 
-  nsCOMPtr<nsIAccessibleText> textAcc =
+  nsRefPtr<nsHyperTextAccessible> textAcc =
     nsAccUtils::GetTextAccessibleFromSelection(aSel);
   NS_ENSURE_STATE(textAcc);
 
-  nsCOMPtr<nsIAccessible> acc(do_QueryInterface(textAcc));
-
   nsRefPtr<nsAccEvent> event =
     new nsAccEvent(nsIAccessibleEvent::EVENT_TEXT_ATTRIBUTE_CHANGED,
-                   acc, nsnull);
+                   textAcc, nsnull);
 
   nsEventShell::FireEvent(event);
   return NS_OK;
 }
 
 nsIntRect
 nsCaretAccessible::GetCaretRect(nsIWidget **aOutWidget)
 {
@@ -304,25 +300,20 @@ nsCaretAccessible::GetCaretRect(nsIWidge
   NS_ENSURE_TRUE(aOutWidget, caretRect);
   *aOutWidget = nsnull;
   NS_ENSURE_TRUE(mRootAccessible, caretRect);
 
   if (!mLastTextAccessible) {
     return caretRect;    // Return empty rect
   }
 
-  nsCOMPtr<nsIAccessNode> lastAccessNode(do_QueryInterface(mLastTextAccessible));
-  NS_ENSURE_TRUE(lastAccessNode, caretRect);
-
-  nsCOMPtr<nsIDOMNode> lastNodeWithCaret;
-  lastAccessNode->GetDOMNode(getter_AddRefs(lastNodeWithCaret));
+  nsINode *lastNodeWithCaret = mLastTextAccessible->GetNode();
   NS_ENSURE_TRUE(lastNodeWithCaret, caretRect);
 
-  nsIPresShell *presShell =
-    nsCoreUtils::GetPresShellFor(lastNodeWithCaret);
+  nsIPresShell *presShell = nsCoreUtils::GetPresShellFor(lastNodeWithCaret);
   NS_ENSURE_TRUE(presShell, caretRect);
 
   nsRefPtr<nsCaret> caret = presShell->GetCaret();
   NS_ENSURE_TRUE(caret, caretRect);
 
   nsCOMPtr<nsISelection> caretSelection(do_QueryReferent(mLastUsedSelection));
   NS_ENSURE_TRUE(caretSelection, caretRect);
   
@@ -356,35 +347,30 @@ nsCaretAccessible::GetCaretRect(nsIWidge
     caretRect.height -= charY - caretRect.y;
     caretRect.y = charY;
   }
 
   return caretRect;
 }
 
 already_AddRefed<nsISelectionController>
-nsCaretAccessible::GetSelectionControllerForNode(nsIDOMNode *aNode)
+nsCaretAccessible::GetSelectionControllerForNode(nsIContent *aContent)
 {
-  if (!aNode)
+  if (!aContent)
     return nsnull;
 
-  nsIPresShell *presShell = nsCoreUtils::GetPresShellFor(aNode);
+  nsIDocument *document = aContent->GetOwnerDoc();
+  if (!document)
+    return nsnull;
+
+  nsIPresShell *presShell = document->GetPrimaryShell();
   if (!presShell)
     return nsnull;
 
-  nsCOMPtr<nsIDocument> doc = presShell->GetDocument();
-  if (!doc)
-    return nsnull;
-
-  // Get selection controller only for form controls, not for the document.
-  nsCOMPtr<nsIContent> content(do_QueryInterface(aNode));
-  if (!content)
-    return nsnull;
-
-  nsIFrame *frame = content->GetPrimaryFrame();
+  nsIFrame *frame = aContent->GetPrimaryFrame();
   if (!frame)
     return nsnull;
 
   nsPresContext *presContext = presShell->GetPresContext();
   if (!presContext)
     return nsnull;
 
   nsISelectionController *controller = nsnull;
--- a/accessible/src/base/nsCaretAccessible.h
+++ b/accessible/src/base/nsCaretAccessible.h
@@ -33,27 +33,21 @@
  * 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 ***** */
 
 #ifndef __nsCaretAccessible_h__
 #define __nsCaretAccessible_h__
 
-#include "nsIWeakReference.h"
-#include "nsIAccessibleText.h"
-#include "nsIDOMNode.h"
+#include "nsHyperTextAccessible.h"
+
 #include "nsISelectionListener.h"
-#include "nsISelectionController.h"
-#include "nsRect.h"
 
 class nsRootAccessible;
-class nsIView;
-class nsIPresShell;
-class nsIWidget;
 
 /*
  * This special accessibility class is for the caret, which is really the currently focused selection.
  * There is only 1 visible caret per top level window (nsRootAccessible),
  * However, there may be several visible selections.
  *
  * The important selections are the one owned by each document, and the one in the currently focused control.
  *
@@ -87,17 +81,17 @@ public:
   /**
    * Listen to selection events on the focused control.
    * Only one control's selection events are listened to at a time, per top-level window.
    * This will remove the previous control's selection listener.
    * It will fail if aFocusedNode is a document node -- document selection must be listened
    * to via AddDocSelectionListener().
    * @param aFocusedNode   The node for the focused control
    */
-  nsresult SetControlSelectionListener(nsIDOMNode *aCurrentNode);
+  nsresult SetControlSelectionListener(nsIContent *aCurrentNode);
 
   /**
    * Stop listening to selection events for any control.
    * This does not have to be called explicitly in Shutdown() procedures,
    * because the nsCaretAccessible implementation guarantees that.
    */
   nsresult ClearControlSelectionListener();
 
@@ -120,29 +114,34 @@ public:
   nsresult RemoveDocSelectionListener(nsIPresShell *aShell);
 
   nsIntRect GetCaretRect(nsIWidget **aOutWidget);
 
 protected:
   nsresult NormalSelectionChanged(nsIDOMDocument *aDoc, nsISelection *aSel);
   nsresult SpellcheckSe