Merge from m-c.
authorJason Duell <jduell.mcbugs@gmail.com>
Tue, 22 Jun 2010 17:33:57 -0700
changeset 46909 155d97b3f8c9f6e74239e9cca56db40e53610dc1
parent 46908 f80302dc4c6cdc3ec12ca024388f3bc3a70f62cf (current diff)
parent 44122 b9ef5bc12c38be88d58fb259852ed912612b141a (diff)
child 46910 7050d2595c2da5d660ec1e0c62af72dbe0cc4943
push idunknown
push userunknown
push dateunknown
milestone1.9.3a6pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge from m-c. Fair amount of merge conflicts. Biggest item was changes to nsHttpChannel from web sockets changes. Other likely suspects if things are borken: nsFrameLoader.cpp: - nsFrameLoader::EnsureMessageManager: pass "this" (orig e10s code) or nsnull (m-c) to local process call to new nsFrameMessageManager(), callback arg? Smaug said null. - only calling SetCallBackData for local case. also +r smaug. nsPrefBranch.cpp had fairly extensive merge conflicts. nsChromeRegistry had lots of changes. Dougt did most of the non-necko changes (thanks).
.hgtags
accessible/src/base/nsAccIterator.cpp
accessible/src/base/nsAccIterator.h
accessible/tests/mochitest/events/test_doc.html
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
build/automation.py.in
caps/src/nsScriptSecurityManager.cpp
chrome/src/nsChromeRegistry.cpp
chrome/src/nsChromeRegistry.h
chrome/src/nsChromeRegistryChrome.cpp
chrome/src/nsChromeRegistryChrome.h
configure.in
content/base/public/Makefile.in
content/base/public/nsContentUtils.h
content/base/src/Makefile.in
content/base/src/nsContentUtils.cpp
content/base/src/nsDocument.cpp
content/base/src/nsFrameLoader.cpp
content/base/src/nsFrameMessageManager.cpp
content/base/src/nsFrameMessageManager.h
content/base/src/nsGkAtomList.h
content/base/src/nsXMLHttpRequest.h
content/canvas/src/WebGLContext.cpp
content/canvas/src/WebGLContext.h
content/canvas/src/nsCanvasRenderingContext2D.cpp
content/events/public/nsIPrivateDOMEvent.h
content/events/src/Makefile.in
content/events/src/nsDOMEvent.cpp
content/events/src/nsDOMEvent.h
content/html/content/public/nsHTMLCanvasElement.h
content/html/content/src/nsGenericHTMLElement.cpp
content/html/content/src/nsHTMLCanvasElement.cpp
content/html/content/test/test_bug559284.html
content/media/ogg/nsOggReader.cpp
content/xul/content/src/nsXULElement.h
docshell/base/nsDocShell.cpp
dom/Makefile.in
dom/base/nsDOMClassInfo.cpp
dom/base/nsDOMClassInfoClasses.h
dom/base/nsGlobalWindow.cpp
dom/base/nsGlobalWindow.h
dom/base/nsJSEnvironment.cpp
dom/locales/en-US/chrome/prompts.properties
dom/plugins/PluginInstanceChild.cpp
dom/plugins/PluginInstanceParent.cpp
dom/plugins/PluginModuleChild.cpp
dom/plugins/PluginModuleChild.h
dom/plugins/PluginModuleParent.cpp
editor/txtsvc/src/nsTSDNotifier.cpp
editor/txtsvc/src/nsTSDNotifier.h
embedding/base/Makefile.in
embedding/base/nsEmbedAPI.cpp
embedding/base/nsEmbedAPI.h
embedding/base/nsEmbedOS2.cpp
embedding/base/nsEmbedWin32.cpp
embedding/base/objs.mk
embedding/base/standalone/Makefile.in
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.h
extensions/cookie/test/unit/test_cookies_thirdparty.js
extensions/spellcheck/locales/en-US/hunspell/README.txt
extensions/spellcheck/locales/en-US/hunspell/mozilla_words.diff
gfx/thebes/public/gfxSharedImageSurface.h
intl/unicharutil/public/nsHankakuToZenkakuCID.h
intl/unicharutil/src/nsHankakuToZenkaku.cpp
intl/unicharutil/src/nsTextTransformFactory.h
ipc/glue/IPCMessageUtils.h
layout/base/nsPresContext.cpp
layout/base/tests/region_lib.js
layout/base/tests/scrolling_helper.html
layout/base/tests/test_scrolling.html
layout/build/Makefile.in
layout/build/nsLayoutModule.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
media/libvorbis/bug498855.patch
media/libvorbis/bug550184.patch
modules/libpref/public/nsISecurityPref.idl
modules/libpref/public/nsPrefsCID.h
modules/libpref/src/init/all.js
modules/libpref/src/nsPrefBranch.cpp
modules/plugin/base/src/nsPluginHost.cpp
netwerk/build/nsNetModule.cpp
netwerk/cookie/nsCookieService.cpp
netwerk/cookie/nsCookieService.h
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/protocol/http/HttpBaseChannel.h
netwerk/protocol/http/HttpChannelChild.h
netwerk/protocol/http/Makefile.in
netwerk/protocol/http/nsHttpChannel.cpp
netwerk/protocol/http/nsHttpChannel.h
netwerk/protocol/http/nsHttpChannelAuthProvider.cpp
netwerk/protocol/http/nsHttpChannelAuthProvider.h
netwerk/protocol/http/nsHttpHandler.cpp
netwerk/streamconv/converters/nsGopherDirListingConv.cpp
netwerk/streamconv/converters/nsGopherDirListingConv.h
other-licenses/nsis/Contrib/ShellLink/ConvFunc.h
other-licenses/nsis/Contrib/ShellLink/Readme.html
other-licenses/nsis/Contrib/ShellLink/ShellLink.cpp
other-licenses/nsis/Contrib/ShellLink/ShellLink.dsp
other-licenses/nsis/Contrib/ShellLink/ShellLink.dsw
other-licenses/nsis/Contrib/UAC/History.txt
other-licenses/nsis/Contrib/UAC/License.txt
other-licenses/nsis/Contrib/UAC/NSISUtil.h
other-licenses/nsis/Contrib/UAC/RunAs.cpp
other-licenses/nsis/Contrib/UAC/UAC Readme.html
other-licenses/nsis/Contrib/UAC/UAC.dsp
other-licenses/nsis/Contrib/UAC/UAC.dsw
other-licenses/nsis/Contrib/UAC/resource.h
other-licenses/nsis/Contrib/UAC/resource.rc
other-licenses/nsis/Contrib/UAC/uac.cpp
other-licenses/nsis/Contrib/UAC/uac.h
testing/mozmill/jsbridge-2.3.5/jsbridge/extension/._chrome.manifest
testing/mozmill/jsbridge-2.3.5/jsbridge/extension/chrome/content/._overlay.js
testing/mozmill/jsbridge-2.3.5/jsbridge/extension/chrome/content/._overlay.xul
testing/mozmill/jsbridge-2.3.5/jsbridge/extension/components/._cmdarg.js
testing/mozmill/jsbridge-2.3.5/jsbridge/extension/resource/modules/._events.js
testing/mozmill/jsbridge-2.3.5/jsbridge/extension/resource/modules/._init.js
testing/mozmill/jsbridge-2.3.5/jsbridge/extension/resource/modules/._json2.js
testing/mozmill/jsbridge-2.3.5/jsbridge/extension/resource/modules/._server.js
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/content/tests/browser/browser_bug471962.js
toolkit/content/widgets/browser.xml
toolkit/crashreporter/nsExceptionHandler.cpp
toolkit/library/libxul-config.mk
toolkit/mozapps/extensions/nsAddonRepository.js
toolkit/mozapps/extensions/nsIAddonRepository.idl
toolkit/mozapps/extensions/test/browser/browser_installssl.xpi
toolkit/mozapps/installer/windows/nsis/AppAssocReg.dll
toolkit/mozapps/installer/windows/nsis/ApplicationID.dll
toolkit/mozapps/installer/windows/nsis/ShellLink.dll
toolkit/mozapps/installer/windows/nsis/UAC.dll
toolkit/mozapps/installer/windows/nsis/check-locales.pl
toolkit/mozapps/installer/windows/nsis/nsProcess.dll
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/toolkit-makefiles.sh
toolkit/toolkit-tiers.mk
toolkit/xre/nsAppRunner.cpp
widget/src/qt/nsWindow.cpp
widget/src/windows/nsWindow.cpp
widget/src/windows/nsWindow.h
widget/src/windows/nsWindowGfx.cpp
xpcom/reflect/xptinfo/src/xptiFile.cpp
xpcom/reflect/xptinfo/src/xptiManifest.cpp
xpcom/reflect/xptinfo/src/xptiZipItem.cpp
xpcom/reflect/xptinfo/src/xptiZipLoader.cpp
xpcom/tools/Makefile.in
xpcom/tools/registry/Makefile.in
xpcom/tools/registry/regxpcom.cpp
--- a/.hgtags
+++ b/.hgtags
@@ -43,8 +43,9 @@ 65c1582465efe99899189519fccaf7b2826fcb2e
 27937722da69ad0e8fd140a00671413068226a5b last-mozilla-central
 27937722da69ad0e8fd140a00671413068226a5b last-mozilla-central
 a732c6d3c078f80635255c78bfaadffa5828a8a5 last-mozilla-central
 a732c6d3c078f80635255c78bfaadffa5828a8a5 last-mozilla-central
 925595f3c08634cc42e33158ea6858bb55623ef7 last-mozilla-central
 dba2abb7db57078c5a4810884834d3056a5d56c2 last-mozilla-central
 138f593553b66c9f815e8f57870c19d6347f7702 UPDATE_PACKAGING_R9
 138f593553b66c9f815e8f57870c19d6347f7702 UPDATE_PACKAGING_R10
+138f593553b66c9f815e8f57870c19d6347f7702 UPDATE_PACKAGING_R11
--- 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/nsIAccessibleEvent.idl
+++ b/accessible/public/nsIAccessibleEvent.idl
@@ -56,17 +56,17 @@ interface nsIDOMNode;
  * using code something like this:
  *   nsCOMPtr<nsIObserverService> observerService = 
  *     do_GetService("@mozilla.org/observer-service;1", &rv);
  *   if (NS_SUCCEEDED(rv)) 
  *     rv = observerService->AddObserver(this, "accessible-event", PR_TRUE);
  *
  * @status UNDER_REVIEW
  */
-[scriptable, uuid(5713f093-1d67-4666-b9e2-516f410976bc)]
+[scriptable, uuid(c68b4386-dca7-4b88-8988-7a95ce7be92f)]
 interface nsIAccessibleEvent : nsISupports
 {
   /**
    * An object has been created.
    */
   const unsigned long EVENT_SHOW = 0x0001;
 
   /**
@@ -252,217 +252,207 @@ interface nsIAccessibleEvent : nsISuppor
   const unsigned long EVENT_MINIMIZE_START = 0x0025;
 
   /**
    * A window object has been minimized or maximized
    */
   const unsigned long EVENT_MINIMIZE_END = 0x0026;
 
   /**
-   * XXX:
-   */
-  const unsigned long EVENT_DOCUMENT_LOAD_START = 0x0027;
-
-  /**
    * The loading of the document has completed.
    */
-  const unsigned long EVENT_DOCUMENT_LOAD_COMPLETE = 0x0028;
+  const unsigned long EVENT_DOCUMENT_LOAD_COMPLETE = 0x0027;
 
   /**
    * The document contents are being reloaded.
    */
-  const unsigned long EVENT_DOCUMENT_RELOAD = 0x0029;
+  const unsigned long EVENT_DOCUMENT_RELOAD = 0x0028;
 
   /**
    * The loading of the document was interrupted.
    */
-  const unsigned long EVENT_DOCUMENT_LOAD_STOPPED = 0x002A;
+  const unsigned long EVENT_DOCUMENT_LOAD_STOPPED = 0x0029;
 
   /**
    * The document wide attributes of the document object have changed.
    */
-  const unsigned long EVENT_DOCUMENT_ATTRIBUTES_CHANGED = 0x002B;
+  const unsigned long EVENT_DOCUMENT_ATTRIBUTES_CHANGED = 0x002A;
 
   /**
    * The contents of the document have changed.
    */
-  const unsigned long EVENT_DOCUMENT_CONTENT_CHANGED = 0x002C;
+  const unsigned long EVENT_DOCUMENT_CONTENT_CHANGED = 0x002B;
 
-  const unsigned long EVENT_PROPERTY_CHANGED = 0x002D;
-  const unsigned long EVENT_SELECTION_CHANGED = 0x002E;
+  const unsigned long EVENT_PROPERTY_CHANGED = 0x002C;
+  const unsigned long EVENT_SELECTION_CHANGED = 0x002D;
 
   /**
    * A text object's attributes changed.
    * Also see EVENT_OBJECT_ATTRIBUTE_CHANGED.
    */
-  const unsigned long EVENT_TEXT_ATTRIBUTE_CHANGED = 0x002F;
+  const unsigned long EVENT_TEXT_ATTRIBUTE_CHANGED = 0x002E;
 
   /**
    * The caret has moved to a new position.
    */
-  const unsigned long EVENT_TEXT_CARET_MOVED = 0x0030;
+  const unsigned long EVENT_TEXT_CARET_MOVED = 0x002F;
 
   /**
    * This event indicates general text changes, i.e. changes to text that is
    * exposed through the IAccessibleText and IAccessibleEditableText interfaces.
    */
-  const unsigned long EVENT_TEXT_CHANGED = 0x0031;
+  const unsigned long EVENT_TEXT_CHANGED = 0x0030;
 
   /**
    * Text was inserted.
    */
-  const unsigned long EVENT_TEXT_INSERTED = 0x0032;
+  const unsigned long EVENT_TEXT_INSERTED = 0x0031;
 
   /**
    * Text was removed.
    */
-  const unsigned long EVENT_TEXT_REMOVED = 0x0033;
+  const unsigned long EVENT_TEXT_REMOVED = 0x0032;
 
   /**
    * Text was updated.
    */
-  const unsigned long EVENT_TEXT_UPDATED = 0x0034;
+  const unsigned long EVENT_TEXT_UPDATED = 0x0033;
 
   /**
    * The text selection changed.
    */
-  const unsigned long EVENT_TEXT_SELECTION_CHANGED = 0x0035;
+  const unsigned long EVENT_TEXT_SELECTION_CHANGED = 0x0034;
 
   /**
    * A visibile data event indicates the change of the visual appearance
    * of an accessible object.  This includes for example most of the
    * attributes available via the IAccessibleComponent interface.
    */
-  const unsigned long EVENT_VISIBLE_DATA_CHANGED = 0x0036;
+  const unsigned long EVENT_VISIBLE_DATA_CHANGED = 0x0035;
 
   /**
    * The caret moved from one column to the next.
    */
-  const unsigned long EVENT_TEXT_COLUMN_CHANGED = 0x0037;
+  const unsigned long EVENT_TEXT_COLUMN_CHANGED = 0x0036;
 
   /**
    * The caret moved from one section to the next.
    */
-  const unsigned long EVENT_SECTION_CHANGED = 0x0038;
+  const unsigned long EVENT_SECTION_CHANGED = 0x0037;
 
   /**
    * A table caption changed.
    */
-  const unsigned long EVENT_TABLE_CAPTION_CHANGED = 0x0039;
+  const unsigned long EVENT_TABLE_CAPTION_CHANGED = 0x0038;
 
   /**
    * A table's data changed.
    */
-  const unsigned long EVENT_TABLE_MODEL_CHANGED = 0x003A;
+  const unsigned long EVENT_TABLE_MODEL_CHANGED = 0x0039;
 
   /**
    * A table's summary changed.
    */
-  const unsigned long EVENT_TABLE_SUMMARY_CHANGED = 0x003B;
+  const unsigned long EVENT_TABLE_SUMMARY_CHANGED = 0x003A;
 
   /**
    * A table's row description changed.
    */
-  const unsigned long EVENT_TABLE_ROW_DESCRIPTION_CHANGED = 0x003C;
+  const unsigned long EVENT_TABLE_ROW_DESCRIPTION_CHANGED = 0x003B;
 
   /**
    * A table's row header changed.
    */
-  const unsigned long EVENT_TABLE_ROW_HEADER_CHANGED = 0x003D;
+  const unsigned long EVENT_TABLE_ROW_HEADER_CHANGED = 0x003C;
 
-  const unsigned long EVENT_TABLE_ROW_INSERT = 0x003E;
-  const unsigned long EVENT_TABLE_ROW_DELETE = 0x003F;
-  const unsigned long EVENT_TABLE_ROW_REORDER = 0x0040;
+  const unsigned long EVENT_TABLE_ROW_INSERT = 0x003D;
+  const unsigned long EVENT_TABLE_ROW_DELETE = 0x003E;
+  const unsigned long EVENT_TABLE_ROW_REORDER = 0x003F;
 
   /**
    * A table's column description changed.
    */
-  const unsigned long EVENT_TABLE_COLUMN_DESCRIPTION_CHANGED = 0x0041;
+  const unsigned long EVENT_TABLE_COLUMN_DESCRIPTION_CHANGED = 0x0040;
 
   /**
    * A table's column header changed.
    */
-  const unsigned long EVENT_TABLE_COLUMN_HEADER_CHANGED = 0x0042;
+  const unsigned long EVENT_TABLE_COLUMN_HEADER_CHANGED = 0x0041;
 
-  const unsigned long EVENT_TABLE_COLUMN_INSERT = 0x0043;
-  const unsigned long EVENT_TABLE_COLUMN_DELETE = 0x0044;
-  const unsigned long EVENT_TABLE_COLUMN_REORDER = 0x0045;
+  const unsigned long EVENT_TABLE_COLUMN_INSERT = 0x0042;
+  const unsigned long EVENT_TABLE_COLUMN_DELETE = 0x0043;
+  const unsigned long EVENT_TABLE_COLUMN_REORDER = 0x0044;
 
-  const unsigned long EVENT_WINDOW_ACTIVATE = 0x0046;
-  const unsigned long EVENT_WINDOW_CREATE = 0x0047;
-  const unsigned long EVENT_WINDOW_DEACTIVATE = 0x0048;
-  const unsigned long EVENT_WINDOW_DESTROY = 0x0049;
-  const unsigned long EVENT_WINDOW_MAXIMIZE = 0x004A;
-  const unsigned long EVENT_WINDOW_MINIMIZE = 0x004B;
-  const unsigned long EVENT_WINDOW_RESIZE = 0x004C;
-  const unsigned long EVENT_WINDOW_RESTORE = 0x004D;
+  const unsigned long EVENT_WINDOW_ACTIVATE = 0x0045;
+  const unsigned long EVENT_WINDOW_CREATE = 0x0046;
+  const unsigned long EVENT_WINDOW_DEACTIVATE = 0x0047;
+  const unsigned long EVENT_WINDOW_DESTROY = 0x0048;
+  const unsigned long EVENT_WINDOW_MAXIMIZE = 0x0049;
+  const unsigned long EVENT_WINDOW_MINIMIZE = 0x004A;
+  const unsigned long EVENT_WINDOW_RESIZE = 0x004B;
+  const unsigned long EVENT_WINDOW_RESTORE = 0x004C;
 
   /**
    * The ending index of this link within the containing string has changed.
    */
-  const unsigned long EVENT_HYPERLINK_END_INDEX_CHANGED = 0x004E;
+  const unsigned long EVENT_HYPERLINK_END_INDEX_CHANGED = 0x004D;
 
   /**
    * The number of anchors assoicated with this hyperlink object has changed.
    */
-  const unsigned long EVENT_HYPERLINK_NUMBER_OF_ANCHORS_CHANGED = 0x004F;
+  const unsigned long EVENT_HYPERLINK_NUMBER_OF_ANCHORS_CHANGED = 0x004E;
 
   /**
    * The hyperlink selected state changed from selected to unselected or
    * from unselected to selected.
    */
-  const unsigned long EVENT_HYPERLINK_SELECTED_LINK_CHANGED = 0x0050;
+  const unsigned long EVENT_HYPERLINK_SELECTED_LINK_CHANGED = 0x004F;
 
   /**
    * One of the links associated with the hypertext object has been activated.
    */
-  const unsigned long EVENT_HYPERTEXT_LINK_ACTIVATED = 0x0051;
+  const unsigned long EVENT_HYPERTEXT_LINK_ACTIVATED = 0x0050;
 
   /**
    * One of the links associated with the hypertext object has been selected.
    */
-  const unsigned long EVENT_HYPERTEXT_LINK_SELECTED = 0x0052;
+  const unsigned long EVENT_HYPERTEXT_LINK_SELECTED = 0x0051;
 
   /**
    * The starting index of this link within the containing string has changed.
    */
-  const unsigned long EVENT_HYPERLINK_START_INDEX_CHANGED = 0x0053;
+  const unsigned long EVENT_HYPERLINK_START_INDEX_CHANGED = 0x0052;
 
   /**
    * Focus has changed from one hypertext object to another, or focus moved
    * from a non-hypertext object to a hypertext object, or focus moved from a
    * hypertext object to a non-hypertext object.
    */
-  const unsigned long EVENT_HYPERTEXT_CHANGED = 0x0054;
+  const unsigned long EVENT_HYPERTEXT_CHANGED = 0x0053;
 
   /**
    * The number of hyperlinks associated with a hypertext object changed.
    */
-  const unsigned long EVENT_HYPERTEXT_NLINKS_CHANGED = 0x0055;
+  const unsigned long EVENT_HYPERTEXT_NLINKS_CHANGED = 0x0054;
 
   /**
    * An object's attributes changed. Also see EVENT_TEXT_ATTRIBUTE_CHANGED.
    */
-  const unsigned long EVENT_OBJECT_ATTRIBUTE_CHANGED = 0x0056;
+  const unsigned long EVENT_OBJECT_ATTRIBUTE_CHANGED = 0x0055;
 
   /**
    * A slide changed in a presentation document or a page boundary was
    * crossed in a word processing document.
    */
-  const unsigned long EVENT_PAGE_CHANGED = 0x0057;
-
-  /**
-   * Used internally in Gecko.
-   */
-  const unsigned long EVENT_INTERNAL_LOAD = 0x0058;
+  const unsigned long EVENT_PAGE_CHANGED = 0x0056;
 
   /**
    * Help make sure event map does not get out-of-line.
    */
-  const unsigned long EVENT_LAST_ENTRY = 0x0059;
+  const unsigned long EVENT_LAST_ENTRY = 0x0057;
 
   /**
    * The type of event, based on the enumerated event values
    * defined in this interface.
    */
   readonly attribute unsigned long eventType;
   
   /**
--- 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
@@ -432,17 +432,17 @@ mai_util_remove_key_event_listener (guin
     if (g_hash_table_size(key_listener_list) == 0) {
         gtk_key_snooper_remove(key_snooper_id);
     }
 }
 
 AtkObject *
 mai_util_get_root(void)
 {
-    if (nsAccessibilityService::gIsShutdown) {
+    if (nsAccessibilityService::IsShutdown()) {
         // We've shutdown, try to use gail instead
         // (to avoid assert in spi_atk_tidy_windows())
         if (gail_get_root)
             return gail_get_root();
 
         return nsnull;
     }
 
@@ -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,19 +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>
new file mode 100644
--- /dev/null
+++ b/accessible/src/base/nsAccDocManager.cpp
@@ -0,0 +1,578 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * 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 "nsAccDocManager.h"
+
+#include "nsAccessibilityService.h"
+#include "nsAccUtils.h"
+#include "nsOuterDocAccessible.h"
+#include "nsRootAccessibleWrap.h"
+
+#include "nsCURILoader.h"
+#include "nsDocShellLoadTypes.h"
+#include "nsIChannel.h"
+#include "nsIContentViewer.h"
+#include "nsIDOMDocument.h"
+#include "nsIEventListenerManager.h"
+#include "nsIDOMEventTarget.h"
+#include "nsIDOMWindow.h"
+#include "nsIInterfaceRequestorUtils.h"
+#include "nsIWebNavigation.h"
+#include "nsServiceManagerUtils.h"
+
+////////////////////////////////////////////////////////////////////////////////
+// nsAccDocManager
+////////////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////////////
+// nsAccDocManager public
+
+nsDocAccessible*
+nsAccDocManager::GetDocAccessible(nsIDocument *aDocument)
+{
+  if (!aDocument)
+    return nsnull;
+
+  nsDocAccessible *docAcc =
+    mDocAccessibleCache.GetWeak(static_cast<void*>(aDocument));
+  if (docAcc)
+    return docAcc;
+
+  return CreateDocOrRootAccessible(aDocument);
+}
+
+nsAccessible*
+nsAccDocManager::FindAccessibleInCache(void *aUniqueID) const
+{
+  nsSearchAccessibleInCacheArg arg;
+    arg.mUniqueID = aUniqueID;
+
+  mDocAccessibleCache.EnumerateRead(SearchAccessibleInDocCache,
+                                    static_cast<void*>(&arg));
+
+  return arg.mAccessible;
+}
+
+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);
+
+  nsCOMPtr<nsIWebProgress> progress =
+    do_GetService(NS_DOCUMENTLOADER_SERVICE_CONTRACTID);
+
+  if (!progress)
+    return PR_FALSE;
+
+  progress->AddProgressListener(static_cast<nsIWebProgressListener*>(this),
+                                nsIWebProgress::NOTIFY_STATE_DOCUMENT);
+
+  return PR_TRUE;
+}
+
+void
+nsAccDocManager::Shutdown()
+{
+  nsCOMPtr<nsIWebProgress> progress =
+    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)
+
+////////////////////////////////////////////////////////////////////////////////
+// nsIWebProgressListener
+
+NS_IMETHODIMP
+nsAccDocManager::OnStateChange(nsIWebProgress *aWebProgress,
+                               nsIRequest *aRequest, PRUint32 aStateFlags,
+                               nsresult aStatus)
+{
+  NS_ASSERTION(aStateFlags & STATE_IS_DOCUMENT, "Other notifications excluded");
+
+  if (nsAccessibilityService::IsShutdown() || !aWebProgress ||
+      (aStateFlags & (STATE_START | STATE_STOP)) == 0)
+    return NS_OK;
+
+  nsCOMPtr<nsIDOMWindow> DOMWindow;
+  aWebProgress->GetDOMWindow(getter_AddRefs(DOMWindow));
+  NS_ENSURE_STATE(DOMWindow);
+
+  nsCOMPtr<nsIDOMDocument> DOMDocument;
+  DOMWindow->GetDocument(getter_AddRefs(DOMDocument));
+  NS_ENSURE_STATE(DOMDocument);
+
+  nsCOMPtr<nsIDocument> document(do_QueryInterface(DOMDocument));
+
+  // Document was loaded.
+  if (aStateFlags & STATE_STOP) {
+    NS_LOG_ACCDOCLOAD("document loaded", aWebProgress, aRequest, aStateFlags)
+
+    // Figure out an event type to notify the document has been loaded.
+    PRUint32 eventType = nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_STOPPED;
+
+    // Some XUL documents get start state and then stop state with failure
+    // status when everything is ok. Fire document load complete event in this
+    // case.
+    if (NS_SUCCEEDED(aStatus) || !nsCoreUtils::IsContentDocument(document))
+      eventType = nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE;
+
+    // If end consumer has been retargeted for loaded content then do not fire
+    // any event because it means no new document has been loaded, for example,
+    // it happens when user clicks on file link.
+    if (aRequest) {
+      PRUint32 loadFlags = 0;
+      aRequest->GetLoadFlags(&loadFlags);
+      if (loadFlags & nsIChannel::LOAD_RETARGETED_DOCUMENT_URI)
+        eventType = 0;
+    }
+
+    HandleDOMDocumentLoad(document, eventType);
+    return NS_OK;
+  }
+
+  // Document loading was started.
+  NS_LOG_ACCDOCLOAD("start document loading", aWebProgress, aRequest,
+                    aStateFlags)
+
+  if (!IsEventTargetDocument(document))
+    return NS_OK;
+
+  nsDocAccessible *docAcc =
+    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);
+
+  // 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 ||
+      loadType == LOAD_RELOAD_BYPASS_PROXY_AND_CACHE) {
+
+    // Fire reload event.
+    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(document, nsIAccessibleStates::STATE_BUSY,
+                              PR_FALSE, PR_TRUE);
+  docAcc->FireDelayedAccessibleEvent(stateEvent);
+
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsAccDocManager::OnProgressChange(nsIWebProgress *aWebProgress,
+                                  nsIRequest *aRequest,
+                                  PRInt32 aCurSelfProgress,
+                                  PRInt32 aMaxSelfProgress,
+                                  PRInt32 aCurTotalProgress,
+                                  PRInt32 aMaxTotalProgress)
+{
+  NS_NOTREACHED("notification excluded in AddProgressListener(...)");
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsAccDocManager::OnLocationChange(nsIWebProgress *aWebProgress,
+                                  nsIRequest *aRequest, nsIURI *aLocation)
+{
+  NS_NOTREACHED("notification excluded in AddProgressListener(...)");
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsAccDocManager::OnStatusChange(nsIWebProgress *aWebProgress,
+                                nsIRequest *aRequest, nsresult aStatus,
+                                const PRUnichar *aMessage)
+{
+  NS_NOTREACHED("notification excluded in AddProgressListener(...)");
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsAccDocManager::OnSecurityChange(nsIWebProgress *aWebProgress,
+                                  nsIRequest *aRequest,
+                                  PRUint32 aState)
+{
+  NS_NOTREACHED("notification excluded in AddProgressListener(...)");
+  return NS_OK;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// nsIDOMEventListener
+
+NS_IMETHODIMP
+nsAccDocManager::HandleEvent(nsIDOMEvent *aEvent)
+{
+  nsAutoString type;
+  aEvent->GetType(type);
+
+  nsCOMPtr<nsIDOMEventTarget> target;
+  aEvent->GetTarget(getter_AddRefs(target));
+
+  nsCOMPtr<nsIDocument> document(do_QueryInterface(target));
+  NS_ASSERTION(document, "pagehide or DOMContentLoaded for non document!");
+  if (!document)
+    return NS_OK;
+
+  if (type.EqualsLiteral("pagehide")) {
+    // 'pagehide' event is registered on every DOM document we create an
+    // accessible for, process the event for the target. This document
+    // accessible and all its sub document accessible are shutdown as result of
+    // processing.
+
+    NS_LOG_ACCDOCDESTROY("received 'pagehide' event", document)
+
+    // Ignore 'pagehide' on temporary documents since we ignore them entirely in
+    // accessibility.
+    if (document->IsInitialDocument())
+      return NS_OK;
+
+    // Shutdown this one and sub document accessibles.
+    ShutdownDocAccessiblesInTree(document);
+    return NS_OK;
+  }
+
+  // XXX: handle error pages loading separately since they get neither
+  // webprogress notifications nor 'pageshow' event.
+  if (type.EqualsLiteral("DOMContentLoaded") &&
+      nsCoreUtils::IsErrorPage(document)) {
+    NS_LOG_ACCDOCLOAD2("handled 'DOMContentLoaded' event", document)
+    HandleDOMDocumentLoad(document,
+                          nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE,
+                          PR_TRUE);
+  }
+
+  return NS_OK;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// nsAccDocManager private
+
+void
+nsAccDocManager::HandleDOMDocumentLoad(nsIDocument *aDocument,
+                                       PRUint32 aLoadEventType,
+                                       PRBool aMarkAsLoaded)
+{
+  // Document accessible can be created before we were notified the DOM document
+  // was loaded completely. However if it's not created yet then create it.
+  nsDocAccessible *docAcc =
+    mDocAccessibleCache.GetWeak(static_cast<void*>(aDocument));
+
+  if (!docAcc) {
+    docAcc = CreateDocOrRootAccessible(aDocument);
+    NS_ASSERTION(docAcc, "Can't create document accessible!");
+    if (!docAcc)
+      return;
+  }
+
+  if (aMarkAsLoaded)
+    docAcc->MarkAsLoaded();
+
+  // Do not fire document complete/stop events for root chrome document
+  // accessibles and for frame/iframe documents because
+  // a) screen readers start working on focus event in the case of root chrome
+  // documents
+  // b) document load event on sub documents causes screen readers to act is if
+  // entire page is reloaded.
+  if (!IsEventTargetDocument(aDocument)) {
+    // XXX: AT doesn't update their virtual buffer once frame is loaded and it
+    // has dynamic content added after frame load. There's something wrong how
+    // we handle this changes.
+    if (!nsCoreUtils::IsRootDocument(aDocument)) {
+      docAcc->InvalidateCacheSubtree(nsnull,
+                                     nsIAccessibilityService::NODE_SIGNIFICANT_CHANGE);
+    }
+    return;
+  }
+
+  // Fire complete/load stopped if the load event type is given.
+  if (aLoadEventType) {
+    nsRefPtr<nsAccEvent> loadEvent = new nsAccEvent(aLoadEventType, aDocument);
+    docAcc->FireDelayedAccessibleEvent(loadEvent);
+  }
+
+  // Fire busy state change event.
+  nsRefPtr<nsAccEvent> stateEvent =
+    new nsAccStateChangeEvent(aDocument, nsIAccessibleStates::STATE_BUSY,
+                              PR_FALSE, PR_FALSE);
+  docAcc->FireDelayedAccessibleEvent(stateEvent);
+}
+
+PRBool
+nsAccDocManager::IsEventTargetDocument(nsIDocument *aDocument) const
+{
+  nsCOMPtr<nsISupports> container = aDocument->GetContainer();
+  nsCOMPtr<nsIDocShellTreeItem> docShellTreeItem =
+    do_QueryInterface(container);
+  NS_ASSERTION(docShellTreeItem, "No document shell for document!");
+
+  nsCOMPtr<nsIDocShellTreeItem> parentTreeItem;
+  docShellTreeItem->GetParent(getter_AddRefs(parentTreeItem));
+
+  // It's not a root document.
+  if (parentTreeItem) {
+    nsCOMPtr<nsIDocShellTreeItem> sameTypeRoot;
+    docShellTreeItem->GetSameTypeRootTreeItem(getter_AddRefs(sameTypeRoot));
+
+    // It's not a sub document, i.e. a frame or iframe.
+    return (sameTypeRoot == docShellTreeItem);
+  }
+
+  // It's not chrome root document.
+  PRInt32 contentType;
+  docShellTreeItem->GetItemType(&contentType);
+  return (contentType == nsIDocShellTreeItem::typeContent);
+}
+
+void
+nsAccDocManager::AddListeners(nsIDocument *aDocument,
+                              PRBool aAddDOMContentLoadedListener)
+{
+  nsPIDOMWindow *window = aDocument->GetWindow();
+  nsPIDOMEventTarget *target = window->GetChromeEventHandler();
+  nsIEventListenerManager* elm = target->GetListenerManager(PR_TRUE);
+  elm->AddEventListenerByType(this, NS_LITERAL_STRING("pagehide"),
+                              NS_EVENT_FLAG_CAPTURE, nsnull);
+
+  NS_LOG_ACCDOCCREATE_TEXT("  added 'pagehide' listener")
+
+  if (aAddDOMContentLoadedListener) {
+    elm->AddEventListenerByType(this, NS_LITERAL_STRING("DOMContentLoaded"),
+                                NS_EVENT_FLAG_CAPTURE, nsnull);
+    NS_LOG_ACCDOCCREATE_TEXT("  added 'DOMContentLoaded' listener")
+  }
+}
+
+nsDocAccessible*
+nsAccDocManager::CreateDocOrRootAccessible(nsIDocument *aDocument)
+{
+  // 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.
+  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);
+    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(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(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.
+    outerDocAcc->AppendChild(docAcc);
+  }
+
+  if (!GetAccService()->InitAccessible(docAcc,
+                                       nsAccUtils::GetRoleMapEntry(aDocument))) {
+    mDocAccessibleCache.Remove(static_cast<void*>(aDocument));
+    return nsnull;
+  }
+
+  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) {
+    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;
+
+      ShutdownDocAccessiblesInTree(treeItemChild, contentViewer->GetDocument());
+    }
+  }
+
+  ShutdownDocAccessible(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)
+    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);
+    arg->mAccessible = aDocAccessible->GetCachedAccessible(arg->mUniqueID);
+    if (arg->mAccessible)
+      return PL_DHASH_STOP;
+  }
+
+  return PL_DHASH_NEXT;
+}
new file mode 100644
--- /dev/null
+++ b/accessible/src/base/nsAccDocManager.h
@@ -0,0 +1,581 @@
+/* ***** 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 nsAccDocManager_h_
+#define nsAccDocManager_h_
+
+#include "nsAccessible.h"
+
+#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:
+  virtual ~nsAccDocManager() { };
+
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSIWEBPROGRESSLISTENER
+  NS_DECL_NSIDOMEVENTLISTENER
+
+  /**
+   * Return document accessible for the given DOM node.
+   */
+  nsDocAccessible *GetDocAccessible(nsIDocument *aDocument);
+
+  /**
+   * Search through all document accessibles for an accessible with the given
+   * unique id.
+   */
+  nsAccessible *FindAccessibleInCache(void *aUniqueID) const;
+
+  /**
+   * 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.
+   *
+   * @param  aDocument       [in] loaded DOM document
+   * @param  aLoadEventType  [in] specifies the event type to fire load event,
+   *                           if 0 then no event is fired
+   * @param  aMarkAsLoaded   [in] indicates whether we should mark forcedly
+   *                           an accessible document as loaded (used for error
+   *                           pages only which do not get 'pageshow' event)
+   */
+  void HandleDOMDocumentLoad(nsIDocument *aDocument,
+                             PRUint32 aLoadEventType,
+                             PRBool aMarkAsLoaded = PR_FALSE);
+
+  /**
+   * Return true if accessibility events accompanying document accessible
+   * loading should be fired.
+   *
+   * The rules are: do not fire events for root chrome document accessibles and
+   * for sub document accessibles (like HTML frame of iframe) of the loading
+   * document accessible.
+   *
+   * XXX: in general AT expect events for document accessible loading into
+   * tabbrowser, events from other document accessibles may break AT. We need to
+   * figure out what AT wants to know about loading page (for example, some of
+   * 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 'pagehide' and 'DOMContentLoaded' event listeners.
+   */
+  void AddListeners(nsIDocument *aDocument, PRBool aAddPageShowListener);
+
+  /**
+   * 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);
+
+  typedef nsRefPtrHashtable<nsVoidPtrHashKey, nsDocAccessible>
+    nsDocAccessibleHashtable;
+
+  /**
+   * Shutdown and remove the document accessible from cache.
+   */
+  static PLDHashOperator
+    ClearDocCacheEntry(const void* aKey,
+                       nsRefPtr<nsDocAccessible>& aDocAccessible,
+                       void* aUserArg);
+
+  /**
+   * Clear the cache and shutdown the document accessibles.
+   */
+  void ClearDocCache()
+  {
+    mDocAccessibleCache.Enumerate(ClearDocCacheEntry, static_cast<void*>(this));
+  }
+
+  struct nsSearchAccessibleInCacheArg
+  {
+    nsAccessible *mAccessible;
+    void *mUniqueID;
+  };
+
+  static PLDHashOperator
+    SearchAccessibleInDocCache(const void* aKey,
+                               nsDocAccessible* aDocAccessible,
+                               void* aUserArg);
+
+  nsDocAccessibleHashtable mDocAccessibleCache;
+};
+
+/**
+ * nsAccDocManager debugging macros.
+ */
+#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: %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)                                          \
+  PRBool isContent = nsCoreUtils::IsContentDocument(aDocument);                \
+  printf("%s document", (isContent ? "content" : "chrome"));
+
+#define NS_LOG_ACCDOC_SHELLSTATE(aDocument)                                    \
+  nsCOMPtr<nsISupports> container = aDocument->GetContainer();                 \
+  nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(container);               \
+  PRUint32 busyFlags = nsIDocShell::BUSY_FLAGS_NONE;                           \
+  docShell->GetBusyFlags(&busyFlags);                                          \
+  nsCAutoString docShellBusy;                                                  \
+  if (busyFlags == nsIDocShell::BUSY_FLAGS_NONE)                               \
+    docShellBusy.AppendLiteral("'none'");                                      \
+  if (busyFlags & nsIDocShell::BUSY_FLAGS_BUSY)                                \
+    docShellBusy.AppendLiteral("'busy'");                                      \
+  if (busyFlags & nsIDocShell::BUSY_FLAGS_BEFORE_PAGE_LOAD)                    \
+    docShellBusy.AppendLiteral(", 'before page load'");                        \
+  if (busyFlags & nsIDocShell::BUSY_FLAGS_PAGE_LOADING)                        \
+    docShellBusy.AppendLiteral(", 'page loading'");                            \
+  printf("docshell busy: %s", docShellBusy.get());
+
+#define NS_LOG_ACCDOC_DOCSTATES(aDocument)                                     \
+  const char *docState = 0;                                                    \
+  nsIDocument::ReadyState docStateFlag = aDocument->GetReadyStateEnum();       \
+  switch (docStateFlag) {                                                      \
+    case nsIDocument::READYSTATE_UNINITIALIZED:                                \
+     docState = "uninitialized";                                               \
+      break;                                                                   \
+    case nsIDocument::READYSTATE_LOADING:                                      \
+      docState = "loading";                                                    \
+      break;                                                                   \
+    case nsIDocument::READYSTATE_INTERACTIVE:                                  \
+      docState = "interactive";                                                \
+      break;                                                                   \
+    case nsIDocument::READYSTATE_COMPLETE:                                     \
+      docState = "complete";                                                   \
+      break;                                                                   \
+  }                                                                            \
+  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: %p", ps);                                                 \
+  nsIScrollableFrame *sf = ps ?                                                \
+    ps->GetRootScrollFrameAsScrollableExternal() : nsnull;                     \
+  printf(", root scroll frame: %p", sf);
+
+#define NS_LOG_ACCDOC_DOCLOADGROUP(aDocument)                                  \
+  nsCOMPtr<nsILoadGroup> loadGroup = aDocument->GetDocumentLoadGroup();        \
+  printf("load group: %p", loadGroup);
+
+#define NS_LOG_ACCDOC_DOCPARENT(aDocument)                                     \
+  nsIDocument *parentDoc = aDocument->GetParentDocument();                     \
+  printf("parent id: %p", parentDoc);                                          \
+  if (parentDoc) {                                                             \
+    printf("\n    parent ");                                                   \
+    NS_LOG_ACCDOC_URI(parentDoc)                                               \
+    printf("\n");                                                              \
+  }
+
+#define NS_LOG_ACCDOC_SHELLLOADTYPE(aDocShell)                                 \
+  {                                                                            \
+    printf("load type: ");                                                     \
+    PRUint32 loadType;                                                         \
+    docShell->GetLoadType(&loadType);                                          \
+    switch (loadType) {                                                        \
+      case LOAD_NORMAL:                                                        \
+        printf("normal; ");                                                    \
+        break;                                                                 \
+      case LOAD_NORMAL_REPLACE:                                                \
+        printf("normal replace; ");                                            \
+        break;                                                                 \
+      case LOAD_NORMAL_EXTERNAL:                                               \
+        printf("normal external; ");                                           \
+        break;                                                                 \
+      case LOAD_HISTORY:                                                       \
+        printf("history; ");                                                   \
+        break;                                                                 \
+      case LOAD_NORMAL_BYPASS_CACHE:                                           \
+        printf("normal bypass cache; ");                                       \
+        break;                                                                 \
+      case LOAD_NORMAL_BYPASS_PROXY:                                           \
+        printf("normal bypass proxy; ");                                       \
+        break;                                                                 \
+      case LOAD_NORMAL_BYPASS_PROXY_AND_CACHE:                                 \
+        printf("normal bypass proxy and cache; ");                             \
+        break;                                                                 \
+      case LOAD_RELOAD_NORMAL:                                                 \
+        printf("reload normal; ");                                             \
+        break;                                                                 \
+      case LOAD_RELOAD_BYPASS_CACHE:                                           \
+        printf("reload bypass cache; ");                                       \
+        break;                                                                 \
+      case LOAD_RELOAD_BYPASS_PROXY:                                           \
+        printf("reload bypass proxy; ");                                       \
+        break;                                                                 \
+      case LOAD_RELOAD_BYPASS_PROXY_AND_CACHE:                                 \
+        printf("reload bypass proxy and cache; ");                             \
+        break;                                                                 \
+      case LOAD_LINK:                                                          \
+        printf("link; ");                                                      \
+        break;                                                                 \
+      case LOAD_REFRESH:                                                       \
+        printf("refresh; ");                                                   \
+        break;                                                                 \
+      case LOAD_RELOAD_CHARSET_CHANGE:                                         \
+        printf("reload charset change; ");                                     \
+        break;                                                                 \
+      case LOAD_BYPASS_HISTORY:                                                \
+        printf("bypass history; ");                                            \
+        break;                                                                 \
+      case LOAD_STOP_CONTENT:                                                  \
+        printf("stop content; ");                                              \
+        break;                                                                 \
+      case LOAD_STOP_CONTENT_AND_REPLACE:                                      \
+        printf("stop content and replace; ");                                  \
+        break;                                                                 \
+      case LOAD_PUSHSTATE:                                                     \
+        printf("load pushstate; ");                                            \
+        break;                                                                 \
+      case LOAD_ERROR_PAGE:                                                    \
+        printf("error page;");                                                 \
+        break;                                                                 \
+      default:                                                                 \
+        printf("unknown");                                                     \
+    }                                                                          \
+  }
+
+#define NS_LOG_ACCDOC_DOCINFO_BEGIN                                            \
+  printf("  {\n");
+#define NS_LOG_ACCDOC_DOCINFO_BODY(aDocument, aDocAcc)                         \
+  {                                                                            \
+    printf("    ");                                                            \
+    NS_LOG_ACCDOC_ADDRESS(aDocument, aDocAcc)                                  \
+    printf("\n    ");                                                          \
+    NS_LOG_ACCDOC_URI(aDocument)                                               \
+    printf("\n    ");                                                          \
+    NS_LOG_ACCDOC_SHELLSTATE(aDocument)                                        \
+    printf("; ");                                                              \
+    NS_LOG_ACCDOC_TYPE(aDocument)                                              \
+    printf("\n    ");                                                          \
+    NS_LOG_ACCDOC_DOCSTATES(aDocument)                                         \
+    printf("\n    ");                                                          \
+    NS_LOG_ACCDOC_DOCPRESSHELL(aDocument)                                      \
+    printf("\n    ");                                                          \
+    NS_LOG_ACCDOC_DOCLOADGROUP(aDocument)                                      \
+    printf(", ");                                                              \
+    NS_LOG_ACCDOC_DOCPARENT(aDocument)                                         \
+    printf("\n");                                                              \
+  }
+#define NS_LOG_ACCDOC_DOCINFO_END                                              \
+  printf("  }\n");
+
+#define NS_LOG_ACCDOC_DOCINFO(aDocument, aDocAcc)                              \
+  NS_LOG_ACCDOC_DOCINFO_BEGIN                                                  \
+  NS_LOG_ACCDOC_DOCINFO_BODY(aDocument, aDocAcc)                               \
+  NS_LOG_ACCDOC_DOCINFO_END
+
+#define NS_GET_ACCDOC_EVENTTYPE(aEvent)                                        \
+  nsCAutoString strEventType;                                                  \
+  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) {                 \
+    nsAccStateChangeEvent *event = downcast_accEvent(aEvent);                  \
+    if (event->GetState() == nsIAccessibleStates::STATE_BUSY) {                \
+      strEventType.AssignLiteral("busy ");                                     \
+      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) {                                                              \
+    nsCAutoString name;                                                        \
+    aRequest->GetName(name);                                                   \
+    printf("    request spec: %s\n", name.get());                              \
+    PRUint32 loadFlags = 0;                                                    \
+    aRequest->GetLoadFlags(&loadFlags);                                        \
+    printf("    request load flags: %x; ", loadFlags);                         \
+    if (loadFlags & nsIChannel::LOAD_DOCUMENT_URI)                             \
+      printf("document uri; ");                                                \
+    if (loadFlags & nsIChannel::LOAD_RETARGETED_DOCUMENT_URI)                  \
+      printf("retargeted document uri; ");                                     \
+    if (loadFlags & nsIChannel::LOAD_REPLACE)                                  \
+      printf("replace; ");                                                     \
+    if (loadFlags & nsIChannel::LOAD_INITIAL_DOCUMENT_URI)                     \
+      printf("initial document uri; ");                                        \
+    if (loadFlags & nsIChannel::LOAD_TARGETED)                                 \
+      printf("targeted; ");                                                    \
+    if (loadFlags & nsIChannel::LOAD_CALL_CONTENT_SNIFFERS)                    \
+      printf("call content sniffers; ");                                       \
+    if (loadFlags & nsIChannel::LOAD_CLASSIFY_URI)                             \
+      printf("classify uri; ");                                                \
+  } else {                                                                     \
+    printf("    no request");                                                  \
+  }
+
+#define NS_LOG_ACCDOCLOAD(aMsg, aWebProgress, aRequest, aStateFlags)           \
+  {                                                                            \
+    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 =                                              \
+          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");                                                          \
+        NS_LOG_ACCDOCLOAD_REQUEST(aRequest)                                    \
+        printf("\n");                                                          \
+        printf("    state flags: %x", aStateFlags);                            \
+        PRBool isDocLoading;                                                   \
+        aWebProgress->GetIsLoadingDocument(&isDocLoading);                     \
+        printf(", document is %sloading\n", (isDocLoading ? "" : "not "));     \
+        printf("  }\n");                                                       \
+      }                                                                        \
+    }                                                                          \
+  }
+
+#define NS_LOG_ACCDOCLOAD2(aMsg, aDocument)                                    \
+  {                                                                            \
+    NS_LOG_ACCDOC_MSG("A11Y DOCLOAD: " aMsg);                                  \
+    nsDocAccessible *docAcc =                                                  \
+      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());                              \
+  }
+
+#define NS_LOG_ACCDOCLOAD_HANDLEEVENT(aEvent)                                  \
+  {                                                                            \
+    NS_GET_ACCDOC_EVENTTYPE(aEvent)                                            \
+    nsCOMPtr<nsIDocument> doc(do_QueryInterface(aEvent->GetNode()));           \
+    if (doc && !strEventType.IsEmpty()) {                                      \
+      printf("\nA11Y DOCEVENT: handled '%s' event ", strEventType.get());      \
+      nsDocAccessible *docAcc = aEvent->GetDocAccessible();                    \
+      NS_LOG_ACCDOC_DOCINFO(doc, docAcc)                                       \
+      printf("\n");                                                            \
+    }                                                                          \
+  }
+
+#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)                      \
+  NS_LOG_ACCDOC_MSG("A11Y DOCCREATE: " aMsg);                                  \
+  NS_LOG_ACCDOC_DOCINFO(aDocument, aDocAcc)
+
+#define NS_LOG_ACCDOCCREATE(aMsg, aDocument)                                   \
+  {                                                                            \
+    nsDocAccessible *docAcc =                                                  \
+      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)                     \
+  NS_LOG_ACCDOC_MSG("A11Y DOCDESTROY: " aMsg);                                 \
+  NS_LOG_ACCDOC_DOCINFO(aDocument, aDocAcc)
+
+#define NS_LOG_ACCDOCDESTROY(aMsg, aDocument)                                  \
+  {                                                                            \
+    nsDocAccessible* docAcc =                                                  \
+      GetAccService()->GetDocAccessibleFromCache(aDocument);                   \
+    NS_LOG_ACCDOCDESTROY_FOR(aMsg, aDocument, docAcc)                          \
+  }
+
+#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)
+#define NS_LOG_ACCDOCLOAD_EVENT(aMsg, aEvent)
+#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,56 +155,54 @@ 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();
   if (node)
-    return nsAccessNode::GetDocAccessibleFor(node->GetOwnerDoc());
+    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,49 +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,
-                       PRInt32 aStart, PRUint32 aLength, PRBool aIsInserted,
+  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)
+  mStart(aStart), mLength(aLength), mIsInserted(aIsInserted),
+  mModifiedText(aModifiedText)
 {
-#ifdef XP_WIN
-  nsCOMPtr<nsIAccessibleText> textAccessible = do_QueryInterface(aAccessible);
-  NS_ASSERTION(textAccessible, "Should not be firing test change event for non-text accessible!!!");
-  if (textAccessible) {
-    textAccessible->GetText(aStart, aStart + aLength, mModifiedText);
-  }
-#endif
 }
 
 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;
@@ -440,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)
 {
@@ -470,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,174 +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, PRUint32 aLength,
+  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
@@ -37,16 +37,19 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsAccTreeWalker.h"
 
 #include "nsAccessible.h"
 #include "nsAccessibilityService.h"
 
+#include "nsINodeList.h"
+#include "nsIPresShell.h"
+
 ////////////////////////////////////////////////////////////////////////////////
 // WalkState
 ////////////////////////////////////////////////////////////////////////////////
 
 struct WalkState
 {
   WalkState(nsIContent *aContent) :
     content(aContent), childIdx(0), prevState(nsnull) {}
@@ -104,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
@@ -40,25 +40,31 @@
 #define nsAccUtils_h_
 
 #include "nsIAccessible.h"
 #include "nsIAccessNode.h"
 #include "nsIAccessibleDocument.h"
 #include "nsIAccessibleRole.h"
 #include "nsIAccessibleText.h"
 #include "nsIAccessibleTable.h"
+
 #include "nsARIAMap.h"
+#include "nsAccessibilityService.h"
+#include "nsCoreUtils.h"
 
+#include "nsIContent.h"
+#include "nsIDocShell.h"
 #include "nsIDOMNode.h"
 #include "nsIPersistentProperties2.h"
-#include "nsIContent.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
 {
@@ -96,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
    */
@@ -140,28 +146,62 @@ public:
    * property is not present, or is "" or "undefined". Do not call 
    * this method for properties of type string, decimal, IDREF or IDREFS.
    * 
    * Return PR_TRUE if the ARIA property is defined, otherwise PR_FALSE
    */
   static PRBool HasDefinedARIAToken(nsIContent *aContent, nsIAtom *aAtom);
 
   /**
-   * Return true if the given DOM node contains accessible children.
+   * Return document accessible for the given presshell.
    */
-  static PRBool HasAccessibleChildren(nsIDOMNode *aNode);
+  static nsDocAccessible *GetDocAccessibleFor(nsIWeakReference *aWeakShell)
+  {
+    nsCOMPtr<nsIPresShell> presShell(do_QueryReferent(aWeakShell));
+    return presShell ?
+      GetAccService()->GetDocAccessible(presShell->GetDocument()) : nsnull;
+  }
+
+  /**
+   * Return document accessible for the given DOM node.
+   */
+  static nsDocAccessible *GetDocAccessibleFor(nsINode *aNode)
+  {
+    nsIPresShell *presShell = nsCoreUtils::GetPresShellFor(aNode);
+    return presShell ?
+      GetAccService()->GetDocAccessible(presShell->GetDocument()) : nsnull;
+  }
 
   /**
-    * 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 document accessible for the given docshell.
+   */
+  static nsDocAccessible *GetDocAccessibleFor(nsIDocShellTreeItem *aContainer)
+  {
+    nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(aContainer));
+    nsCOMPtr<nsIPresShell> presShell;
+    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(nsINode *aNode);
+
+  /**
+    * 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
@@ -172,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)
@@ -368,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,22 +75,20 @@
 #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;
-nsRefPtrHashtable<nsVoidPtrHashKey, nsDocAccessible>
-  nsAccessNode::gGlobalDocAccessibleCache;
 
 nsApplicationAccessible *nsAccessNode::gApplicationAccessible = nsnull;
 
 /*
  * Class nsAccessNode
  */
  
 ////////////////////////////////////////////////////////////////////////////////
@@ -106,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()
 {
@@ -133,103 +132,54 @@ 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
-  nsRefPtr<nsDocAccessible> docAcc = GetDocAccessible();
-  if (!docAcc) {
-    // No doc accessible yet for this node's document. 
-    // There was probably an accessible event fired before the 
-    // current document was ever asked for by the assistive technology.
-    // Create a doc accessible so we can cache this node
-    nsCOMPtr<nsIPresShell> presShell(do_QueryReferent(mWeakShell));
-    if (presShell) {
-      nsCOMPtr<nsIDOMNode> docNode(do_QueryInterface(presShell->GetDocument()));
-      if (docNode) {
-        nsAccessible *accessible =
-          GetAccService()->GetAccessibleInWeakShell(docNode, mWeakShell);
-        docAcc = do_QueryObject(accessible);
-      }
-    }
-    NS_ASSERTION(docAcc, "Cannot cache new nsAccessNode");
-    if (!docAcc) {
-      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::gIsShutdown,
+  NS_ASSERTION(!nsAccessibilityService::IsShutdown(),
                "Accessibility wasn't initialized!");
 
   if (!gApplicationAccessible) {
     nsApplicationAccessibleWrap::PreCreate();
 
     gApplicationAccessible = new nsApplicationAccessibleWrap();
     if (!gApplicationAccessible)
       return nsnull;
@@ -257,18 +207,16 @@ void nsAccessNode::InitXPAccessibility()
     stringBundleService->CreateBundle(ACCESSIBLE_BUNDLE_URL, 
                                       &gStringBundle);
     stringBundleService->CreateBundle(PLATFORM_KEYS_BUNDLE_URL, 
                                       &gKeyStringBundle);
   }
 
   nsAccessibilityAtoms::AddRefAtoms();
 
-  gGlobalDocAccessibleCache.Init(4);
-
   nsCOMPtr<nsIPrefBranch> prefBranch(do_GetService(NS_PREFSERVICE_CONTRACTID));
   if (prefBranch) {
     prefBranch->GetBoolPref("accessibility.disablecache", &gIsCacheDisabled);
     prefBranch->GetBoolPref("browser.formfill.enable", &gIsFormFillEnabled);
   }
 
   NotifyA11yInitOrShutdown(PR_TRUE);
 }
@@ -293,33 +241,31 @@ void nsAccessNode::ShutdownXPAccessibili
   // Called by nsAccessibilityService::Shutdown()
   // which happens when xpcom is shutting down
   // at exit of program
 
   NS_IF_RELEASE(gStringBundle);
   NS_IF_RELEASE(gKeyStringBundle);
   NS_IF_RELEASE(gLastFocusedNode);
 
-  ClearCache(gGlobalDocAccessibleCache);
-
   // Release gApplicationAccessible after everything else is shutdown
   // so we don't accidently create it again while tearing down root accessibles
   nsApplicationAccessibleWrap::Unload();
   if (gApplicationAccessible) {
     gApplicationAccessible->Shutdown();
     NS_RELEASE(gApplicationAccessible);
   }
 
   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()
@@ -344,100 +290,71 @@ 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;
   }
 
-  nsCOMPtr<nsIAccessibleDocument> accDoc = GetDocAccessibleFor(root);
-  if (!accDoc) {
-    return nsnull;
-  }
-
-  // nsRootAccessible has a special QI
-  // that let us get that concrete type directly.
-  nsRootAccessible* rootAccessible;
-  accDoc->QueryInterface(NS_GET_IID(nsRootAccessible), (void**)&rootAccessible); // addrefs
-  return rootAccessible;
+  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()
-{
-  nsCOMPtr<nsIAccessibleDocument> accessibleDoc =
-    nsAccessNode::GetDocAccessibleFor(mWeakShell);
-
-  if (!accessibleDoc)
-    return nsnull;
-
-  void* uniqueID = nsnull;
-  GetUniqueID(&uniqueID);
-
-  nsRefPtr<nsDocAccessible> docAccessible = do_QueryObject(accessibleDoc);
-  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 = GetDocAccessibleFor(mWeakShell));
+  NS_IF_ADDREF(*aDocument = GetDocAccessible());
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsAccessNode::GetRootDocument(nsIAccessibleDocument **aRootDocument)
 {
   NS_ENSURE_ARG_POINTER(aRootDocument);
 
@@ -446,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)
 {
@@ -491,301 +408,98 @@ 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 static
-
-nsDocAccessible*
-nsAccessNode::GetDocAccessibleFor(nsIDocument *aDocument)
-{
-  return aDocument ?
-    gGlobalDocAccessibleCache.GetWeak(static_cast<void*>(aDocument)) : nsnull;
-}
-
-nsDocAccessible*
-nsAccessNode::GetDocAccessibleFor(nsIWeakReference *aWeakShell)
-{
-  nsCOMPtr<nsIPresShell> presShell(do_QueryReferent(aWeakShell));
-  if (!presShell) {
-    return nsnull;
-  }
-
-  return GetDocAccessibleFor(presShell->GetDocument());
-}
-
-already_AddRefed<nsIAccessibleDocument>
-nsAccessNode::GetDocAccessibleFor(nsIDocShellTreeItem *aContainer,
-                                  PRBool aCanCreate)
+// nsAccessNode public
+already_AddRefed<nsINode>
+nsAccessNode::GetCurrentFocus()
 {
-  if (!aCanCreate) {
-    nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(aContainer));
-    NS_ASSERTION(docShell, "This method currently only supports docshells");
-    nsCOMPtr<nsIPresShell> presShell;
-    docShell->GetPresShell(getter_AddRefs(presShell));
-    if (!presShell)
-      return nsnull;
-
-    nsDocAccessible *docAcc = GetDocAccessibleFor(presShell->GetDocument());
-    NS_IF_ADDREF(docAcc);
-    return docAcc;
-  }
-
-  nsCOMPtr<nsIDOMNode> node = nsCoreUtils::GetDOMNodeForContainer(aContainer);
-  if (!node) {
-    return nsnull;
-  }
-
-  nsCOMPtr<nsIAccessible> accessible;
-  GetAccService()->GetAccessibleFor(node, getter_AddRefs(accessible));
-  nsIAccessibleDocument *docAccessible = nsnull;
-  if (accessible) {
-    CallQueryInterface(accessible, &docAccessible);
-  }
-  return docAccessible;
-}
- 
-nsDocAccessible*
-nsAccessNode::GetDocAccessibleFor(nsIDOMNode *aNode)
-{
-  nsIPresShell *presShell = nsCoreUtils::GetPresShellFor(aNode);
-  if (presShell)
-    return GetDocAccessibleFor(presShell->GetDocument());
-
-  nsCOMPtr<nsIDocument> doc(do_QueryInterface(aNode));
-  if (doc) {
-    return GetDocAccessibleFor(doc);
-  }
-
-  return nsnull;
-}
-
-already_AddRefed<nsIDOMNode> 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);
   }
 
   return focusedNode;
 }
 
-// nsIAccessNode
 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 GetDocAccessibleFor(mWeakShell);
-}
--- a/accessible/src/base/nsAccessNode.h
+++ b/accessible/src/base/nsAccessNode.h
@@ -47,164 +47,166 @@
 #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
-
-  /**
-   * Return cached document accessible.
-   */
-  static nsDocAccessible* GetDocAccessibleFor(nsIDocument *aDocument);
-  static nsDocAccessible* GetDocAccessibleFor(nsIWeakReference *aWeakShell);
-  static nsDocAccessible* GetDocAccessibleFor(nsIDOMNode *aNode);
-
-  /**
-   * Return document accessible.
-   */
-  static already_AddRefed<nsIAccessibleDocument>
-    GetDocAccessibleFor(nsIDocShellTreeItem *aContainer,
-                        PRBool aCanCreate = PR_FALSE);
-
 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;
     static nsIStringBundle *gKeyStringBundle;
 
     static PRBool gIsCacheDisabled;
     static PRBool gIsFormFillEnabled;
 
-  static nsRefPtrHashtable<nsVoidPtrHashKey, nsDocAccessible>
-    gGlobalDocAccessibleCache;
-
 private:
   static nsApplicationAccessible *gApplicationAccessible;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsAccessNode,
                               NS_ACCESSNODE_IMPL_CID)
 
 #endif
--- 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
@@ -57,39 +57,27 @@
 #include "nsIAccessibleProvider.h"
 
 #include "nsIDOMDocument.h"
 #include "nsIDOMHTMLAreaElement.h"
 #include "nsIDOMHTMLLegendElement.h"
 #include "nsIDOMHTMLObjectElement.h"
 #include "nsIDOMHTMLOptGroupElement.h"
 #include "nsIDOMHTMLOptionElement.h"
-#include "nsIDOMWindow.h"
 #include "nsIDOMXULElement.h"
 #include "nsIHTMLDocument.h"
-#include "nsIDocShell.h"
-#include "nsIFrame.h"
-#include "nsIInterfaceRequestorUtils.h"
 #include "nsIImageFrame.h"
 #include "nsILink.h"
-#include "nsINameSpaceManager.h"
 #include "nsIObserverService.h"
 #include "nsIPluginInstance.h"
-#include "nsIPresShell.h"
 #include "nsISupportsUtils.h"
-#include "nsIWebNavigation.h"
 #include "nsObjectFrame.h"
 #include "nsOuterDocAccessible.h"
 #include "nsRootAccessibleWrap.h"
 #include "nsTextFragment.h"
-#include "nsServiceManagerUtils.h"
-#include "nsUnicharUtils.h"
-#include "nsIWebProgress.h"
-#include "nsNetError.h"
-#include "nsDocShellLoadTypes.h"
 #include "mozilla/Services.h"
 
 #ifdef MOZ_XUL
 #include "nsXULAlertAccessible.h"
 #include "nsXULColorPickerAccessible.h"
 #include "nsXULComboboxAccessible.h"
 #include "nsXULFormControlAccessible.h"
 #include "nsXULListboxAccessibleWrap.h"
@@ -114,562 +102,348 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccessibilityService
 ////////////////////////////////////////////////////////////////////////////////
 
 nsAccessibilityService *nsAccessibilityService::gAccessibilityService = nsnull;
 PRBool nsAccessibilityService::gIsShutdown = PR_TRUE;
 
-nsAccessibilityService::nsAccessibilityService()
+nsAccessibilityService::nsAccessibilityService() : nsAccDocManager()
 {
   NS_TIME_FUNCTION;
-
-  // Add observers.
-  nsCOMPtr<nsIObserverService> observerService =
-    mozilla::services::GetObserverService();
-  if (!observerService)
-    return;
-
-  observerService->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, PR_FALSE);
-  nsCOMPtr<nsIWebProgress> progress(do_GetService(NS_DOCUMENTLOADER_SERVICE_CONTRACTID));
-  if (progress) {
-    progress->AddProgressListener(static_cast<nsIWebProgressListener*>(this),
-                                  nsIWebProgress::NOTIFY_STATE_DOCUMENT);
-  }
-
-  // Initialize accessibility.
-  nsAccessNodeWrap::InitAccessibility();
 }
 
 nsAccessibilityService::~nsAccessibilityService()
 {
   NS_ASSERTION(gIsShutdown, "Accessibility wasn't shutdown!");
   gAccessibilityService = nsnull;
 }
 
-NS_IMPL_THREADSAFE_ISUPPORTS5(nsAccessibilityService, nsIAccessibilityService, nsIAccessibleRetrieval,
-                              nsIObserver, nsIWebProgressListener, nsISupportsWeakReference)
+////////////////////////////////////////////////////////////////////////////////
+// nsISupports
 
+NS_IMPL_ISUPPORTS_INHERITED3(nsAccessibilityService,
+                             nsAccDocManager,
+                             nsIAccessibilityService,
+                             nsIAccessibleRetrieval,
+                             nsIObserver)
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsIObserver
 
 NS_IMETHODIMP
 nsAccessibilityService::Observe(nsISupports *aSubject, const char *aTopic,
                          const PRUnichar *aData)
 {
-  if (!nsCRT::strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID)) {
-
-    // Remove observers.
-    nsCOMPtr<nsIObserverService> observerService =
-      mozilla::services::GetObserverService();
-    if (observerService)
-      observerService->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID);
-
-    nsCOMPtr<nsIWebProgress> progress(do_GetService(NS_DOCUMENTLOADER_SERVICE_CONTRACTID));
-    if (progress)
-      progress->RemoveProgressListener(static_cast<nsIWebProgressListener*>(this));
-
-    // Application is going to be closed, shutdown accessibility and mark
-    // accessibility service as shutdown to prevent calls of its methods.
-    // Don't null accessibility service static member at this point to be safe
-    // if someone will try to operate with it.
-
-    NS_ASSERTION(!gIsShutdown, "Accessibility was shutdown already");
-
-    gIsShutdown = PR_TRUE;
-    nsAccessNodeWrap::ShutdownAccessibility();
-  }
+  if (!nsCRT::strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID))
+    Shutdown();
 
   return NS_OK;
 }
 
-////////////////////////////////////////////////////////////////////////////////
-// nsIWebProgressListener
-
-NS_IMETHODIMP nsAccessibilityService::OnStateChange(nsIWebProgress *aWebProgress,
-  nsIRequest *aRequest, PRUint32 aStateFlags, nsresult aStatus)
-{
-  NS_ASSERTION(aStateFlags & STATE_IS_DOCUMENT, "Other notifications excluded");
-
-  if (gIsShutdown || !aWebProgress ||
-      (aStateFlags & (STATE_START | STATE_STOP)) == 0) {
-    return NS_OK;
-  }
-  
-  nsCAutoString name;
-  aRequest->GetName(name);
-  if (name.EqualsLiteral("about:blank"))
-    return NS_OK;
-
-  if (NS_FAILED(aStatus) && (aStateFlags & STATE_START))
-    return NS_OK;
-
-  if (aStateFlags & STATE_START) {
-    NS_DISPATCH_RUNNABLEMETHOD_ARG2(ProcessDocLoadEvent, this, aWebProgress,
-                                    nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_START)
-  } else if (NS_SUCCEEDED(aStatus)) {
-    NS_DISPATCH_RUNNABLEMETHOD_ARG2(ProcessDocLoadEvent, this, aWebProgress,
-                                    nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE)
-  } else { // Failed end load
-    NS_DISPATCH_RUNNABLEMETHOD_ARG2(ProcessDocLoadEvent, this, aWebProgress,
-                                    nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_STOPPED)
-  }
-
-  return NS_OK;
-}
-
-// nsAccessibilityService private
-void
-nsAccessibilityService::ProcessDocLoadEvent(nsIWebProgress *aWebProgress,
-                                            PRUint32 aEventType)
-{
-  if (gIsShutdown)
-    return;
-
-  nsCOMPtr<nsIDOMWindow> domWindow;
-  aWebProgress->GetDOMWindow(getter_AddRefs(domWindow));
-  NS_ENSURE_TRUE(domWindow,);
-
-  if (aEventType == nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_START) {
-    nsCOMPtr<nsIWebNavigation> webNav(do_GetInterface(domWindow));
-    nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(webNav));
-    NS_ENSURE_TRUE(docShell,);
-    PRUint32 loadType;
-    docShell->GetLoadType(&loadType);
-    if (loadType == LOAD_RELOAD_NORMAL ||
-        loadType == LOAD_RELOAD_BYPASS_CACHE ||
-        loadType == LOAD_RELOAD_BYPASS_PROXY ||
-        loadType == LOAD_RELOAD_BYPASS_PROXY_AND_CACHE) {
-      aEventType = nsIAccessibleEvent::EVENT_DOCUMENT_RELOAD;
-    }
-  }
-      
-  nsCOMPtr<nsIDOMDocument> domDoc;
-  domWindow->GetDocument(getter_AddRefs(domDoc));
-  nsCOMPtr<nsIDOMNode> docNode = do_QueryInterface(domDoc);
-  NS_ENSURE_TRUE(docNode,);
-
-  nsCOMPtr<nsIAccessible> accessible;
-  GetAccessibleFor(docNode, getter_AddRefs(accessible));
-  nsRefPtr<nsDocAccessible> docAcc = do_QueryObject(accessible);
-  NS_ENSURE_TRUE(docAcc,);
-
-  docAcc->FireDocLoadEvents(aEventType);
-}
-
 // nsIAccessibilityService
 void
 nsAccessibilityService::NotifyOfAnchorJumpTo(nsIContent *aTarget)
 {
   nsIDocument *document = aTarget->GetCurrentDoc();
-  nsCOMPtr<nsIDOMNode> documentNode(do_QueryInterface(document));
-  if (!documentNode)
+  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
-  nsRefPtr<nsDocAccessible> accessibleDoc =
-    nsAccessNode::GetDocAccessibleFor(documentNode);
-  if (!accessibleDoc)
+  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,
   // for example if the node becomes inaccessible, or is removed from the DOM.
-  accessibleDoc->FireDelayedAccessibleEvent(
-                     nsIAccessibleEvent::EVENT_SCROLLING_START,
-                     targetNode);
+  docAccessible->
+    FireDelayedAccessibleEvent(nsIAccessibleEvent::EVENT_SCROLLING_START,
+                               targetNode);
 }
 
 // nsIAccessibilityService
 nsresult
 nsAccessibilityService::FireAccessibleEvent(PRUint32 aEvent,
                                             nsIAccessible *aTarget)
 {
-  nsEventShell::FireEvent(aEvent, aTarget);
-  return NS_OK;
-}
-
-/* void onProgressChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long aCurSelfProgress, in long aMaxSelfProgress, in long aCurTotalProgress, in long aMaxTotalProgress); */
-NS_IMETHODIMP nsAccessibilityService::OnProgressChange(nsIWebProgress *aWebProgress,
-  nsIRequest *aRequest, PRInt32 aCurSelfProgress, PRInt32 aMaxSelfProgress,
-  PRInt32 aCurTotalProgress, PRInt32 aMaxTotalProgress)
-{
-  NS_NOTREACHED("notification excluded in AddProgressListener(...)");
-  return NS_OK;
-}
-
-/* void onLocationChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsIURI location); */
-NS_IMETHODIMP nsAccessibilityService::OnLocationChange(nsIWebProgress *aWebProgress,
-  nsIRequest *aRequest, nsIURI *location)
-{
-  NS_NOTREACHED("notification excluded in AddProgressListener(...)");
+  nsRefPtr<nsAccessible> accessible(do_QueryObject(aTarget));
+  nsEventShell::FireEvent(aEvent, accessible);
   return NS_OK;
 }
 
-/* void onStatusChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsresult aStatus, in wstring aMessage); */
-NS_IMETHODIMP nsAccessibilityService::OnStatusChange(nsIWebProgress *aWebProgress,
-  nsIRequest *aRequest, nsresult aStatus, const PRUnichar *aMessage)
-{
-  NS_NOTREACHED("notification excluded in AddProgressListener(...)");
-  return NS_OK;
-}
-
-/* void onSecurityChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in unsigned long state); */
-NS_IMETHODIMP nsAccessibilityService::OnSecurityChange(nsIWebProgress *aWebProgress,
-  nsIRequest *aRequest, PRUint32 state)
-{
-  NS_NOTREACHED("notification excluded in AddProgressListener(...)");
-  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;
 }
 
-// nsAccessibilityService private
-already_AddRefed<nsAccessible>
-nsAccessibilityService::CreateDocOrRootAccessible(nsIPresShell *aShell,
-                                                  nsIDocument* aDocument)
-{
-  nsCOMPtr<nsIDOMNode> rootNode(do_QueryInterface(aDocument));
-  NS_ENSURE_TRUE(rootNode, nsnull);
-
-  nsIPresShell *presShell = aShell;
-  if (!presShell) {
-    presShell = aDocument->GetPrimaryShell();
-  }
-  nsCOMPtr<nsIWeakReference> weakShell(do_GetWeakReference(presShell));
-
-  nsCOMPtr<nsISupports> container = aDocument->GetContainer();
-  nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(container);
-  NS_ENSURE_TRUE(docShell, nsnull);
-
-  nsCOMPtr<nsIContentViewer> contentViewer;
-  docShell->GetContentViewer(getter_AddRefs(contentViewer));
-  NS_ENSURE_TRUE(contentViewer, nsnull); // Doc was already shut down
-
-  PRUint32 busyFlags;
-  docShell->GetBusyFlags(&busyFlags);
-  if (busyFlags != nsIDocShell::BUSY_FLAGS_NONE) {
-    nsCOMPtr<nsIWebNavigation> webNav(do_GetInterface(docShell));
-    nsCOMPtr<nsIURI> uri;
-    webNav->GetCurrentURI(getter_AddRefs(uri));
-    NS_ENSURE_TRUE(uri, nsnull);
-
-    nsCAutoString url;
-    uri->GetSpec(url);
-    if (url.EqualsLiteral("about:blank")) {
-      // No load events for a busy about:blank -- they are often temporary.
-      return nsnull;
-    }
-  }
-
-  nsCOMPtr<nsIDocShellTreeItem> docShellTreeItem =
-    do_QueryInterface(container);
-  NS_ENSURE_TRUE(docShellTreeItem, nsnull);
-  
-  nsCOMPtr<nsIDocShellTreeItem> parentTreeItem;
-  docShellTreeItem->GetParent(getter_AddRefs(parentTreeItem));
-
-  nsRefPtr<nsAccessible> accessible;
-  if (parentTreeItem) {
-    // We only create root accessibles for the true root, othewise create a
-    // doc accessible
-    accessible = new nsDocAccessibleWrap(rootNode, weakShell);
-  }
-  else {
-    accessible = new nsRootAccessibleWrap(rootNode, weakShell);
-  }
-
-  return accessible.forget();
-}
-
  /**
    * 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);
@@ -677,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;
 }
 
 /**
@@ -756,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
@@ -802,214 +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)
 {
-  nsCOMPtr<nsIAccessibleDocument> accessibleDoc =
-    nsAccessNode::GetDocAccessibleFor(aWeakShell);
-
-  if (!accessibleDoc)
-    return nsnull;
-
-  nsRefPtr<nsDocAccessible> docAccessible = do_QueryObject(accessibleDoc);
-  return docAccessible->GetCachedAccessNode(static_cast<void*>(aNode));
+  nsDocAccessible *docAccessible = GetDocAccessible(aNode->GetOwnerDoc());
+  return docAccessible ?
+    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);
@@ -1158,153 +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;
 }
 
-////////////////////////////////////////////////////////////////////////////////
-// nsAccessibilityService private
+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!");
@@ -1336,94 +1177,60 @@ static PRBool HasRelatedContent(nsIConte
         // ancestor has activedescendant property, this content could be active
       return PR_TRUE;
     }
   }
 
   return PR_FALSE;
 }
 
-// nsAccessibilityService public
 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.
-  nsRefPtr<nsAccessible> newAcc;
-
-  nsCOMPtr<nsIContent> content(do_QueryInterface(aNode));
-  if (!content) {
-    // This happens when we're on the document node, which will not QI to an
-    // nsIContent.
-    nsCOMPtr<nsIDocument> nodeIsDoc = do_QueryInterface(aNode);
-    if (!nodeIsDoc) // No content, and not doc node.
-      return nsnull;
 
-#ifdef DEBUG
-    // XXX: remove me if you don't see an assertion.
-    nsCOMPtr<nsIAccessibleDocument> accessibleDoc =
-      nsAccessNode::GetDocAccessibleFor(nodeIsDoc);
-    NS_ASSERTION(!accessibleDoc,
-                 "Trying to create already cached accessible document!");
-#endif
+  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));
+    nsAccessible *accessible = GetDocAccessible(document);
+    NS_IF_ADDREF(accessible);
+    return accessible;
+  }
 
-    newAcc = CreateDocOrRootAccessible(aPresShell, nodeIsDoc);
-    if (InitAccessible(newAcc, nsAccUtils::GetRoleMapEntry(aNode)))
-      return newAcc.forget();
+  // We have a content node.
+  if (!aNode->IsInDoc()) {
+    NS_WARNING("Creating accessible for node with no document");
     return nsnull;
   }
 
-  // We have a content node.
-  if (!content->IsInDoc()) {
-    NS_ERROR("Creating accessible for node with no document");
+  if (aNode->GetOwnerDoc() != aPresShell->GetDocument()) {
+    NS_ERROR("Creating accessible for wrong pres shell");
     return nsnull;
   }
 
-  if (content->GetOwnerDoc() != aPresShell->GetDocument()) {
-    NS_ERROR("Creating accessible for wrong pres shell");
+  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.
@@ -1435,20 +1242,22 @@ nsAccessibilityService::GetAccessible(ns
     return nsnull;
   }
 
   if (weakFrame.GetFrame()->GetContent() != content) {
     // Not the main content for this frame. This happens because <area>
     // elements return the image frame as their primary frame. The main content
     // for the image frame is the image content. If the frame is not an image
     // frame or the node is not an area element then null is returned.
+    // This setup will change when bug 135040 is fixed.
     return GetAreaAccessible(weakFrame.GetFrame(), aNode, aWeakShell);
   }
 
   // Attempt to create an accessible based on what we know.
+  nsRefPtr<nsAccessible> newAcc;
   if (content->IsNodeOfType(nsINode::eTEXT)) {
     // --- Create HTML for visible text frames ---
     nsIFrame* f = weakFrame.GetFrame();
     if (f && f->IsEmpty()) {
       nsAutoString renderedWhitespace;
       f->GetRenderedText(&renderedWhitespace, nsnull, nsnull, 0, 1);
       if (renderedWhitespace.IsEmpty()) {
         // Really empty -- nothing is rendered
@@ -1486,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
@@ -1523,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>
@@ -1543,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
@@ -1582,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
@@ -1633,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() && 
@@ -1669,29 +1477,78 @@ 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;
 }
 
+////////////////////////////////////////////////////////////////////////////////
+// nsAccessibilityService private
+
+PRBool
+nsAccessibilityService::Init()
+{
+  // Initialize accessible document manager.
+  if (!nsAccDocManager::Init())
+    return PR_FALSE;
+
+  // Add observers.
+  nsCOMPtr<nsIObserverService> observerService =
+    mozilla::services::GetObserverService();
+  if (!observerService)
+    return PR_FALSE;
+
+  observerService->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, PR_FALSE);
+
+  // Initialize accessibility.
+  nsAccessNodeWrap::InitAccessibility();
+
+  gIsShutdown = PR_FALSE;
+  return PR_TRUE;
+}
+
+void
+nsAccessibilityService::Shutdown()
+{
+  // Remove observers.
+  nsCOMPtr<nsIObserverService> observerService =
+      mozilla::services::GetObserverService();
+  if (observerService)
+    observerService->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID);
+
+  // Stop accessible document loader.
+  nsAccDocManager::Shutdown();
+
+  // Application is going to be closed, shutdown accessibility and mark
+  // accessibility service as shutdown to prevent calls of its methods.
+  // Don't null accessibility service static member at this point to be safe
+  // if someone will try to operate with it.
+
+  NS_ASSERTION(!gIsShutdown, "Accessibility was shutdown already");
+
+  gIsShutdown = PR_TRUE;
+
+  nsAccessNodeWrap::ShutdownAccessibility();
+}
+
 PRBool
 nsAccessibilityService::HasUniversalAriaProperty(nsIContent *aContent)
 {
   // ARIA attributes that take token values (NMTOKEN, bool) are special cased
   // because of special value "undefined" (see HasDefinedARIAToken).
   return nsAccUtils::HasDefinedARIAToken(aContent, nsAccessibilityAtoms::aria_atomic) ||
          nsAccUtils::HasDefinedARIAToken(aContent, nsAccessibilityAtoms::aria_busy) ||
          aContent->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_controls) ||
@@ -1705,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.
 
@@ -1729,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();
@@ -2121,101 +1954,106 @@ nsAccessibilityService::InvalidateSubtre
                aChangeType == nsIAccessibilityService::FRAME_HIDE ||
                aChangeType == nsIAccessibilityService::NODE_SIGNIFICANT_CHANGE ||
                aChangeType == nsIAccessibilityService::NODE_APPEND ||
                aChangeType == nsIAccessibilityService::NODE_REMOVE,
                "Incorrect aEvent passed in");
 
   NS_ENSURE_ARG_POINTER(aShell);
 
-  nsCOMPtr<nsIAccessibleDocument> accessibleDoc =
-    nsAccessNode::GetDocAccessibleFor(aShell->GetDocument());
-  nsRefPtr<nsDocAccessible> docAcc = do_QueryObject(accessibleDoc);
-  if (docAcc)
-    docAcc->InvalidateCacheSubtree(aChangeContent, aChangeType);
+  nsDocAccessible *docAccessible = GetDocAccessible(aShell->GetDocument());
+  if (docAccessible)
+    docAccessible->InvalidateCacheSubtree(aChangeContent, aChangeType);
 
   return NS_OK;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // NS_GetAccessibilityService
 ////////////////////////////////////////////////////////////////////////////////
 
 /**
  * Return accessibility service; creating one if necessary.
  */
 nsresult
 NS_GetAccessibilityService(nsIAccessibilityService** aResult)
 {
-   NS_ENSURE_TRUE(aResult, NS_ERROR_NULL_POINTER);
-   *aResult = nsnull;
+  NS_ENSURE_TRUE(aResult, NS_ERROR_NULL_POINTER);
+  *aResult = nsnull;
  
-  if (!nsAccessibilityService::gAccessibilityService) {
-    nsAccessibilityService::gAccessibilityService = new nsAccessibilityService();
-    NS_ENSURE_TRUE(nsAccessibilityService::gAccessibilityService, NS_ERROR_OUT_OF_MEMORY);
- 
-    nsAccessibilityService::gIsShutdown = PR_FALSE;
-   }
- 
-  NS_ADDREF(*aResult = nsAccessibilityService::gAccessibilityService);
+  if (nsAccessibilityService::gAccessibilityService) {
+    NS_ADDREF(*aResult = nsAccessibilityService::gAccessibilityService);
+    return NS_OK;
+  }
+
+  nsRefPtr<nsAccessibilityService> service = new nsAccessibilityService();
+  NS_ENSURE_TRUE(service, NS_ERROR_OUT_OF_MEMORY);
+
+  if (!service->Init()) {
+    service->Shutdown();
+    return NS_ERROR_FAILURE;
+  }
+
+  nsAccessibilityService::gAccessibilityService = service;
+  NS_ADDREF(*aResult = service);
+
   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
@@ -37,48 +37,30 @@
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef __nsAccessibilityService_h__
 #define __nsAccessibilityService_h__
 
 #include "nsIAccessibilityService.h"
 
 #include "a11yGeneric.h"
-#include "nsCoreUtils.h"
+#include "nsAccDocManager.h"
 
-#include "nsCOMArray.h"
 #include "nsIObserver.h"
-#include "nsIWebProgress.h"
-#include "nsIWebProgressListener.h"
-#include "nsWeakReference.h"
 
-class nsAccessNode;
-class nsAccessible;
-class nsIFrame;
-class nsIWeakReference;
-class nsIDOMNode;
-class nsObjectFrame;
-class nsIDocShell;
-class nsIPresShell;
-class nsIContent;
-struct nsRoleMapEntry;
-
-class nsAccessibilityService : public nsIAccessibilityService,
-                               public nsIObserver,
-                               public nsIWebProgressListener,
-                               public nsSupportsWeakReference
+class nsAccessibilityService : public nsAccDocManager,
+                               public nsIAccessibilityService,
+                               public nsIObserver
 {
 public:
-  nsAccessibilityService();
   virtual ~nsAccessibilityService();
 
-  NS_DECL_ISUPPORTS
+  NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIACCESSIBLERETRIEVAL
   NS_DECL_NSIOBSERVER
-  NS_DECL_NSIWEBPROGRESSLISTENER
 
   // nsIAccessibilityService
   virtual nsAccessible* GetAccessibleInShell(nsIDOMNode *aNode,
                                              nsIPresShell *aPresShell);
 
   virtual nsresult CreateOuterDocAccessible(nsIDOMNode *aNode,
                                             nsIAccessible **aAccessible);
   virtual nsresult CreateHTML4ButtonAccessible(nsIFrame *aFrame,
@@ -137,177 +119,202 @@ 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.
+   * Return true if accessibility service has been shutdown.
    */
-  static nsresult GetShellFromNode(nsIDOMNode *aNode,
-                                   nsIWeakReference **weakShell);
-
-  /**
-   * Indicates whether accessibility service was shutdown.
-   */
-  static PRBool gIsShutdown;
+  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.
    *
-   * @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
+   * XXX: this method must go away once we'll implement correct accessible tree.
+   *
+   * @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);
 
-private:
   /**
-   * Return presentation shell, DOM node for the given frame.
+   * 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.
    *
-   * @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
+   * 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
    */
-  nsresult GetInfo(nsIFrame *aFrame,
-                   nsIWeakReference **aShell,
-                   nsIDOMNode **aContent);
+  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:
+  /**
+   * Initialize accessibility service.
+   */
+  PRBool Init();
+
+  /**
+   * Shutdowns accessibility service.
+   */
+  void Shutdown();
+
+  /**
+   * Return presentation shell, DOM node for 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,
+                   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);
-
-  /**
-   * Create document or root accessible.
-   */
-  already_AddRefed<nsAccessible>
-    CreateDocOrRootAccessible(nsIPresShell *aShell, nsIDocument *aDocument);
+    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;
 
   /**
+   * Indicates whether accessibility service was shutdown.
+   */
+  static PRBool gIsShutdown;
+
+  /**
    * Does this content node have a universal ARIA property set on it?
    * A universal ARIA property is one that can be defined on any element even if there is no role.
    *
    * @param aContent The content node to test
    * @return PR_TRUE if there is a universal ARIA property set on the node
    */
   PRBool HasUniversalAriaProperty(nsIContent *aContent);
 
-  /**
-   *  Process the internal doc load event.
-   *
-   *  @param  aWebProgress  [in] the nsIWebProgress object for the load event
-   *  @param  aEventType    [in] the type of load event, one of:
-   *                          nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_START,
-   *                          nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE,
-   *                          nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_STOPPED
-   */
-  void ProcessDocLoadEvent(nsIWebProgress *aWebProgress, PRUint32 aEventType);
-
   friend nsAccessibilityService* GetAccService();
 
-  friend nsresult  NS_GetAccessibilityService(nsIAccessibilityService** aResult);
-
-  
-  NS_DECL_RUNNABLEMETHOD_ARG2(nsAccessibilityService, ProcessDocLoadEvent,
-                              nsCOMPtr<nsIWebProgress>, PRUint32)
+  friend nsresult NS_GetAccessibilityService(nsIAccessibilityService** aResult);
 };
 
 /**
  * Return the accessibility service instance. (Handy global function)
  */
 inline nsAccessibilityService*
 GetAccService()
 {
@@ -483,17 +490,16 @@ static const char kEventTypeNames[][40] 
   "dragdrop start",                          // EVENT_DRAGDROP_START
   "dragdrop end",                            // EVENT_DRAGDROP_END
   "dialog start",                            // EVENT_DIALOG_START
   "dialog end",                              // EVENT_DIALOG_END
   "scrolling start",                         // EVENT_SCROLLING_START
   "scrolling end",                           // EVENT_SCROLLING_END
   "minimize start",                          // EVENT_MINIMIZE_START
   "minimize end",                            // EVENT_MINIMIZE_END
-  "document load start",                     // EVENT_DOCUMENT_LOAD_START
   "document load complete",                  // EVENT_DOCUMENT_LOAD_COMPLETE
   "document reload",                         // EVENT_DOCUMENT_RELOAD
   "document load stopped",                   // EVENT_DOCUMENT_LOAD_STOPPED
   "document attributes changed",             // EVENT_DOCUMENT_ATTRIBUTES_CHANGED
   "document content changed",                // EVENT_DOCUMENT_CONTENT_CHANGED
   "property changed",                        // EVENT_PROPERTY_CHANGED
   "selection changed",                       // EVENT_SELECTION_CHANGED
   "text attribute changed",                  // EVENT_TEXT_ATTRIBUTE_CHANGED
@@ -531,18 +537,17 @@ static const char kEventTypeNames[][40] 
   "hyperlink number of anchors changed",     // EVENT_HYPERLINK_NUMBER_OF_ANCHORS_CHANGED
   "hyperlink selected link changed",         // EVENT_HYPERLINK_SELECTED_LINK_CHANGED
   "hypertext link activated",                // EVENT_HYPERTEXT_LINK_ACTIVATED
   "hypertext link selected",                 // EVENT_HYPERTEXT_LINK_SELECTED
   "hyperlink start index changed",           // EVENT_HYPERLINK_START_INDEX_CHANGED
   "hypertext changed",                       // EVENT_HYPERTEXT_CHANGED
   "hypertext links count changed",           // EVENT_HYPERTEXT_NLINKS_CHANGED
   "object attribute changed",                // EVENT_OBJECT_ATTRIBUTE_CHANGED
-  "page changed",                            // EVENT_PAGE_CHANGED
-  "internal load"                            // EVENT_INTERNAL_LOAD
+  "page changed"                             // EVENT_PAGE_CHANGED
 };
 
 /**
  * Map nsIAccessibleRelation constants to strings. Used by
  * nsIAccessibleRetrieval::getStringRelationType() method.
  */
 static const char kRelationTypeNames[][20] = {
   "unknown",             // RELATION_NUL
--- 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;
   }