Merge
authorLuke Wagner <lw@mozilla.com>
Thu, 01 Jul 2010 23:10:37 -0700
changeset 53058 65081752a7c809d478743141fa5d5bea0b1f68c0
parent 53050 1e7185c470b0b391ddea72d8af285a01961f5089 (current diff)
parent 47561 bdafb6c8fb3be67fce951d717962c198dfde612f (diff)
child 53059 bf88f75a66ce7f75b7b558210469ca38296cab96
push idunknown
push userunknown
push dateunknown
milestone2.0b2pre
Merge
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
caps/include/nsScriptSecurityManager.h
caps/src/nsScriptSecurityManager.cpp
content/base/public/nsContentUtils.h
content/base/src/nsContentUtils.cpp
content/base/src/nsFrameMessageManager.cpp
content/canvas/src/CustomQS_WebGL.h
content/events/src/nsEventListenerManager.cpp
content/events/src/nsEventListenerManager.h
content/html/content/test/test_bug559284.html
content/html/document/src/nsHTMLDocument.cpp
content/html/document/src/nsHTMLDocument.h
content/html/document/test/test_bug386495.html
dom/base/nsDOMClassInfo.cpp
dom/base/nsDOMClassInfo.h
dom/base/nsGlobalWindow.cpp
dom/base/nsGlobalWindow.h
dom/base/nsJSEnvironment.cpp
dom/locales/en-US/chrome/prompts.properties
editor/txtsvc/src/nsTSDNotifier.cpp
editor/txtsvc/src/nsTSDNotifier.h
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
extensions/spellcheck/locales/en-US/hunspell/README.txt
extensions/spellcheck/locales/en-US/hunspell/mozilla_words.diff
gfx/idl/Makefile.in
gfx/idl/geniid.pl
gfx/idl/gfxIFormats.idl
gfx/idl/gfxidltypes.idl
gfx/idl/nsIFontEnumerator.idl
gfx/idl/nsIScriptableRegion.idl
gfx/public/Makefile.in
gfx/public/gfxCore.h
gfx/public/nsColor.h
gfx/public/nsColorNameList.h
gfx/public/nsColorNames.h
gfx/public/nsCoord.h
gfx/public/nsFont.h
gfx/public/nsGfxCIID.h
gfx/public/nsIDeviceContext.h
gfx/public/nsIFontMetrics.h
gfx/public/nsIRegion.h
gfx/public/nsIRenderingContext.h
gfx/public/nsITheme.h
gfx/public/nsMargin.h
gfx/public/nsPoint.h
gfx/public/nsRect.h
gfx/public/nsRegion.h
gfx/public/nsSize.h
gfx/public/nsThemeConstants.h
gfx/public/nsTransform2D.h
gfx/src/psshared/Makefile.in
gfx/src/psshared/nsCUPSShim.cpp
gfx/src/psshared/nsCUPSShim.h
gfx/src/psshared/nsPSPrinters.cpp
gfx/src/psshared/nsPSPrinters.h
gfx/src/psshared/nsPaperPS.cpp
gfx/src/psshared/nsPaperPS.h
gfx/src/psshared/psSharedCore.h
gfx/thebes/public/GLContext.h
gfx/thebes/public/GLContextProvider.h
gfx/thebes/public/GLDefs.h
gfx/thebes/public/Makefile.in
gfx/thebes/public/WGLLibrary.h
gfx/thebes/public/gfx3DMatrix.h
gfx/thebes/public/gfxASurface.h
gfx/thebes/public/gfxAlphaRecovery.h
gfx/thebes/public/gfxAndroidPlatform.h
gfx/thebes/public/gfxBeOSPlatform.h
gfx/thebes/public/gfxBeOSSurface.h
gfx/thebes/public/gfxColor.h
gfx/thebes/public/gfxContext.h
gfx/thebes/public/gfxD2DSurface.h
gfx/thebes/public/gfxDDrawSurface.h
gfx/thebes/public/gfxDWriteFonts.h
gfx/thebes/public/gfxDirectFBSurface.h
gfx/thebes/public/gfxFT2FontBase.h
gfx/thebes/public/gfxFT2Fonts.h
gfx/thebes/public/gfxFont.h
gfx/thebes/public/gfxFontConstants.h
gfx/thebes/public/gfxFontTest.h
gfx/thebes/public/gfxFontUtils.h
gfx/thebes/public/gfxGdkNativeRenderer.h
gfx/thebes/public/gfxGlitzSurface.h
gfx/thebes/public/gfxImageSurface.h
gfx/thebes/public/gfxMatrix.h
gfx/thebes/public/gfxOS2Fonts.h
gfx/thebes/public/gfxOS2Platform.h
gfx/thebes/public/gfxOS2Surface.h
gfx/thebes/public/gfxPDFSurface.h
gfx/thebes/public/gfxPSSurface.h
gfx/thebes/public/gfxPangoFonts.h
gfx/thebes/public/gfxPath.h
gfx/thebes/public/gfxPattern.h
gfx/thebes/public/gfxPlatform.h
gfx/thebes/public/gfxPlatformGtk.h
gfx/thebes/public/gfxPlatformMac.h
gfx/thebes/public/gfxPoint.h
gfx/thebes/public/gfxQPainterSurface.h
gfx/thebes/public/gfxQtNativeRenderer.h
gfx/thebes/public/gfxQtPlatform.h
gfx/thebes/public/gfxQuartzImageSurface.h
gfx/thebes/public/gfxQuartzNativeDrawing.h
gfx/thebes/public/gfxQuartzPDFSurface.h
gfx/thebes/public/gfxQuartzSurface.h
gfx/thebes/public/gfxRect.h
gfx/thebes/public/gfxSharedImageSurface.h
gfx/thebes/public/gfxSkipChars.h
gfx/thebes/public/gfxTextRunCache.h
gfx/thebes/public/gfxTextRunWordCache.h
gfx/thebes/public/gfxTypes.h
gfx/thebes/public/gfxUserFontSet.h
gfx/thebes/public/gfxUtils.h
gfx/thebes/public/gfxWindowsNativeDrawing.h
gfx/thebes/public/gfxWindowsPlatform.h
gfx/thebes/public/gfxWindowsSurface.h
gfx/thebes/public/gfxXlibNativeRenderer.h
gfx/thebes/public/gfxXlibSurface.h
gfx/thebes/src/GLContext.cpp
gfx/thebes/src/GLContextProviderCGL.mm
gfx/thebes/src/GLContextProviderNull.cpp
gfx/thebes/src/GLContextProviderOSMesa.cpp
gfx/thebes/src/GLContextProviderWGL.cpp
gfx/thebes/src/Makefile.in
gfx/thebes/src/cairo-gdk-utils.c
gfx/thebes/src/cairo-gdk-utils.h
gfx/thebes/src/cairo-xlib-utils.c
gfx/thebes/src/cairo-xlib-utils.h
gfx/thebes/src/gfxASurface.cpp
gfx/thebes/src/gfxAlphaRecovery.cpp
gfx/thebes/src/gfxAndroidPlatform.cpp
gfx/thebes/src/gfxAtomList.h
gfx/thebes/src/gfxAtoms.cpp
gfx/thebes/src/gfxAtoms.h
gfx/thebes/src/gfxBeOSPlatform.cpp
gfx/thebes/src/gfxBeOSSurface.cpp
gfx/thebes/src/gfxContext.cpp
gfx/thebes/src/gfxCoreTextShaper.cpp
gfx/thebes/src/gfxCoreTextShaper.h
gfx/thebes/src/gfxD2DSurface.cpp
gfx/thebes/src/gfxDDrawSurface.cpp
gfx/thebes/src/gfxDWriteCommon.cpp
gfx/thebes/src/gfxDWriteCommon.h
gfx/thebes/src/gfxDWriteFontList.cpp
gfx/thebes/src/gfxDWriteFontList.h
gfx/thebes/src/gfxDWriteFonts.cpp
gfx/thebes/src/gfxDWriteShaper.cpp
gfx/thebes/src/gfxDWriteShaper.h
gfx/thebes/src/gfxDWriteTextAnalysis.cpp
gfx/thebes/src/gfxDWriteTextAnalysis.h
gfx/thebes/src/gfxDirectFBSurface.cpp
gfx/thebes/src/gfxDllDeps.cpp
gfx/thebes/src/gfxFT2FontBase.cpp
gfx/thebes/src/gfxFT2FontList.cpp
gfx/thebes/src/gfxFT2FontList.h
gfx/thebes/src/gfxFT2Fonts.cpp
gfx/thebes/src/gfxFT2Utils.cpp
gfx/thebes/src/gfxFT2Utils.h
gfx/thebes/src/gfxFont.cpp
gfx/thebes/src/gfxFontMissingGlyphs.cpp
gfx/thebes/src/gfxFontMissingGlyphs.h
gfx/thebes/src/gfxFontTest.cpp
gfx/thebes/src/gfxFontUtils.cpp
gfx/thebes/src/gfxFontconfigUtils.cpp
gfx/thebes/src/gfxFontconfigUtils.h
gfx/thebes/src/gfxGDIFont.cpp
gfx/thebes/src/gfxGDIFont.h
gfx/thebes/src/gfxGDIFontList.cpp
gfx/thebes/src/gfxGDIFontList.h
gfx/thebes/src/gfxGDIShaper.cpp
gfx/thebes/src/gfxGDIShaper.h
gfx/thebes/src/gfxGdkNativeRenderer.cpp
gfx/thebes/src/gfxImageSurface.cpp
gfx/thebes/src/gfxMacFont.cpp
gfx/thebes/src/gfxMacFont.h
gfx/thebes/src/gfxMacPlatformFontList.h
gfx/thebes/src/gfxMacPlatformFontList.mm
gfx/thebes/src/gfxMatrix.cpp
gfx/thebes/src/gfxOS2Fonts.cpp
gfx/thebes/src/gfxOS2Platform.cpp
gfx/thebes/src/gfxOS2Surface.cpp
gfx/thebes/src/gfxPDFSurface.cpp
gfx/thebes/src/gfxPSSurface.cpp
gfx/thebes/src/gfxPangoFonts.cpp
gfx/thebes/src/gfxPath.cpp
gfx/thebes/src/gfxPattern.cpp
gfx/thebes/src/gfxPlatform.cpp
gfx/thebes/src/gfxPlatformFontList.cpp
gfx/thebes/src/gfxPlatformFontList.h
gfx/thebes/src/gfxPlatformGtk.cpp
gfx/thebes/src/gfxPlatformMac.cpp
gfx/thebes/src/gfxQPainterSurface.cpp
gfx/thebes/src/gfxQtNativeRenderer.cpp
gfx/thebes/src/gfxQtPlatform.cpp
gfx/thebes/src/gfxQuartzImageSurface.cpp
gfx/thebes/src/gfxQuartzNativeDrawing.cpp
gfx/thebes/src/gfxQuartzPDFSurface.cpp
gfx/thebes/src/gfxQuartzSurface.cpp
gfx/thebes/src/gfxRect.cpp
gfx/thebes/src/gfxSharedImageSurface.cpp
gfx/thebes/src/gfxSkipChars.cpp
gfx/thebes/src/gfxTextRunCache.cpp
gfx/thebes/src/gfxTextRunWordCache.cpp
gfx/thebes/src/gfxUniscribeShaper.cpp
gfx/thebes/src/gfxUniscribeShaper.h
gfx/thebes/src/gfxUserFontSet.cpp
gfx/thebes/src/gfxUtils.cpp
gfx/thebes/src/gfxWindowsNativeDrawing.cpp
gfx/thebes/src/gfxWindowsPlatform.cpp
gfx/thebes/src/gfxWindowsSurface.cpp
gfx/thebes/src/gfxXlibNativeRenderer.cpp
gfx/thebes/src/gfxXlibSurface.cpp
gfx/thebes/src/ignorable.x-ccmap
gfx/thebes/src/nsUnicodeRange.cpp
gfx/thebes/src/nsUnicodeRange.h
gfx/thebes/src/woff-private.h
gfx/thebes/src/woff.c
gfx/thebes/src/woff.h
intl/unicharutil/public/nsHankakuToZenkakuCID.h
intl/unicharutil/src/nsHankakuToZenkaku.cpp
intl/unicharutil/src/nsTextTransformFactory.h
js/src/Makefile.in
js/src/config/rules.mk
js/src/configure.in
js/src/jsapi-tests/testDefineGetterSetterNonEnumerable.cpp
js/src/jsapi-tests/testExtendedEq.cpp
js/src/jsapi-tests/testGCChunkAlloc.cpp
js/src/jsapi-tests/testIsAboutToBeFinalized.cpp
js/src/jsapi-tests/testLookup.cpp
js/src/jsapi-tests/testNewObject.cpp
js/src/jsapi-tests/testPropCache.cpp
js/src/jsapi-tests/testSameValue.cpp
js/src/jsapi-tests/tests.h
js/src/jsapi.cpp
js/src/jsapi.h
js/src/jsarray.cpp
js/src/jsatom.cpp
js/src/jsatom.h
js/src/jsbuiltins.cpp
js/src/jscntxt.cpp
js/src/jscntxt.h
js/src/jscntxtinlines.h
js/src/jsdate.cpp
js/src/jsdbgapi.cpp
js/src/jsdbgapi.h
js/src/jsemit.cpp
js/src/jsexn.cpp
js/src/jsfun.cpp
js/src/jsfun.h
js/src/jsgc.cpp
js/src/jsgc.h
js/src/jsinterp.cpp
js/src/jsinterp.h
js/src/jsiter.cpp
js/src/jsiter.h
js/src/jsobj.cpp
js/src/jsobj.h
js/src/jsobjinlines.h
js/src/json.cpp
js/src/jsopcode.cpp
js/src/jsops.cpp
js/src/jsparse.cpp
js/src/jsparse.h
js/src/jspropertytree.cpp
js/src/jsproxy.cpp
js/src/jsproxy.h
js/src/jsprvtd.h
js/src/jspubtd.h
js/src/jsregexp.cpp
js/src/jsscan.cpp
js/src/jsscope.cpp
js/src/jsscope.h
js/src/jsscopeinlines.h
js/src/jsstr.cpp
js/src/jstl.h
js/src/jstracer.cpp
js/src/jstracer.h
js/src/jstypedarray.cpp
js/src/jstypes.h
js/src/jswrapper.cpp
js/src/jswrapper.h
js/src/jsxdrapi.h
js/src/jsxml.cpp
js/src/jsxml.h
js/src/lirasm/tests/random-opt.in
js/src/lirasm/tests/random-opt.out
js/src/lirasm/tests/random.in
js/src/shell/js.cpp
js/src/tests/README-jsDriver.html
js/src/tests/jsDriver.pl
js/src/tests/jstests.py
js/src/tests/runRhinoTests.pl
js/src/tests/runtests.pl
js/src/tests/runtests2.pl
js/src/xpconnect/idl/nsIXPCScriptable.idl
js/src/xpconnect/idl/nsIXPConnect.idl
js/src/xpconnect/loader/mozJSComponentLoader.cpp
js/src/xpconnect/src/Makefile.in
js/src/xpconnect/src/XPCCrossOriginWrapper.cpp
js/src/xpconnect/src/XPCSafeJSObjectWrapper.cpp
js/src/xpconnect/src/XPCSystemOnlyWrapper.cpp
js/src/xpconnect/src/XPCWrapper.h
js/src/xpconnect/src/nsXPConnect.cpp
js/src/xpconnect/src/qsgen.py
js/src/xpconnect/src/xpccomponents.cpp
js/src/xpconnect/src/xpcconvert.cpp
js/src/xpconnect/src/xpcinlines.h
js/src/xpconnect/src/xpcjsruntime.cpp
js/src/xpconnect/src/xpcprivate.h
js/src/xpconnect/src/xpcruntimesvc.cpp
js/src/xpconnect/src/xpcvariant.cpp
js/src/xpconnect/src/xpcwrappedjs.cpp
js/src/xpconnect/src/xpcwrappednative.cpp
js/src/xpconnect/src/xpcwrappednativejsops.cpp
js/src/xpconnect/src/xpcwrappednativescope.cpp
layout/base/tests/region_lib.js
layout/base/tests/scrolling_helper.html
layout/base/tests/test_scrolling.html
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/plugin/base/src/nsNPAPIPlugin.cpp
netwerk/protocol/gopher/Makefile.in
netwerk/protocol/gopher/nsGopherChannel.cpp
netwerk/protocol/gopher/nsGopherChannel.h
netwerk/protocol/gopher/nsGopherHandler.cpp
netwerk/protocol/gopher/nsGopherHandler.h
netwerk/streamconv/converters/nsGopherDirListingConv.cpp
netwerk/streamconv/converters/nsGopherDirListingConv.h
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
storage/src/mozStoragePrivateHelpers.cpp
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/mozapps/extensions/nsAddonRepository.js
toolkit/mozapps/extensions/nsIAddonRepository.idl
toolkit/mozapps/extensions/test/browser/browser_installssl.xpi
toolkit/mozapps/installer/CFGParser.pm
toolkit/mozapps/installer/make-installjsremoves.pl
toolkit/mozapps/installer/makecfgini.pl
toolkit/mozapps/installer/makeinstallini.pl
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/make-installremoves.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
widget/public/nsIAccelerometer.idl
widget/src/android/nsAccelerometerAndroid.cpp
widget/src/android/nsAccelerometerAndroid.h
widget/src/cocoa/nsAccelerometerX.h
widget/src/cocoa/nsAccelerometerX.mm
widget/src/gtk2/nsAccelerometerUnix.cpp
widget/src/gtk2/nsAccelerometerUnix.h
widget/src/windows/nsAccelerometerWin.cpp
widget/src/windows/nsAccelerometerWin.h
widget/src/xpwidgets/nsAccelerometer.cpp
widget/src/xpwidgets/nsAccelerometer.h
xpcom/base/nsrootidl.idl
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
@@ -32,8 +32,9 @@ fb32f6e1859c07846a01b4478a7b1678019e0b45
 f817a4378f32b1ad0a7c4b5a9949586dba816da5 FENNEC_M11
 5c1e7c779b6edc8ff912001990edc579f80597f4 FENNEC_B1
 fe9cc55b8db7f56f7e68a246acba363743854979 UPDATE_PACKAGING_R8
 6fd4bb500d425c406c1b52f66e5b195b20ae5e0a chromium-import-r15462
 6fd4bb500d425c406c1b52f66e5b195b20ae5e0a chromium-import-latest
 376b78fc72230aaf2ca4e279a8f4ef1efd4a1d9f GECKO_1_9_2_BASE
 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
@@ -39,108 +39,100 @@
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef _nsIAccessibilityService_h_
 #define _nsIAccessibilityService_h_
 
 #include "nsIAccessibleRetrieval.h"
 #include "nsIAccessibleEvent.h"
 
+#include "nsAutoPtr.h"
+
 class nsAccessible;
+class nsINode;
 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.
    *
    * @param  aNode      [in] the DOM node to get an accessible for
    * @param  aPresShell [in] the presentation shell which contains layout info
    *                         for the DOM node
    */
-  virtual nsAccessible* GetAccessibleInShell(nsIDOMNode *aNode,
-                                             nsIPresShell *aPresShell) = 0;
+  virtual nsAccessible* GetAccessibleInShell(nsINode* aNode,
+                                             nsIPresShell* aPresShell) = 0;
 
   /**
    * Creates accessible for the given DOM node or frame.
    */
-  virtual nsresult CreateOuterDocAccessible(nsIDOMNode *aNode,
-                                            nsIAccessible **aAccessible) = 0;
-
-  virtual nsresult CreateHTML4ButtonAccessible(nsIFrame *aFrame,
-                                               nsIAccessible **aAccessible) = 0;
-  virtual nsresult CreateHyperTextAccessible(nsIFrame *aFrame,
-                                             nsIAccessible **aAccessible) = 0;
-  virtual nsresult CreateHTMLBRAccessible(nsIFrame *aFrame,
-                                          nsIAccessible **aAccessible) = 0;
-  virtual nsresult CreateHTMLButtonAccessible(nsIFrame *aFrame,
-                                              nsIAccessible **aAccessible) = 0;
-  virtual nsresult CreateHTMLLIAccessible(nsIFrame *aFrame,
-                                          nsIFrame *aBulletFrame,
-                                          const nsAString& aBulletText,
-                                          nsIAccessible **aAccessible) = 0;
-  virtual nsresult CreateHTMLCheckboxAccessible(nsIFrame *aFrame,
-                                                nsIAccessible **aAccessible) = 0;
-  virtual nsresult CreateHTMLComboboxAccessible(nsIDOMNode *aNode,
-                                                nsIWeakReference *aPresShell,
-                                                nsIAccessible **aAccessible) = 0;
-  virtual nsresult CreateHTMLGenericAccessible(nsIFrame *aFrame,
-                                               nsIAccessible **aAccessible) = 0;
-  virtual nsresult CreateHTMLGroupboxAccessible(nsIFrame *aFrame,
-                                                nsIAccessible **aAccessible) = 0;
-  virtual nsresult CreateHTMLHRAccessible(nsIFrame *aFrame,
-                                          nsIAccessible **aAccessible) = 0;
-  virtual nsresult CreateHTMLImageAccessible(nsIFrame *aFrame,
-                                             nsIAccessible **aAccessible) = 0;
-  virtual nsresult CreateHTMLLabelAccessible(nsIFrame *aFrame,
-                                             nsIAccessible **aAccessible) = 0;
-  virtual nsresult CreateHTMLListboxAccessible(nsIDOMNode *aNode,
-                                               nsIWeakReference *aPresShell,
-                                               nsIAccessible **aAccessible) = 0;
-  virtual nsresult CreateHTMLMediaAccessible(nsIFrame *aFrame,
-                                             nsIAccessible **aAccessible) = 0;
-  virtual nsresult CreateHTMLObjectFrameAccessible(nsObjectFrame *aFrame,
-                                                   nsIAccessible **aAccessible) = 0;
-  virtual nsresult CreateHTMLRadioButtonAccessible(nsIFrame *aFrame,
-                                                   nsIAccessible **aAccessible) = 0;
-  virtual nsresult CreateHTMLSelectOptionAccessible(nsIDOMNode *aNode,
-                                                    nsIAccessible *aAccParent,
-                                                    nsIWeakReference *aPresShell,
-                                                    nsIAccessible **aAccessible) = 0;
-  virtual nsresult CreateHTMLTableAccessible(nsIFrame *aFrame,
-                                             nsIAccessible **aAccessible) = 0;
-  virtual nsresult CreateHTMLTableCellAccessible(nsIFrame *aFrame,
-                                                 nsIAccessible **aAccessible) = 0;
-  virtual nsresult CreateHTMLTextAccessible(nsIFrame *aFrame,
-                                            nsIAccessible **aAccessible) = 0;
-  virtual nsresult CreateHTMLTextFieldAccessible(nsIFrame *aFrame,
-                                                 nsIAccessible **aAccessible) = 0;
-  virtual nsresult CreateHTMLCaptionAccessible(nsIFrame *aFrame,
-                                               nsIAccessible **aAccessible) = 0;
+  virtual already_AddRefed<nsAccessible>
+    CreateHTMLBRAccessible(nsIContent* aContent, nsIPresShell* aPresShell) = 0;
+  virtual already_AddRefed<nsAccessible>
+    CreateHTML4ButtonAccessible(nsIContent* aContent, nsIPresShell* aPresShell) = 0;
+  virtual already_AddRefed<nsAccessible>
+    CreateHTMLButtonAccessible(nsIContent* aContent, nsIPresShell* aPresShell) = 0;
+  virtual already_AddRefed<nsAccessible>
+    CreateHTMLCaptionAccessible(nsIContent* aContent, nsIPresShell* aPresShell) = 0;
+  virtual already_AddRefed<nsAccessible>
+    CreateHTMLCheckboxAccessible(nsIContent* aContent, nsIPresShell* aPresShell) = 0;
+  virtual already_AddRefed<nsAccessible>
+    CreateHTMLComboboxAccessible(nsIContent* aContent, nsIPresShell* aPresShell) = 0;
+  virtual already_AddRefed<nsAccessible>
+    CreateHTMLGroupboxAccessible(nsIContent* aContent, nsIPresShell* aPresShell) = 0;
+  virtual already_AddRefed<nsAccessible>
+    CreateHTMLHRAccessible(nsIContent* aContent, nsIPresShell* aPresShell) = 0;
+  virtual already_AddRefed<nsAccessible>
+    CreateHTMLImageAccessible(nsIContent* aContent, nsIPresShell* aPresShell) = 0;
+  virtual already_AddRefed<nsAccessible>
+    CreateHTMLLabelAccessible(nsIContent* aContent, nsIPresShell* aPresShell) = 0;
+  virtual already_AddRefed<nsAccessible>
+    CreateHTMLLIAccessible(nsIContent* aContent, nsIPresShell* aPresShell,
+                           const nsAString& aBulletText) = 0;
+  virtual already_AddRefed<nsAccessible>
+    CreateHTMLListboxAccessible(nsIContent* aContent, nsIPresShell* aPresShell) = 0;
+  virtual already_AddRefed<nsAccessible>
+    CreateHTMLMediaAccessible(nsIContent* aContent, nsIPresShell* aPresShell) = 0;
+  virtual already_AddRefed<nsAccessible>
+    CreateHTMLObjectFrameAccessible(nsObjectFrame* aFrame, nsIContent* aContent,
+                                    nsIPresShell* aPresShell) = 0;
+  virtual already_AddRefed<nsAccessible>
+    CreateHTMLRadioButtonAccessible(nsIContent* aContent, nsIPresShell* aPresShell) = 0;
+  virtual already_AddRefed<nsAccessible>
+    CreateHTMLTableAccessible(nsIContent* aContent, nsIPresShell* aPresShell) = 0;
+  virtual already_AddRefed<nsAccessible>
+    CreateHTMLTableCellAccessible(nsIContent* aContent, nsIPresShell* aPresShell) = 0;
+  virtual already_AddRefed<nsAccessible>
+    CreateHTMLTextAccessible(nsIContent* aContent, nsIPresShell* aPresShell) = 0;
+  virtual already_AddRefed<nsAccessible>
+    CreateHTMLTextFieldAccessible(nsIContent* aContent, nsIPresShell* aPresShell) = 0;
+  virtual already_AddRefed<nsAccessible>
+    CreateHyperTextAccessible(nsIContent* aContent, nsIPresShell* aPresShell) = 0;
+  virtual already_AddRefed<nsAccessible>
+    CreateOuterDocAccessible(nsIContent* aContent, nsIPresShell* aPresShell) = 0;
 
   /**
    * Adds/remove ATK root accessible for gtk+ native window to/from children
    * of the application accessible.
    */
-  virtual nsresult AddNativeRootAccessible(void *aAtkAccessible,
-                                           nsIAccessible **aAccessible) = 0;
-  virtual nsresult
-    RemoveNativeRootAccessible(nsIAccessible *aRootAccessible) = 0;
+  virtual nsAccessible* AddNativeRootAccessible(void* aAtkAccessible) = 0;
+  virtual void RemoveNativeRootAccessible(nsAccessible* aRootAccessible) = 0;
 
   /**
    * Used to describe sort of changes leading to accessible tree invalidation.
    */
   enum {
     NODE_APPEND = 0x01,
     NODE_REMOVE = 0x02,
     NODE_SIGNIFICANT_CHANGE = 0x03,
@@ -162,16 +154,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;
@@ -648,26 +648,23 @@ gboolean fireRootAccessibleAddedCB(gpoin
                           eventData->index, eventData->root_accessible, NULL);
     g_object_unref(eventData->app_accessible);
     g_object_unref(eventData->root_accessible);
     free(data);
     
     return FALSE;
 }
 
-nsresult
-nsApplicationAccessibleWrap::AddRootAccessible(nsIAccessible *aRootAccWrap)
+PRBool
+nsApplicationAccessibleWrap::AppendChild(nsAccessible *aChild)
 {
-    NS_ENSURE_ARG_POINTER(aRootAccWrap);
+    if (!nsApplicationAccessible::AppendChild(aChild))
+      return PR_FALSE;
 
-    // add by weak reference
-    nsresult rv = nsApplicationAccessible::AddRootAccessible(aRootAccWrap);
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    AtkObject *atkAccessible = nsAccessibleWrap::GetAtkObject(aRootAccWrap);
+    AtkObject *atkAccessible = nsAccessibleWrap::GetAtkObject(aChild);
     atk_object_set_parent(atkAccessible, mAtkObject);
 
     PRUint32 count = mChildren.Length();
 
     // Emit children_changed::add in a timeout
     // to make sure aRootAccWrap is fully initialized.
     AtkRootAccessibleAddedEvent* eventData = (AtkRootAccessibleAddedEvent*)
       malloc(sizeof(AtkRootAccessibleAddedEvent));
@@ -675,32 +672,30 @@ nsApplicationAccessibleWrap::AddRootAcce
       eventData->app_accessible = mAtkObject;
       eventData->root_accessible = atkAccessible;
       eventData->index = count -1;
       g_object_ref(mAtkObject);
       g_object_ref(atkAccessible);
       g_timeout_add(0, fireRootAccessibleAddedCB, eventData);
     }
 
-    return NS_OK;
+    return PR_TRUE;
 }
 
-nsresult
-nsApplicationAccessibleWrap::RemoveRootAccessible(nsIAccessible *aRootAccWrap)
+PRBool
+nsApplicationAccessibleWrap::RemoveChild(nsAccessible* aChild)
 {
-    NS_ENSURE_ARG_POINTER(aRootAccWrap);
+    PRInt32 index = aChild->GetIndexInParent();
 
-    PRInt32 index = mChildren.IndexOf(aRootAccWrap);
-
-    AtkObject *atkAccessible = nsAccessibleWrap::GetAtkObject(aRootAccWrap);
+    AtkObject *atkAccessible = nsAccessibleWrap::GetAtkObject(aChild);
     atk_object_set_parent(atkAccessible, NULL);
     g_signal_emit_by_name(mAtkObject, "children_changed::remove", index,
                           atkAccessible, NULL);
 
-    return nsApplicationAccessible::RemoveRootAccessible(aRootAccWrap);
+    return nsApplicationAccessible::RemoveChild(aChild);
 }
 
 void
 nsApplicationAccessibleWrap::PreCreate()
 {
     if (!sATKChecked) {
         sATKLib = PR_LoadLibrary(sATKLibName);
         if (sATKLib) {
--- a/accessible/src/atk/nsApplicationAccessibleWrap.h
+++ b/accessible/src/atk/nsApplicationAccessibleWrap.h
@@ -50,19 +50,19 @@ public:
     static void Unload();
     static void PreCreate();
 
 public:
     nsApplicationAccessibleWrap();
     virtual ~nsApplicationAccessibleWrap();
 
     // nsAccessNode
-    virtual nsresult Init();
+    virtual PRBool Init();
+
+    // nsAccessible
+    virtual PRBool AppendChild(nsAccessible* aChild);
+    virtual PRBool RemoveChild(nsAccessible* aChild);
 
     // return the atk object for app root accessible
     NS_IMETHOD GetNativeInterface(void **aOutAccessible);
-
-    // nsApplicationAccessible
-    virtual nsresult AddRootAccessible(nsIAccessible *aRootAccWrap);
-    virtual nsresult RemoveRootAccessible(nsIAccessible *aRootAccWrap);
 };
 
 #endif   /* __NS_APP_ROOT_ACCESSIBLE_H__ */
--- 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->GetShell();
+  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->GetShell();                                    \
+  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;
 
@@ -161,37 +154,37 @@ nsAccUtils::GetPositionAndSizeForXULSele
   control->GetIndexOfItem(item, &indexOf);
 
   *aSetSize = itemsCount;
   *aPosInSet = indexOf;
 
   for (PRUint32 index = 0; index < itemsCount; index++) {
     nsCOMPtr<nsIDOMXULSelectControlItemElement> currItem;
     control->GetItemAtIndex(index, getter_AddRefs(currItem));
-    nsCOMPtr<nsIDOMNode> currNode(do_QueryInterface(currItem));
+    nsCOMPtr<nsINode> currNode(do_QueryInterface(currItem));
 
-    nsCOMPtr<nsIAccessible> itemAcc;
-    GetAccService()->GetAccessibleFor(currNode, getter_AddRefs(itemAcc));
+    nsAccessible* itemAcc = GetAccService()->GetAccessible(currNode);
+
     if (!itemAcc ||
         State(itemAcc) & nsIAccessibleStates::STATE_INVISIBLE) {
       (*aSetSize)--;
       if (index < static_cast<PRUint32>(indexOf))
         (*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;
 
@@ -203,19 +196,19 @@ nsAccUtils::GetPositionAndSizeForXULCont
   PRInt32 indexOf = 0;
   container->GetIndexOfItem(item, &indexOf);
 
   // Calculate set size and position in the set.
   *aSetSize = 0, *aPosInSet = 0;
   for (PRInt32 index = indexOf; index >= 0; index--) {
     nsCOMPtr<nsIDOMXULElement> item;
     container->GetItemAtIndex(index, getter_AddRefs(item));
+    nsCOMPtr<nsINode> itemNode(do_QueryInterface(item));
 
-    nsCOMPtr<nsIAccessible> itemAcc;
-    GetAccService()->GetAccessibleFor(item, getter_AddRefs(itemAcc));
+    nsAccessible* itemAcc = GetAccService()->GetAccessible(itemNode);
 
     if (itemAcc) {
       PRUint32 itemRole = Role(itemAcc);
       if (itemRole == nsIAccessibleRole::ROLE_SEPARATOR)
         break; // We reached the beginning of our group.
 
       PRUint32 itemState = State(itemAcc);
       if (!(itemState & nsIAccessibleStates::STATE_INVISIBLE)) {
@@ -224,36 +217,36 @@ nsAccUtils::GetPositionAndSizeForXULCont
       }
     }
   }
 
   for (PRInt32 index = indexOf + 1; index < static_cast<PRInt32>(itemsCount);
        index++) {
     nsCOMPtr<nsIDOMXULElement> item;
     container->GetItemAtIndex(index, getter_AddRefs(item));
+    nsCOMPtr<nsINode> itemNode(do_QueryInterface(item));
     
-    nsCOMPtr<nsIAccessible> itemAcc;
-    GetAccService()->GetAccessibleFor(item, getter_AddRefs(itemAcc));
+    nsAccessible* itemAcc = GetAccService()->GetAccessible(itemNode);
 
     if (itemAcc) {
       PRUint32 itemRole = Role(itemAcc);
       if (itemRole == nsIAccessibleRole::ROLE_SEPARATOR)
         break; // We reached the end of our group.
 
       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,151 +241,102 @@ 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()
+already_AddRefed<nsIPresShell>
+nsAccessNode::GetPresShell()
 {
-  if (!mDOMNode)
-    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()
-{
-  nsIPresShell *presShell = nsnull;
+  nsIPresShell* presShell = nsnull;
   if (mWeakShell)
     CallQueryReferent(mWeakShell.get(), &presShell);
-  if (!presShell) {
-    if (mWeakShell) {
-      // If our pres shell has died, but we're still holding onto
-      // a weak reference, our accessibles are no longer relevant
-      // and should be shut down
-      Shutdown();
-    }
-    return nsnull;
-  }
+
   return presShell;
 }
 
 // nsAccessNode protected
 nsPresContext* nsAccessNode::GetPresContext()
 {
   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 +345,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 +390,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,160 @@
 #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;
-
-    already_AddRefed<nsIDOMNode> GetCurrentFocus();
+  /**
+   * Reference to a node of focused accessible.
+   */
+  static nsINode *gLastFocusedNode;
 
-    /**
-     * Returns true when the accessible is defunct.
-     */
-    virtual PRBool IsDefunct();
+  /**
+   * 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();
 
-    /**
-     * Initialize the access node object, add it to the cache.
-     */
-    virtual nsresult Init();
+  /**
+   * Returns true when the accessible is defunct.
+   */
+  virtual PRBool IsDefunct() { return !mContent; }
 
-    /**
-     * Shutdown the access node object.
-     */
-    virtual nsresult Shutdown();
+  /**
+   * Initialize the access node object, add it to the cache.
+   */
+  virtual PRBool Init();
+
+  /**
+   * 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,902 +102,448 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 // 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(...)");
-  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)
-{
-  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)
-    return NS_ERROR_FAILURE;
-
-  *aNode = node;
-  NS_IF_ADDREF(*aNode);
-
-  nsCOMPtr<nsIDocument> document = content->GetDocument();
-  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);
-
+  nsRefPtr<nsAccessible> accessible(do_QueryObject(aTarget));
+  nsEventShell::FireEvent(aEvent, accessible);
   return NS_OK;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsIAccessibilityService
 
-nsresult
-nsAccessibilityService::CreateOuterDocAccessible(nsIDOMNode* aDOMNode, 
-                                                 nsIAccessible **aOuterDocAccessible)
+already_AddRefed<nsAccessible>
+nsAccessibilityService::CreateOuterDocAccessible(nsIContent* aContent,
+                                                 nsIPresShell* aPresShell)
 {
-  NS_ENSURE_ARG_POINTER(aDOMNode);
-  
-  *aOuterDocAccessible = nsnull;
-
-  nsCOMPtr<nsIWeakReference> outerWeakShell;
-  GetShellFromNode(aDOMNode, getter_AddRefs(outerWeakShell));
-  NS_ENSURE_TRUE(outerWeakShell, NS_ERROR_FAILURE);
-
-  nsOuterDocAccessible *outerDocAccessible =
-    new nsOuterDocAccessible(aDOMNode, outerWeakShell);
-  NS_ENSURE_TRUE(outerDocAccessible, NS_ERROR_FAILURE);
-
-  NS_ADDREF(*aOuterDocAccessible = outerDocAccessible);
-
-  return NS_OK;
+  nsCOMPtr<nsIWeakReference> weakShell(do_GetWeakReference(aPresShell));
+  nsAccessible* accessible = new nsOuterDocAccessible(aContent, weakShell);
+  NS_IF_ADDREF(accessible);
+  return accessible;
 }
 
-// nsAccessibilityService private
 already_AddRefed<nsAccessible>
-nsAccessibilityService::CreateDocOrRootAccessible(nsIPresShell *aShell,
-                                                  nsIDocument* aDocument)
+nsAccessibilityService::CreateHTML4ButtonAccessible(nsIContent* aContent,
+                                                    nsIPresShell* aPresShell)
 {
-  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();
+  nsCOMPtr<nsIWeakReference> weakShell(do_GetWeakReference(aPresShell));
+  nsAccessible* accessible = new nsHTML4ButtonAccessible(aContent, weakShell);
+  NS_IF_ADDREF(accessible);
+  return accessible;
 }
 
- /**
-   * HTML widget creation
-   */
-nsresult
-nsAccessibilityService::CreateHTML4ButtonAccessible(nsIFrame *aFrame, nsIAccessible **_retval)
+already_AddRefed<nsAccessible>
+nsAccessibilityService::CreateHTMLButtonAccessible(nsIContent* aContent,
+                                                   nsIPresShell* aPresShell)
 {
-  nsCOMPtr<nsIDOMNode> node;
-  nsCOMPtr<nsIWeakReference> weakShell;
-  nsresult rv = GetInfo(aFrame, getter_AddRefs(weakShell), getter_AddRefs(node));
-  if (NS_FAILED(rv))
-    return rv;
-
-  *_retval = new nsHTML4ButtonAccessible(node, weakShell);
-  if (! *_retval) 
-    return NS_ERROR_OUT_OF_MEMORY;
-
-  NS_ADDREF(*_retval);
-  return NS_OK;
-}
-
-nsresult
-nsAccessibilityService::CreateHTMLButtonAccessible(nsIFrame *aFrame, nsIAccessible **_retval)
-{
-  nsCOMPtr<nsIDOMNode> node;
-  nsCOMPtr<nsIWeakReference> weakShell;
-  nsresult rv = GetInfo(aFrame, getter_AddRefs(weakShell), getter_AddRefs(node));
-  if (NS_FAILED(rv))
-    return rv;
-
-  *_retval = new nsHTMLButtonAccessible(node, weakShell);
-  if (! *_retval) 
-    return NS_ERROR_OUT_OF_MEMORY;
-
-  NS_ADDREF(*_retval);
-  return NS_OK;
+  nsCOMPtr<nsIWeakReference> weakShell(do_GetWeakReference(aPresShell));
+  nsAccessible* accessible = new nsHTMLButtonAccessible(aContent, weakShell);
+  NS_IF_ADDREF(accessible);
+  return accessible;
 }
 
-// nsAccessibilityService private
 already_AddRefed<nsAccessible>
-nsAccessibilityService::CreateHTMLAccessibleByMarkup(nsIFrame *aFrame,
-                                                     nsIWeakReference *aWeakShell,
-                                                     nsIDOMNode *aNode)
+nsAccessibilityService::CreateHTMLLIAccessible(nsIContent* aContent,
+                                               nsIPresShell* aPresShell,
+                                               const nsAString& aBulletText)
 {
-  // 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);
-  }
-  else if (tag == nsAccessibilityAtoms::option) {
-    accessible = new nsHTMLSelectOptionAccessible(aNode, aWeakShell);
-  }
-  else if (tag == nsAccessibilityAtoms::optgroup) {
-    accessible = new nsHTMLSelectOptGroupAccessible(aNode, aWeakShell);
-  }
-  else if (tag == nsAccessibilityAtoms::ul || tag == nsAccessibilityAtoms::ol ||
-           tag == nsAccessibilityAtoms::dl) {
-    accessible = new nsHTMLListAccessible(aNode, 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) {
+  nsCOMPtr<nsIWeakReference> weakShell(do_GetWeakReference(aPresShell));
+  nsAccessible* accessible = new nsHTMLLIAccessible(aContent, weakShell,
+                                                    aBulletText);
+  NS_IF_ADDREF(accessible);
+  return accessible;
+}
 
-      accessible = new nsHyperTextAccessibleWrap(aNode, aWeakShell);
-    } else {
-      accessible = new nsHTMLLinkAccessible(aNode, 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());
-  }
-  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);
-  }
-  else if (tag == nsAccessibilityAtoms::tr) {
-    accessible = new nsEnumRoleAccessible(aNode, aWeakShell,
-                                            nsIAccessibleRole::ROLE_ROW);
-  }
-  else if (nsCoreUtils::IsHTMLTableHeader(content)) {
-    accessible = new nsHTMLTableHeaderCellAccessibleWrap(aNode, aWeakShell);
-  }
-
-  return accessible.forget();
+already_AddRefed<nsAccessible>
+nsAccessibilityService::CreateHyperTextAccessible(nsIContent* aContent,
+                                                  nsIPresShell* aPresShell)
+{
+  nsCOMPtr<nsIWeakReference> weakShell(do_GetWeakReference(aPresShell));
+  nsAccessible* accessible = new nsHyperTextAccessibleWrap(aContent, weakShell);
+  NS_IF_ADDREF(accessible);
+  return accessible;
 }
 
-nsresult
-nsAccessibilityService::CreateHTMLLIAccessible(nsIFrame *aFrame, 
-                                               nsIFrame *aBulletFrame,
-                                               const nsAString& aBulletText,
-                                               nsIAccessible **_retval)
+already_AddRefed<nsAccessible>
+nsAccessibilityService::CreateHTMLCheckboxAccessible(nsIContent* aContent,
+                                                     nsIPresShell* aPresShell)
 {
-  nsCOMPtr<nsIDOMNode> node;
-  nsCOMPtr<nsIWeakReference> weakShell;
-  nsresult rv = GetInfo(aFrame, getter_AddRefs(weakShell), getter_AddRefs(node));
-  if (NS_FAILED(rv))
-    return rv;
-
-  *_retval = new nsHTMLLIAccessible(node, weakShell, aBulletText);
-  if (! *_retval) 
-    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;
+  nsCOMPtr<nsIWeakReference> weakShell(do_GetWeakReference(aPresShell));
+  nsAccessible* accessible = new nsHTMLCheckboxAccessible(aContent, weakShell);
+  NS_IF_ADDREF(accessible);
+  return accessible;
 }
 
-nsresult
-nsAccessibilityService::CreateHTMLCheckboxAccessible(nsIFrame *aFrame, nsIAccessible **_retval)
+already_AddRefed<nsAccessible>
+nsAccessibilityService::CreateHTMLComboboxAccessible(nsIContent* aContent,
+                                                     nsIPresShell* aPresShell)
 {
-  nsCOMPtr<nsIDOMNode> node;
-  nsCOMPtr<nsIWeakReference> weakShell;
-  nsresult rv = GetInfo(aFrame, getter_AddRefs(weakShell), getter_AddRefs(node));
-  if (NS_FAILED(rv))
-    return rv;
-
-  *_retval = new nsHTMLCheckboxAccessible(node, weakShell);
-  if (! *_retval) 
-    return NS_ERROR_OUT_OF_MEMORY;
-
-  NS_ADDREF(*_retval);
-  return NS_OK;
+  nsCOMPtr<nsIWeakReference> weakShell(do_GetWeakReference(aPresShell));
+  nsAccessible* accessible = new nsHTMLComboboxAccessible(aContent, weakShell);
+  NS_IF_ADDREF(accessible);
+  return accessible;
 }
 
-nsresult
-nsAccessibilityService::CreateHTMLComboboxAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aPresShell, nsIAccessible **_retval)
-{
-  *_retval = new nsHTMLComboboxAccessible(aDOMNode, aPresShell);
-  if (! *_retval)
-    return NS_ERROR_OUT_OF_MEMORY;
-
-  NS_ADDREF(*_retval);
-  return NS_OK;
-}
-
-nsresult
-nsAccessibilityService::CreateHTMLImageAccessible(nsIFrame *aFrame,
-                                                  nsIAccessible **aAccessible)
+already_AddRefed<nsAccessible>
+nsAccessibilityService::CreateHTMLImageAccessible(nsIContent* aContent,
+                                                  nsIPresShell* aPresShell)
 {
-  NS_ENSURE_ARG_POINTER(aAccessible);
-  *aAccessible = nsnull;
-
-  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_STATE(content);
-
   nsCOMPtr<nsIHTMLDocument> htmlDoc =
-    do_QueryInterface(content->GetCurrentDoc());
+    do_QueryInterface(aContent->GetCurrentDoc());
 
   nsCOMPtr<nsIDOMHTMLMapElement> mapElm;
   if (htmlDoc) {
     nsAutoString mapElmName;
-    content->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::usemap,
-                     mapElmName);
+    aContent->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::usemap,
+                      mapElmName);
 
     if (!mapElmName.IsEmpty()) {
       if (mapElmName.CharAt(0) == '#')
         mapElmName.Cut(0,1);
       mapElm = htmlDoc->GetImageMap(mapElmName);
     }
   }
 
-  if (mapElm)
-    *aAccessible = new nsHTMLImageMapAccessible(node, weakShell, mapElm);
-  else
-    *aAccessible = new nsHTMLImageAccessibleWrap(node, 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);
+  nsCOMPtr<nsIWeakReference> weakShell(do_GetWeakReference(aPresShell));
+  nsAccessible* accessible = mapElm ?
+    new nsHTMLImageMapAccessible(aContent, weakShell, mapElm) :
+    new nsHTMLImageAccessibleWrap(aContent, weakShell);
+  NS_IF_ADDREF(accessible);
+  return accessible;
 }
 
-nsresult
-nsAccessibilityService::CreateHTMLGroupboxAccessible(nsIFrame *aFrame, nsIAccessible **_retval)
+already_AddRefed<nsAccessible>
+nsAccessibilityService::CreateHTMLGroupboxAccessible(nsIContent* aContent,
+                                                     nsIPresShell* aPresShell)
 {
-  nsCOMPtr<nsIDOMNode> node;
-  nsCOMPtr<nsIWeakReference> weakShell;
-  nsresult rv = GetInfo(aFrame, getter_AddRefs(weakShell), getter_AddRefs(node));
-  if (NS_FAILED(rv))
-    return rv;
-
-  *_retval = new nsHTMLGroupboxAccessible(node, weakShell);
-  if (! *_retval) 
-    return NS_ERROR_OUT_OF_MEMORY;
-
-  NS_ADDREF(*_retval);
-  return NS_OK;
+  nsCOMPtr<nsIWeakReference> weakShell(do_GetWeakReference(aPresShell));
+  nsAccessible* accessible = new nsHTMLGroupboxAccessible(aContent, weakShell);
+  NS_IF_ADDREF(accessible);
+  return accessible;
 }
 
-nsresult
-nsAccessibilityService::CreateHTMLListboxAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aPresShell, nsIAccessible **_retval)
+already_AddRefed<nsAccessible>
+nsAccessibilityService::CreateHTMLListboxAccessible(nsIContent* aContent,
+                                                    nsIPresShell* aPresShell)
 {
-  *_retval = new nsHTMLSelectListAccessible(aDOMNode, aPresShell);
-  if (! *_retval) 
-    return NS_ERROR_OUT_OF_MEMORY;
-
-  NS_ADDREF(*_retval);
-  return NS_OK;
+  nsCOMPtr<nsIWeakReference> weakShell(do_GetWeakReference(aPresShell));
+  nsAccessible* accessible = new nsHTMLSelectListAccessible(aContent, weakShell);
+  NS_IF_ADDREF(accessible);
+  return accessible;
 }
 
-nsresult
-nsAccessibilityService::CreateHTMLMediaAccessible(nsIFrame *aFrame,
-                                                  nsIAccessible **aAccessible)
+already_AddRefed<nsAccessible>
+nsAccessibilityService::CreateHTMLMediaAccessible(nsIContent* aContent,
+                                                  nsIPresShell* aPresShell)
 {
-  NS_ENSURE_ARG_POINTER(aAccessible);
-  *aAccessible = nsnull;
-
-  nsCOMPtr<nsIDOMNode> node;
-  nsCOMPtr<nsIWeakReference> weakShell;
-  nsresult rv = GetInfo(aFrame, getter_AddRefs(weakShell),
-                        getter_AddRefs(node));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  *aAccessible = new nsEnumRoleAccessible(node, weakShell,
-                                          nsIAccessibleRole::ROLE_GROUPING);
-  NS_ENSURE_TRUE(*aAccessible, NS_ERROR_OUT_OF_MEMORY);
-
-  NS_ADDREF(*aAccessible);
-  return NS_OK;
+  nsCOMPtr<nsIWeakReference> weakShell(do_GetWeakReference(aPresShell));
+  nsAccessible* accessible = new nsEnumRoleAccessible(aContent, weakShell,
+                                                      nsIAccessibleRole::ROLE_GROUPING);
+  NS_IF_ADDREF(accessible);
+  return accessible;
 }
 
-/**
-  * We can have several cases here. 
-  *  1) a text or html embedded document where the contentDocument
-  *     variable in the object element holds the content
-  *  2) web content that uses a plugin, which means we will
-  *     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)
+already_AddRefed<nsAccessible>
+nsAccessibilityService::CreateHTMLObjectFrameAccessible(nsObjectFrame* aFrame,
+                                                        nsIContent* aContent,
+                                                        nsIPresShell* aPresShell)
 {
-  nsCOMPtr<nsIDOMNode> node;
-  nsCOMPtr<nsIWeakReference> weakShell;
-  GetInfo(aFrame, getter_AddRefs(weakShell), getter_AddRefs(node));
+  // We can have several cases here:
+  // 1) a text or html embedded document where the contentDocument variable in
+  //    the object element holds the content;
+  // 2) web content that uses a plugin, which means we will 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.
 
-  *aAccessible = nsnull;
-  if (aFrame->GetRect().IsEmpty()) {
-    return NS_ERROR_FAILURE;
-  }
+  if (aFrame->GetRect().IsEmpty())
+    return nsnull;
+
+  nsCOMPtr<nsIWeakReference> weakShell(do_GetWeakReference(aPresShell));
+
   // 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(aContent));
+  if (obj) {
+    nsCOMPtr<nsIDOMDocument> domDoc;
     obj->GetContentDocument(getter_AddRefs(domDoc));
-  else
-    domDoc = do_QueryInterface(node);
-  if (domDoc)
-    return CreateOuterDocAccessible(node, aAccessible);
+    if (domDoc)
+      return CreateOuterDocAccessible(aContent, aPresShell);
+  }
 
 #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);
-    NS_ENSURE_TRUE(*aAccessible, NS_ERROR_OUT_OF_MEMORY);
-
-    NS_ADDREF(*aAccessible);
-    return NS_OK;
+    nsAccessible* accessible = new nsHTMLWin32ObjectOwnerAccessible(aContent,
+                                                                    weakShell,
+                                                                    pluginPort);
+    NS_IF_ADDREF(accessible);
+    return accessible;
   }
 #endif
 
   // 3) for images and imagemaps, or anything else with a child frame
   // we have the object frame, get the image frame
-  nsIFrame *frame = aFrame->GetFirstChild(nsnull);
-  if (frame)
-    return frame->GetAccessible(aAccessible);
-
-  return NS_OK;
+  nsIFrame* frame = aFrame->GetFirstChild(nsnull);
+  return frame ? frame->CreateAccessible() : nsnull;
 }
 
-nsresult
-nsAccessibilityService::CreateHTMLRadioButtonAccessible(nsIFrame *aFrame, nsIAccessible **_retval)
+already_AddRefed<nsAccessible>
+nsAccessibilityService::CreateHTMLRadioButtonAccessible(nsIContent* aContent,
+                                                        nsIPresShell* aPresShell)
 {
-  nsCOMPtr<nsIDOMNode> node;
-  nsCOMPtr<nsIWeakReference> weakShell;
-  nsresult rv = GetInfo(aFrame, getter_AddRefs(weakShell), getter_AddRefs(node));
-  if (NS_FAILED(rv))
-    return rv;
-
-  *_retval = new nsHTMLRadioButtonAccessible(node, weakShell);
-  if (! *_retval) 
-    return NS_ERROR_OUT_OF_MEMORY;
-
-  NS_ADDREF(*_retval);
-  return NS_OK;
+  nsCOMPtr<nsIWeakReference> weakShell(do_GetWeakReference(aPresShell));
+  nsAccessible* accessible = new nsHTMLRadioButtonAccessible(aContent, weakShell);
+  NS_IF_ADDREF(accessible);
+  return accessible;
 }
 
-nsresult
-nsAccessibilityService::CreateHTMLSelectOptionAccessible(nsIDOMNode* aDOMNode, 
-                                                         nsIAccessible *aParent, 
-                                                         nsIWeakReference* aPresShell, 
-                                                         nsIAccessible **_retval)
+already_AddRefed<nsAccessible>
+nsAccessibilityService::CreateHTMLTableAccessible(nsIContent* aContent,
+                                                  nsIPresShell* aPresShell)
 {
-  *_retval = new nsHTMLSelectOptionAccessible(aDOMNode, aPresShell);
-  if (! *_retval) 
-    return NS_ERROR_OUT_OF_MEMORY;
-
-  NS_ADDREF(*_retval);
-  return NS_OK;
+  nsCOMPtr<nsIWeakReference> weakShell(do_GetWeakReference(aPresShell));
+  nsAccessible* accessible = new nsHTMLTableAccessibleWrap(aContent, weakShell);
+  NS_IF_ADDREF(accessible);
+  return accessible;
 }
 
-nsresult
-nsAccessibilityService::CreateHTMLTableAccessible(nsIFrame *aFrame, nsIAccessible **_retval)
+already_AddRefed<nsAccessible>
+nsAccessibilityService::CreateHTMLTableCellAccessible(nsIContent* aContent,
+                                                      nsIPresShell* aPresShell)
 {
-  nsCOMPtr<nsIDOMNode> node;
-  nsCOMPtr<nsIWeakReference> weakShell;
-  nsresult rv = GetInfo(aFrame, getter_AddRefs(weakShell), getter_AddRefs(node));
-  if (NS_FAILED(rv))
-    return rv;
-
-  *_retval = new nsHTMLTableAccessibleWrap(node, weakShell);
-  if (! *_retval) 
-    return NS_ERROR_OUT_OF_MEMORY;
-
-  NS_ADDREF(*_retval);
-  return NS_OK;
+  nsCOMPtr<nsIWeakReference> weakShell(do_GetWeakReference(aPresShell));
+  nsAccessible* accessible = new nsHTMLTableCellAccessibleWrap(aContent,
+                                                               weakShell);
+  NS_IF_ADDREF(accessible);
+  return accessible;
 }
 
-nsresult
-nsAccessibilityService::CreateHTMLTableCellAccessible(nsIFrame *aFrame,
-                                                      nsIAccessible **aAccessible)
+already_AddRefed<nsAccessible>
+nsAccessibilityService::CreateHTMLTextAccessible(nsIContent* aContent,
+                                                 nsIPresShell* aPresShell)
 {
-  nsCOMPtr<nsIDOMNode> node;
-  nsCOMPtr<nsIWeakReference> weakShell;
-  nsresult rv = GetInfo(aFrame, getter_AddRefs(weakShell), getter_AddRefs(node));
-  if (NS_FAILED(rv))
-    return rv;
-
-  *aAccessible = new nsHTMLTableCellAccessibleWrap(node, weakShell);
-  if (!*aAccessible) 
-    return NS_ERROR_OUT_OF_MEMORY;
-
-  NS_ADDREF(*aAccessible);
-  return NS_OK;
+  nsCOMPtr<nsIWeakReference> weakShell(do_GetWeakReference(aPresShell));
+  nsAccessible* accessible = new nsHTMLTextAccessible(aContent, weakShell);
+  NS_IF_ADDREF(accessible);
+  return accessible;
 }
 
-nsresult
-nsAccessibilityService::CreateHTMLTextAccessible(nsIFrame *aFrame, nsIAccessible **_retval)
+already_AddRefed<nsAccessible>
+nsAccessibilityService::CreateHTMLTextFieldAccessible(nsIContent* aContent,
+                                                      nsIPresShell* aPresShell)
 {
-  *_retval = nsnull;
-
-  nsCOMPtr<nsIDOMNode> node;
-  nsCOMPtr<nsIWeakReference> weakShell;
-  nsresult rv = GetInfo(aFrame, getter_AddRefs(weakShell), getter_AddRefs(node));
-  if (NS_FAILED(rv))
-    return rv;
-
-  // XXX Don't create ATK objects for these
-  *_retval = new nsHTMLTextAccessible(node, weakShell);
-  if (! *_retval) 
-    return NS_ERROR_OUT_OF_MEMORY;
-
-  NS_ADDREF(*_retval);
-  return NS_OK;
+  nsCOMPtr<nsIWeakReference> weakShell(do_GetWeakReference(aPresShell));
+  nsAccessible* accessible = new nsHTMLTextFieldAccessible(aContent, weakShell);
+  NS_IF_ADDREF(accessible);
+  return accessible;
 }
 
-nsresult
-nsAccessibilityService::CreateHTMLTextFieldAccessible(nsIFrame *aFrame, nsIAccessible **_retval)
+already_AddRefed<nsAccessible>
+nsAccessibilityService::CreateHTMLLabelAccessible(nsIContent* aContent,
+                                                  nsIPresShell* aPresShell)
 {
-  nsCOMPtr<nsIDOMNode> node;
-  nsCOMPtr<nsIWeakReference> weakShell;
-  nsresult rv = GetInfo(aFrame, getter_AddRefs(weakShell), getter_AddRefs(node));
-  if (NS_FAILED(rv))
-    return rv;
-
-  *_retval = new nsHTMLTextFieldAccessible(node, weakShell);
-  if (! *_retval) 
-    return NS_ERROR_OUT_OF_MEMORY;
-
-  NS_ADDREF(*_retval);
-  return NS_OK;
+  nsCOMPtr<nsIWeakReference> weakShell(do_GetWeakReference(aPresShell));
+  nsAccessible* accessible = new nsHTMLLabelAccessible(aContent, weakShell);
+  NS_IF_ADDREF(accessible);
+  return accessible;
 }
 
-nsresult
-nsAccessibilityService::CreateHTMLLabelAccessible(nsIFrame *aFrame, nsIAccessible **_retval)
+already_AddRefed<nsAccessible>
+nsAccessibilityService::CreateHTMLHRAccessible(nsIContent* aContent,
+                                               nsIPresShell* aPresShell)
 {
-  nsCOMPtr<nsIDOMNode> node;
-  nsCOMPtr<nsIWeakReference> weakShell;
-  nsresult rv = GetInfo(aFrame, getter_AddRefs(weakShell), getter_AddRefs(node));
-  if (NS_FAILED(rv))
-    return rv;
+  nsCOMPtr<nsIWeakReference> weakShell(do_GetWeakReference(aPresShell));
+  nsAccessible* accessible = new nsHTMLHRAccessible(aContent, weakShell);
+  NS_IF_ADDREF(accessible);
+  return accessible;
+}
 
-  *_retval = new nsHTMLLabelAccessible(node, weakShell);
-  if (! *_retval) 
-    return NS_ERROR_OUT_OF_MEMORY;
-
-  NS_ADDREF(*_retval);
-  return NS_OK;
+already_AddRefed<nsAccessible>
+nsAccessibilityService::CreateHTMLBRAccessible(nsIContent* aContent,
+                                               nsIPresShell* aPresShell)
+{
+  nsCOMPtr<nsIWeakReference> weakShell(do_GetWeakReference(aPresShell));
+  nsAccessible* accessible = new nsHTMLBRAccessible(aContent, weakShell);
+  NS_IF_ADDREF(accessible);
+  return accessible;
 }
 
-nsresult
-nsAccessibilityService::CreateHTMLHRAccessible(nsIFrame *aFrame, nsIAccessible **_retval)
+already_AddRefed<nsAccessible>
+nsAccessibilityService::CreateHTMLCaptionAccessible(nsIContent* aContent,
+                                                    nsIPresShell* aPresShell)
 {
-  nsCOMPtr<nsIDOMNode> node;
-  nsCOMPtr<nsIWeakReference> weakShell;
-  nsresult rv = GetInfo(aFrame, getter_AddRefs(weakShell), getter_AddRefs(node));
-  if (NS_FAILED(rv))
-    return rv;
-
-  *_retval = new nsHTMLHRAccessible(node, weakShell);
-  if (! *_retval) 
-    return NS_ERROR_OUT_OF_MEMORY;
-
-  NS_ADDREF(*_retval);
-  return NS_OK;
+  nsCOMPtr<nsIWeakReference> weakShell(do_GetWeakReference(aPresShell));
+  nsAccessible* accessible = new nsHTMLCaptionAccessible(aContent, weakShell);
+  NS_IF_ADDREF(accessible);
+  return accessible;
 }
 
-nsresult
-nsAccessibilityService::CreateHTMLBRAccessible(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 nsHTMLBRAccessible(node, weakShell);
-  if (! *_retval) 
-    return NS_ERROR_OUT_OF_MEMORY;
-
-  NS_ADDREF(*_retval);
-  return NS_OK;
+  NS_LOG_ACCDOCDESTROY("presshell destroyed", doc)
+  ShutdownDocAccessible(doc);
 }
 
-nsresult
-nsAccessibilityService::CreateHTMLCaptionAccessible(nsIFrame *aFrame, nsIAccessible **_retval)
-{
-  nsCOMPtr<nsIDOMNode> node;
-  nsCOMPtr<nsIWeakReference> weakShell;
-  nsresult rv = GetInfo(aFrame, getter_AddRefs(weakShell), getter_AddRefs(node));
-  if (NS_FAILED(rv))
-    return rv;
-
-  *_retval = new nsHTMLCaptionAccessible(node, weakShell);
-  if (! *_retval) 
-    return NS_ERROR_OUT_OF_MEMORY;
-
-  NS_ADDREF(*_retval);
-  return NS