Bug 545738 - clean up nsAccessibilityService::GetAccessible() and related, r=davidb
authorAlexander Surkov <surkov.alexander@gmail.com>
Sat, 20 Feb 2010 16:56:35 -0800
changeset 38359 acab380e4de3a68370c1b7894b167e8a9007d05d
parent 38358 d804f02df155b0e65a7685b22ecc0b6d1a329858
child 38360 ab5aec9ca05beac5cfcaec5d06cec8af0f343511
push idunknown
push userunknown
push dateunknown
reviewersdavidb
bugs545738
milestone1.9.3a2pre
Bug 545738 - clean up nsAccessibilityService::GetAccessible() and related, r=davidb
accessible/public/nsIAccessibilityService.idl
accessible/src/base/nsAccTreeWalker.cpp
accessible/src/base/nsAccTreeWalker.h
accessible/src/base/nsAccUtils.cpp
accessible/src/base/nsAccessNode.cpp
accessible/src/base/nsAccessNode.h
accessible/src/base/nsAccessibilityService.cpp
accessible/src/base/nsAccessibilityService.h
accessible/src/base/nsAccessible.cpp
accessible/src/base/nsDocAccessible.cpp
accessible/src/base/nsDocAccessible.h
accessible/src/xul/nsXULColorPickerAccessible.cpp
accessible/src/xul/nsXULFormControlAccessible.cpp
--- a/accessible/public/nsIAccessibilityService.idl
+++ b/accessible/public/nsIAccessibilityService.idl
@@ -39,27 +39,25 @@
 #include "nsISupports.idl"
 #include "nsIAccessibleRetrieval.idl"
 
 interface nsIDocument;
 interface nsIFrame;
 interface nsObjectFrame;
 interface nsIContent;
 
-[uuid(84a3ab70-8f7e-4610-9cd8-bd69308b76c5)]
+[uuid(4df7499d-d96e-48f8-a936-8a22ec0d4915)]
 interface nsIAccessibilityService : nsIAccessibleRetrieval
 {
   nsIAccessible createOuterDocAccessible(in nsIDOMNode aNode);
-  nsIAccessible createRootAccessible(in nsIPresShell aShell, in nsIDocument aDocument);
 
   nsIAccessible createHTML4ButtonAccessible(in nsIFrame aFrame);
   nsIAccessible createHyperTextAccessible(in nsIFrame aFrame);
   nsIAccessible createHTMLBRAccessible(in nsIFrame aFrame);
   nsIAccessible createHTMLButtonAccessible(in nsIFrame aFrame);
-  nsIAccessible createHTMLAccessibleByMarkup(in nsIFrame aFrame, in nsIWeakReference aWeakShell, in nsIDOMNode aDOMNode);
   nsIAccessible createHTMLLIAccessible(in nsIFrame aFrame, in nsIFrame aBulletFrame, in AString aBulletText);
   nsIAccessible createHTMLCheckboxAccessible(in nsIFrame aFrame);
   nsIAccessible createHTMLComboboxAccessible(in nsIDOMNode aNode, in nsIWeakReference aPresShell);
   nsIAccessible createHTMLGenericAccessible(in nsIFrame aFrame);
   nsIAccessible createHTMLGroupboxAccessible(in nsIFrame aFrame);
   nsIAccessible createHTMLHRAccessible(in nsIFrame aFrame);
   nsIAccessible createHTMLImageAccessible(in nsIFrame aFrame);
   nsIAccessible createHTMLLabelAccessible(in nsIFrame aFrame);
--- a/accessible/src/base/nsAccTreeWalker.cpp
+++ b/accessible/src/base/nsAccTreeWalker.cpp
@@ -34,16 +34,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 "nsAccTreeWalker.h"
 
+#include "nsAccessible.h"
 #include "nsAccessibilityService.h"
 
 ////////////////////////////////////////////////////////////////////////////////
 // WalkState
 ////////////////////////////////////////////////////////////////////////////////
 
 struct WalkState
 {
@@ -83,17 +84,17 @@ nsAccTreeWalker::~nsAccTreeWalker()
     PopState();
 
   MOZ_COUNT_DTOR(nsAccTreeWalker);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccTreeWalker: private
 
-already_AddRefed<nsIAccessible>
+already_AddRefed<nsAccessible>
 nsAccTreeWalker::GetNextChildInternal(PRBool aNoWalkUp)
 {
   if (!mState || !mState->content)
     return nsnull;
 
   if (!mState->childList)
     mState->childList = mState->content->GetChildren(mChildType);
 
@@ -103,20 +104,20 @@ 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<nsIAccessible> accessible;
     nsCOMPtr<nsIDOMNode> childDOMNode(do_QueryInterface(childNode));
-    GetAccService()->GetAccessible(childDOMNode, presShell, mWeakShell, nsnull,
-                                   &isHidden, getter_AddRefs(accessible));
+    nsRefPtr<nsAccessible> accessible =
+      GetAccService()->GetAccessible(childDOMNode, presShell, mWeakShell,
+                                     &isHidden);
 
     if (accessible)
       return accessible.forget();
 
     // Walk down into subtree to find accessibles.
     if (!isHidden) {
       if (!PushState(childNode))
         break;
--- a/accessible/src/base/nsAccTreeWalker.h
+++ b/accessible/src/base/nsAccTreeWalker.h
@@ -35,50 +35,51 @@
  * 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 _nsAccTreeWalker_H_
 #define _nsAccTreeWalker_H_
 
-#include "nsIAccessible.h"
+#include "nsAutoPtr.h"
 #include "nsIContent.h"
 #include "nsIWeakReference.h"
 
+class nsAccessible;
 struct WalkState;
 
 /**
  * This class is used to walk the DOM tree to create accessible tree.
  */
 class nsAccTreeWalker
 {
 public:
   nsAccTreeWalker(nsIWeakReference *aShell, nsIContent *aNode, 
                   PRBool aWalkAnonymousContent);
   virtual ~nsAccTreeWalker();
 
   /**
    * Return the next child accessible.
    */
-  already_AddRefed<nsIAccessible> GetNextChild()
+  already_AddRefed<nsAccessible> GetNextChild()
   {
     return GetNextChildInternal(PR_FALSE);
   }
 
 private:
 
   /**
    * Return the next child accessible.
    *
    * @param  aNoWalkUp  [in] specifies the walk direction, true means we
    *                     shouldn't go up through the tree if we failed find
    *                     accessible children.
    */
-  already_AddRefed<nsIAccessible>
+  already_AddRefed<nsAccessible>
     GetNextChildInternal(PRBool aNoWalkUp = PR_FALSE);
 
   /**
    * Create new state for the given node and push it on top of stack.
    *
    * @note State stack is used to navigate up/down the DOM subtree during
    *        accessible children search.
    */
--- a/accessible/src/base/nsAccUtils.cpp
+++ b/accessible/src/base/nsAccUtils.cpp
@@ -360,18 +360,17 @@ nsAccUtils::HasAccessibleChildren(nsIDOM
     return PR_FALSE;
 
   nsIFrame *frame = content->GetPrimaryFrame();
   if (!frame)
     return PR_FALSE;
 
   nsCOMPtr<nsIWeakReference> weakShell(do_GetWeakReference(presShell));
   nsAccTreeWalker walker(weakShell, content, PR_FALSE);
-
-  nsCOMPtr<nsIAccessible> accessible = walker.GetNextChild();
+  nsRefPtr<nsAccessible> accessible = walker.GetNextChild();
   return accessible ? PR_TRUE : PR_FALSE;
 }
 
 already_AddRefed<nsIAccessible>
 nsAccUtils::GetAncestorWithRole(nsIAccessible *aDescendant, PRUint32 aRole)
 {
   nsCOMPtr<nsIAccessible> parentAccessible = aDescendant, testRoleAccessible;
   while (NS_SUCCEEDED(parentAccessible->GetParent(getter_AddRefs(testRoleAccessible))) &&
--- a/accessible/src/base/nsAccessNode.cpp
+++ b/accessible/src/base/nsAccessNode.cpp
@@ -97,45 +97,45 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIAccessNode)
 NS_INTERFACE_MAP_END
  
 NS_IMPL_CYCLE_COLLECTING_ADDREF_AMBIGUOUS(nsAccessNode, nsIAccessNode)
 NS_IMPL_CYCLE_COLLECTING_RELEASE_FULL(nsAccessNode, nsIAccessNode,
                                       LastRelease())
 
 ////////////////////////////////////////////////////////////////////////////////
-// nsAccessible. Constructor
+// nsAccessNode construction/desctruction
 
 nsAccessNode::nsAccessNode(nsIDOMNode *aNode, nsIWeakReference* aShell): 
   mDOMNode(aNode), mWeakShell(aShell)
 {
 #ifdef DEBUG_A11Y
   mIsInitialized = PR_FALSE;
 #endif
 }
 
-//-----------------------------------------------------
-// destruction
-//-----------------------------------------------------
 nsAccessNode::~nsAccessNode()
 {
   NS_ASSERTION(!mWeakShell, "LastRelease was never called!?!");
 }
 
 void nsAccessNode::LastRelease()
 {
   // First cleanup if needed...
   if (mWeakShell) {
     Shutdown();
     NS_ASSERTION(!mWeakShell, "A Shutdown() impl forgot to call its parent's Shutdown?");
   }
   // ... then die.
   NS_DELETEXPCOM(this);
 }
 
+////////////////////////////////////////////////////////////////////////////////
+// nsAccessNode public
+
 nsresult
 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
@@ -163,17 +163,19 @@ nsAccessNode::Init()
     }
   }
 
   void* uniqueID;
   GetUniqueID(&uniqueID);
   nsRefPtr<nsDocAccessible> docAcc =
     nsAccUtils::QueryAccessibleDocument(docAccessible);
   NS_ASSERTION(docAcc, "No nsDocAccessible for document accessible!");
-  docAcc->CacheAccessNode(uniqueID, this);
+
+  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>
     nsCOMPtr<nsIAccessible> parentAccessible;
@@ -196,22 +198,24 @@ nsresult
 nsAccessNode::Shutdown()
 {
   mDOMNode = nsnull;
   mWeakShell = nsnull;
 
   return NS_OK;
 }
 
+// nsIAccessNode
 NS_IMETHODIMP nsAccessNode::GetUniqueID(void **aUniqueID)
 {
   *aUniqueID = static_cast<void*>(mDOMNode);
   return NS_OK;
 }
 
+// nsIAccessNode
 NS_IMETHODIMP nsAccessNode::GetOwnerWindow(void **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);
 }
@@ -264,16 +268,17 @@ void nsAccessNode::InitXPAccessibility()
   if (prefBranch) {
     prefBranch->GetBoolPref("accessibility.disablecache", &gIsCacheDisabled);
     prefBranch->GetBoolPref("browser.formfill.enable", &gIsFormFillEnabled);
   }
 
   NotifyA11yInitOrShutdown(PR_TRUE);
 }
 
+// nsAccessNode protected static
 void nsAccessNode::NotifyA11yInitOrShutdown(PRBool aIsInit)
 {
   nsCOMPtr<nsIObserverService> obsService =
     do_GetService("@mozilla.org/observer-service;1");
   NS_ASSERTION(obsService, "No observer service to notify of a11y init/shutdown");
   if (obsService) {
     static const PRUnichar kInitIndicator[] = { '1', 0 };
     static const PRUnichar kShutdownIndicator[] = { '0', 0 }; 
@@ -326,25 +331,27 @@ already_AddRefed<nsIPresShell> nsAccessN
       // 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();
 }
 
+// nsAccessNode protected
 already_AddRefed<nsIAccessibleDocument> nsAccessNode::GetDocAccessible()
 {
   return GetDocAccessibleFor(mWeakShell); // Addref'd
 }
 
 already_AddRefed<nsRootAccessible> nsAccessNode::GetRootAccessible()
 {
   nsCOMPtr<nsIDocShellTreeItem> docShellTreeItem =
@@ -374,16 +381,38 @@ already_AddRefed<nsRootAccessible> nsAcc
 
 nsIFrame*
 nsAccessNode::GetFrame()
 {
   nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
   return content ? content->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 =
+    nsAccUtils::QueryObject<nsDocAccessible>(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
@@ -454,16 +483,17 @@ 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);
 
@@ -605,17 +635,18 @@ nsAccessNode::GetComputedStyleCSSValue(c
 
   nsCOMPtr<nsIDOMCSSValue> cssValue;
   styleDecl->GetPropertyCSSValue(aPropertyName, getter_AddRefs(cssValue));
   NS_ENSURE_TRUE(cssValue, NS_ERROR_FAILURE);
 
   return CallQueryInterface(cssValue, aCSSValue);
 }
 
-/***************** Hashtable of nsIAccessNode's *****************/
+////////////////////////////////////////////////////////////////////////////////
+// nsAccessNode public static
 
 already_AddRefed<nsIAccessibleDocument>
 nsAccessNode::GetDocAccessibleFor(nsIDocument *aDocument)
 {
   if (!aDocument) {
     return nsnull;
   }
 
@@ -720,16 +751,17 @@ already_AddRefed<nsIDOMNode> nsAccessNod
     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
@@ -759,9 +791,8 @@ nsAccessNode::GetLanguage(nsAString& aLa
     nsIDocument *doc = content->GetOwnerDoc();
     if (doc) {
       doc->GetHeaderData(nsAccessibilityAtoms::headerContentLanguage, aLanguage);
     }
   }
  
   return NS_OK;
 }
-
--- a/accessible/src/base/nsAccessNode.h
+++ b/accessible/src/base/nsAccessNode.h
@@ -170,16 +170,23 @@ class nsAccessNode: public nsIAccessNode
   already_AddRefed<nsIPresShell> GetPresShell();
 
   /**
    * Return true if the accessible still has presentation shell. Light-weight
    * version of IsDefunct() method.
    */
   PRBool HasWeakShell() const { return !!mWeakShell; }
 
+#ifdef DEBUG
+  /**
+   * Return true if the access node is cached.
+   */
+  PRBool IsInCache();
+#endif
+
 protected:
     nsresult MakeAccessNode(nsIDOMNode *aNode, nsIAccessNode **aAccessNode);
 
     nsPresContext* GetPresContext();
     already_AddRefed<nsIAccessibleDocument> GetDocAccessible();
     void LastRelease();
 
     nsCOMPtr<nsIDOMNode> mDOMNode;
--- a/accessible/src/base/nsAccessibilityService.cpp
+++ b/accessible/src/base/nsAccessibilityService.cpp
@@ -103,23 +103,23 @@
 #include "nsHTMLWin32ObjectAccessible.h"
 #endif
 
 #ifndef DISABLE_XFORMS_HOOKS
 #include "nsXFormsFormControlsAccessible.h"
 #include "nsXFormsWidgetsAccessible.h"
 #endif
 
+////////////////////////////////////////////////////////////////////////////////
+// nsAccessibilityService
+////////////////////////////////////////////////////////////////////////////////
+
 nsAccessibilityService *nsAccessibilityService::gAccessibilityService = nsnull;
 PRBool nsAccessibilityService::gIsShutdown = PR_TRUE;
 
-/**
-  * nsAccessibilityService
-  */
-
 nsAccessibilityService::nsAccessibilityService()
 {
   // Add observers.
   nsCOMPtr<nsIObserverService> observerService = 
     do_GetService("@mozilla.org/observer-service;1");
   if (!observerService)
     return;
 
@@ -138,16 +138,18 @@ nsAccessibilityService::~nsAccessibility
 {
   NS_ASSERTION(gIsShutdown, "Accessibility wasn't shutdown!");
   gAccessibilityService = nsnull;
 }
 
 NS_IMPL_THREADSAFE_ISUPPORTS5(nsAccessibilityService, nsIAccessibilityService, nsIAccessibleRetrieval,
                               nsIObserver, nsIWebProgressListener, nsISupportsWeakReference)
 
+
+////////////////////////////////////////////////////////////////////////////////
 // nsIObserver
 
 NS_IMETHODIMP
 nsAccessibilityService::Observe(nsISupports *aSubject, const char *aTopic,
                          const PRUnichar *aData)
 {
   if (!nsCRT::strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID)) {
 
@@ -170,17 +172,19 @@ nsAccessibilityService::Observe(nsISuppo
 
     gIsShutdown = PR_TRUE;
     nsAccessNodeWrap::ShutdownAccessibility();
   }
 
   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;
@@ -203,16 +207,17 @@ NS_IMETHODIMP nsAccessibilityService::On
   } 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;
@@ -242,16 +247,17 @@ nsAccessibilityService::ProcessDocLoadEv
   GetAccessibleFor(docNode, getter_AddRefs(accessible));
   nsRefPtr<nsDocAccessible> docAcc =
     nsAccUtils::QueryAccessibleDocument(accessible);
   NS_ENSURE_TRUE(docAcc,);
 
   docAcc->FireDocLoadEvents(aEventType);
 }
 
+// nsIAccessibilityService
 NS_IMETHODIMP
 nsAccessibilityService::NotifyOfAnchorJumpTo(nsIContent *aTarget)
 {
   nsCOMPtr<nsIDOMNode> targetNode(do_QueryInterface(aTarget));
 
   nsCOMPtr<nsIAccessible> targetAcc;
   GetAccessibleFor(targetNode, getter_AddRefs(targetAcc));
 
@@ -271,16 +277,17 @@ nsAccessibilityService::NotifyOfAnchorJu
 
   if (targetAcc)
     nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_SCROLLING_START,
                             targetAcc);
 
   return NS_OK;
 }
 
+// nsIAccessibilityService
 NS_IMETHODIMP
 nsAccessibilityService::FireAccessibleEvent(PRUint32 aEvent,
                                             nsIAccessible *aTarget)
 {
   nsEventShell::FireEvent(aEvent, aTarget);
   return NS_OK;
 }
 
@@ -313,16 +320,17 @@ NS_IMETHODIMP nsAccessibilityService::On
 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();
@@ -342,16 +350,17 @@ nsAccessibilityService::GetInfo(nsIFrame
   // 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;
@@ -364,19 +373,18 @@ nsAccessibilityService::GetShellFromNode
   nsCOMPtr<nsIWeakReference> weakRef(do_GetWeakReference(shell));
   
   *aWeakShell = weakRef;
   NS_IF_ADDREF(*aWeakShell);
 
   return NS_OK;
 }
 
-/**
-  * nsIAccessibilityService methods:
-  */
+////////////////////////////////////////////////////////////////////////////////
+// nsIAccessibilityService
 
 NS_IMETHODIMP 
 nsAccessibilityService::CreateOuterDocAccessible(nsIDOMNode* aDOMNode, 
                                                  nsIAccessible **aOuterDocAccessible)
 {
   NS_ENSURE_ARG_POINTER(aDOMNode);
   
   *aOuterDocAccessible = nsnull;
@@ -389,79 +397,72 @@ nsAccessibilityService::CreateOuterDocAc
     new nsOuterDocAccessible(aDOMNode, outerWeakShell);
   NS_ENSURE_TRUE(outerDocAccessible, NS_ERROR_FAILURE);
 
   NS_ADDREF(*aOuterDocAccessible = outerDocAccessible);
 
   return NS_OK;
 }
 
-NS_IMETHODIMP 
-nsAccessibilityService::CreateRootAccessible(nsIPresShell *aShell, 
-                                             nsIDocument* aDocument, 
-                                             nsIAccessible **aRootAcc)
+// nsAccessibilityService private
+already_AddRefed<nsAccessible>
+nsAccessibilityService::CreateDocOrRootAccessible(nsIPresShell *aShell,
+                                                  nsIDocument* aDocument)
 {
-  *aRootAcc = nsnull;
-
   nsCOMPtr<nsIDOMNode> rootNode(do_QueryInterface(aDocument));
-  NS_ENSURE_TRUE(rootNode, NS_ERROR_FAILURE);
+  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, NS_ERROR_FAILURE);
+  NS_ENSURE_TRUE(docShell, nsnull);
+
   nsCOMPtr<nsIContentViewer> contentViewer;
   docShell->GetContentViewer(getter_AddRefs(contentViewer));
-  NS_ENSURE_TRUE(contentViewer, NS_ERROR_FAILURE); // Doc was already shut down
+  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_STATE(uri);
+    NS_ENSURE_TRUE(uri, nsnull);
+
     nsCAutoString url;
     uri->GetSpec(url);
     if (url.EqualsLiteral("about:blank")) {
-      return NS_OK;  // No load events for a busy about:blank -- they are often temporary
+      // No load events for a busy about:blank -- they are often temporary.
+      return nsnull;
     }
   }
 
   nsCOMPtr<nsIDocShellTreeItem> docShellTreeItem =
     do_QueryInterface(container);
-  NS_ENSURE_TRUE(docShellTreeItem, NS_ERROR_FAILURE);
+  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
-    *aRootAcc = new nsDocAccessibleWrap(rootNode, weakShell);
+    accessible = new nsDocAccessibleWrap(rootNode, weakShell);
   }
   else {
-    *aRootAcc = new nsRootAccessibleWrap(rootNode, weakShell);
+    accessible = new nsRootAccessibleWrap(rootNode, weakShell);
   }
-  if (!*aRootAcc)
-    return NS_ERROR_OUT_OF_MEMORY;
 
-  nsRefPtr<nsAccessible> rootAcc = nsAccUtils::QueryAccessible(*aRootAcc);
-  rootAcc->Init();
-
-  nsRoleMapEntry *roleMapEntry = nsAccUtils::GetRoleMapEntry(rootNode);
-  rootAcc->SetRoleMapEntry(roleMapEntry);
-
-  NS_ADDREF(*aRootAcc);
-
-  return NS_OK;
+  return accessible.forget();
 }
 
  /**
    * HTML widget creation
    */
 NS_IMETHODIMP
 nsAccessibilityService::CreateHTML4ButtonAccessible(nsIFrame *aFrame, nsIAccessible **_retval)
 {
@@ -491,83 +492,85 @@ nsAccessibilityService::CreateHTMLButton
   *_retval = new nsHTMLButtonAccessible(node, weakShell);
   if (! *_retval) 
     return NS_ERROR_OUT_OF_MEMORY;
 
   NS_ADDREF(*_retval);
   return NS_OK;
 }
 
-nsresult
+// nsAccessibilityService private
+already_AddRefed<nsAccessible>
 nsAccessibilityService::CreateHTMLAccessibleByMarkup(nsIFrame *aFrame,
                                                      nsIWeakReference *aWeakShell,
-                                                     nsIDOMNode *aNode,
-                                                     nsIAccessible **aAccessible)
+                                                     nsIDOMNode *aNode)
 {
   // This method assumes we're in an HTML namespace.
-  *aAccessible = nsnull;
+  nsRefPtr<nsAccessible> accessible;
+
   nsCOMPtr<nsIContent> content(do_QueryInterface(aNode));
   nsIAtom *tag = content->Tag();
   if (tag == nsAccessibilityAtoms::legend) {
-    *aAccessible = new nsHTMLLegendAccessible(aNode, aWeakShell);
+    accessible = new nsHTMLLegendAccessible(aNode, aWeakShell);
   }
   else if (tag == nsAccessibilityAtoms::option) {
-    *aAccessible = new nsHTMLSelectOptionAccessible(aNode, aWeakShell);
+    accessible = new nsHTMLSelectOptionAccessible(aNode, aWeakShell);
   }
   else if (tag == nsAccessibilityAtoms::optgroup) {
-    *aAccessible = new nsHTMLSelectOptGroupAccessible(aNode, aWeakShell);
+    accessible = new nsHTMLSelectOptGroupAccessible(aNode, aWeakShell);
   }
   else if (tag == nsAccessibilityAtoms::ul || tag == nsAccessibilityAtoms::ol ||
            tag == nsAccessibilityAtoms::dl) {
-    *aAccessible = new nsHTMLListAccessible(aNode, aWeakShell);
+    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) {
-      return CreateHyperTextAccessible(aFrame, aAccessible);
+
+      accessible = new nsHyperTextAccessibleWrap(aNode, aWeakShell);
+    } else {
+      accessible = new nsHTMLLinkAccessible(aNode, aWeakShell);
     }
-
-    *aAccessible = 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
-    *aAccessible = new nsHTMLLIAccessible(aNode, aWeakShell, EmptyString());
+    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) {
-    return CreateHyperTextAccessible(aFrame, aAccessible);
+
+    accessible = new nsHyperTextAccessibleWrap(aNode, aWeakShell);
   }
   else if (tag == nsAccessibilityAtoms::tr) {
-    *aAccessible = new nsEnumRoleAccessible(aNode, aWeakShell,
+    accessible = new nsEnumRoleAccessible(aNode, aWeakShell,
                                             nsIAccessibleRole::ROLE_ROW);
   }
   else if (nsCoreUtils::IsHTMLTableHeader(content)) {
-    *aAccessible = new nsHTMLTableHeaderCellAccessibleWrap(aNode, aWeakShell);
+    accessible = new nsHTMLTableHeaderCellAccessibleWrap(aNode, aWeakShell);
   }
 
-  NS_IF_ADDREF(*aAccessible);
-  return NS_OK;
+  return accessible.forget();
 }
 
 NS_IMETHODIMP
 nsAccessibilityService::CreateHTMLLIAccessible(nsIFrame *aFrame, 
                                                nsIFrame *aBulletFrame,
                                                const nsAString& aBulletText,
                                                nsIAccessible **_retval)
 {
@@ -933,31 +936,35 @@ nsAccessibilityService::CreateHTMLCaptio
   *_retval = new nsHTMLCaptionAccessible(node, weakShell);
   if (! *_retval) 
     return NS_ERROR_OUT_OF_MEMORY;
 
   NS_ADDREF(*_retval);
   return NS_OK;
 }
 
+// nsAccessibilityService public
 nsAccessNode*
 nsAccessibilityService::GetCachedAccessNode(nsIDOMNode *aNode, 
                                             nsIWeakReference *aWeakShell)
 {
   nsCOMPtr<nsIAccessibleDocument> accessibleDoc =
     nsAccessNode::GetDocAccessibleFor(aWeakShell);
 
   if (!accessibleDoc)
     return nsnull;
 
   nsRefPtr<nsDocAccessible> docAccessible =
     nsAccUtils::QueryObject<nsDocAccessible>(accessibleDoc);
   return docAccessible->GetCachedAccessNode(static_cast<void*>(aNode));
 }
 
+////////////////////////////////////////////////////////////////////////////////
+// nsIAccessibleRetrieval
+
 NS_IMETHODIMP
 nsAccessibilityService::GetStringRole(PRUint32 aRole, nsAString& aString)
 {
   if ( aRole >= NS_ARRAY_LENGTH(kRoleNames)) {
     aString.AssignLiteral("unknown");
     return NS_OK;
   }
 
@@ -1121,31 +1128,39 @@ NS_IMETHODIMP
 nsAccessibilityService::GetAccessibleFor(nsIDOMNode *aNode,
                                          nsIAccessible **aAccessible)
 {
   NS_ENSURE_ARG_POINTER(aAccessible);
   *aAccessible = nsnull;
 
   NS_ENSURE_ARG(aNode);
 
-  // We use presentation shell #0 because we assume that is presentation of
-  // given node window.
   nsCOMPtr<nsIContent> content(do_QueryInterface(aNode));
   nsCOMPtr<nsIDocument> doc;
   if (content) {
     doc = content->GetDocument();
   }
   else {// Could be document node
     doc = do_QueryInterface(aNode);
   }
   if (!doc)
     return NS_ERROR_FAILURE;
 
+  // We use presentation shell #0 because we assume that is presentation of
+  // given node window.
   nsIPresShell *presShell = doc->GetPrimaryShell();
-  return GetAccessibleInShell(aNode, presShell, aAccessible);
+
+  nsCOMPtr<nsIWeakReference> weakShell(do_GetWeakReference(presShell));
+  nsRefPtr<nsAccessible> accessible =
+    GetAccessible(aNode, presShell, weakShell);
+
+  if (accessible)
+    CallQueryInterface(accessible.get(), aAccessible);
+  
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 nsAccessibilityService::GetAttachedAccessibleFor(nsIDOMNode *aNode,
                                                  nsIAccessible **aAccessible)
 {
   NS_ENSURE_ARG(aNode);
   NS_ENSURE_ARG_POINTER(aAccessible);
@@ -1157,66 +1172,84 @@ nsAccessibilityService::GetAttachedAcces
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (relevantNode != aNode)
     return NS_OK;
 
   return GetAccessibleFor(aNode, aAccessible);
 }
 
-NS_IMETHODIMP nsAccessibilityService::GetAccessibleInShell(nsIDOMNode *aNode, 
-                                                           nsIPresShell *aPresShell,
-                                                           nsIAccessible **aAccessible) 
+NS_IMETHODIMP
+nsAccessibilityService::GetAccessibleInShell(nsIDOMNode *aNode, 
+                                             nsIPresShell *aPresShell,
+                                             nsIAccessible **aAccessible) 
 {
   NS_ENSURE_ARG_POINTER(aAccessible);
   *aAccessible = nsnull;
 
   NS_ENSURE_ARG(aNode);
   NS_ENSURE_ARG(aPresShell);
 
   nsCOMPtr<nsIWeakReference> weakShell(do_GetWeakReference(aPresShell));
-  PRBool isHiddenUnused = false;
-  return GetAccessible(aNode, aPresShell, weakShell, 
-                       nsnull, &isHiddenUnused, aAccessible);
+  nsRefPtr<nsAccessible> accessible =
+    GetAccessible(aNode, aPresShell, weakShell);
+
+  if (accessible)
+    CallQueryInterface(accessible.get(), aAccessible);
+  
+  return NS_OK;
 }
 
+////////////////////////////////////////////////////////////////////////////////
+// nsAccessibilityService public
+
 nsresult
 nsAccessibilityService::GetAccessibleInWeakShell(nsIDOMNode *aNode, 
                                                  nsIWeakReference *aWeakShell,
                                                  nsIAccessible **aAccessible) 
 {
   NS_ENSURE_ARG_POINTER(aAccessible);
   *aAccessible = nsnull;
 
   NS_ENSURE_ARG(aNode);
   NS_ENSURE_ARG(aWeakShell);
 
   nsCOMPtr<nsIPresShell> presShell(do_QueryReferent(aWeakShell));
-  PRBool isHiddenUnused = false;
-  return GetAccessible(aNode, presShell, aWeakShell, 
-                       nsnull, &isHiddenUnused, aAccessible);
+  nsRefPtr<nsAccessible> accessible =
+    GetAccessible(aNode, presShell, aWeakShell);
+
+  if (accessible)
+    CallQueryInterface(accessible.get(), aAccessible);
+
+  return NS_OK;
 }
 
-nsresult nsAccessibilityService::InitAccessible(nsIAccessible *aAccessibleIn,
-                                                nsIAccessible **aAccessibleOut,
-                                                nsRoleMapEntry *aRoleMapEntry)
+////////////////////////////////////////////////////////////////////////////////
+// nsAccessibilityService private
+
+PRBool
+nsAccessibilityService::InitAccessible(nsAccessible *aAccessible,
+                                       nsRoleMapEntry *aRoleMapEntry)
 {
-  if (!aAccessibleIn) {
-    return NS_ERROR_FAILURE; // No accessible to init
-  }
-  NS_ASSERTION(aAccessibleOut && !*aAccessibleOut, "Out param should already be cleared out");
+  if (!aAccessible)
+    return PR_FALSE;
 
-  nsRefPtr<nsAccessible> acc = nsAccUtils::QueryAccessible(aAccessibleIn);
-  nsresult rv = acc->Init(); // Add to cache, etc.
-  NS_ENSURE_SUCCESS(rv, rv);
+  nsresult rv = aAccessible->Init(); // Add to cache, etc.
+  if (NS_FAILED(rv)) {
+    NS_ERROR("Failed to initialize an accessible!");
 
-  acc->SetRoleMapEntry(aRoleMapEntry);
-  NS_ADDREF(*aAccessibleOut = aAccessibleIn);
+    aAccessible->Shutdown();
+    return PR_FALSE;
+  }
 
-  return NS_OK;
+  NS_ASSERTION(aAccessible->IsInCache(),
+               "Initialized accessible not in the cache!");
+
+  aAccessible->SetRoleMapEntry(aRoleMapEntry);
+  return PR_TRUE;
 }
 
 static PRBool HasRelatedContent(nsIContent *aContent)
 {
   nsAutoString id;
   if (!aContent || !nsCoreUtils::GetID(aContent, id) || id.IsEmpty()) {
     return PR_FALSE;
   }
@@ -1237,40 +1270,30 @@ static PRBool HasRelatedContent(nsIConte
         // ancestor has activedescendant property, this content could be active
       return PR_TRUE;
     }
   }
 
   return PR_FALSE;
 }
 
-nsresult
+// nsAccessibilityService public
+already_AddRefed<nsAccessible>
 nsAccessibilityService::GetAccessible(nsIDOMNode *aNode,
                                       nsIPresShell *aPresShell,
                                       nsIWeakReference *aWeakShell,
-                                      nsIFrame *aFrameHint,
-                                      PRBool *aIsHidden,
-                                      nsIAccessible **aAccessible)
+                                      PRBool *aIsHidden)
 {
-  NS_ENSURE_ARG_POINTER(aAccessible);
-  *aAccessible = nsnull;
-
-  if (!aPresShell || !aWeakShell || gIsShutdown) {
-    return NS_ERROR_FAILURE;
-  }
+  if (!aPresShell || !aWeakShell || gIsShutdown)
+    return nsnull;
 
   NS_ASSERTION(aNode, "GetAccessible() called with no node.");
 
-  *aIsHidden = PR_FALSE;
-
-  // Frames can be deallocated when we flush layout, or when we call into code
-  // that can flush layout, either directly, or via DOM manipulation, or some
-  // CSS styles like :hover. We use the weak frame checks to avoid calling
-  // methods on a dead frame pointer.
-  nsWeakFrame weakFrame(aFrameHint);
+  if (aIsHidden)
+    *aIsHidden = PR_FALSE;
 
 #ifdef DEBUG_A11Y
   // Please leave this in for now, it's a convenient debugging method
   nsAutoString name;
   aNode->GetLocalName(name);
   if (name.LowerCaseEqualsLiteral("h1")) 
     printf("## aaronl debugging tag name\n");
 
@@ -1284,167 +1307,165 @@ nsAccessibilityService::GetAccessible(ns
 #endif
 
   // Check to see if we already have an accessible for this node in the cache.
   nsAccessNode* cachedAccessNode = GetCachedAccessNode(aNode, aWeakShell);
   if (cachedAccessNode) {
     // XXX: the cache might contain the access node for the DOM node that is not
     // accessible because of wrong cache update. In this case try to create new
     // accessible.
-    CallQueryInterface(cachedAccessNode, aAccessible);
-    NS_ASSERTION(*aAccessible, "Bad cache update!");
-    if (*aAccessible)
-      return NS_OK;
+    nsRefPtr<nsAccessible> cachedAccessible =
+      nsAccUtils::QueryObject<nsAccessible>(cachedAccessNode);
+
+    if (cachedAccessible)
+      return cachedAccessible.forget();
   }
 
-  nsCOMPtr<nsIAccessible> newAcc;
-  nsCOMPtr<nsIContent> content(do_QueryInterface(aNode));
+  // No cache entry, so we must create the accessible.
+  nsRefPtr<nsAccessible> newAcc;
 
-  // No cache entry, so we must create the accessible
-  // Check to see if hidden first
-  nsCOMPtr<nsIDocument> nodeIsDoc;
+  nsCOMPtr<nsIContent> content(do_QueryInterface(aNode));
   if (!content) {
     // This happens when we're on the document node, which will not QI to an
     // nsIContent.
-    nodeIsDoc = do_QueryInterface(aNode);
-    NS_ENSURE_TRUE(nodeIsDoc, NS_ERROR_FAILURE); // No content, and not doc node
+    nsCOMPtr<nsIDocument> nodeIsDoc = do_QueryInterface(aNode);
+    if (!nodeIsDoc) // No content, and not doc node.
+      return nsnull;
 
 #ifdef DEBUG
     // XXX: remove me if you don't see an assertion.
     nsCOMPtr<nsIAccessibleDocument> accessibleDoc =
       nsAccessNode::GetDocAccessibleFor(nodeIsDoc);
     NS_ASSERTION(!accessibleDoc,
                  "Trying to create already cached accessible document!");
 #endif
 
-    CreateRootAccessible(aPresShell, nodeIsDoc, getter_AddRefs(newAcc)); // Does Init() for us
+    newAcc = CreateDocOrRootAccessible(aPresShell, nodeIsDoc);
+    if (InitAccessible(newAcc, nsAccUtils::GetRoleMapEntry(aNode)))
+      return newAcc.forget();
+    return nsnull;
+  }
 
-    NS_IF_ADDREF(*aAccessible = newAcc);
-    return NS_OK;
+  // We have a content node.
+  if (!content->IsInDoc()) {
+    NS_ERROR("Creating accessible for node with no document");
+    return nsnull;
   }
 
-  NS_ASSERTION(content->GetDocument(), "Creating accessible for node with no document");
-  if (!content->GetDocument()) {
-    return NS_ERROR_FAILURE;
+  if (content->GetOwnerDoc() != aPresShell->GetDocument()) {
+    NS_ERROR("Creating accessible for wrong pres shell");
+    return nsnull;
   }
-  NS_ASSERTION(content->GetDocument() == aPresShell->GetDocument(), "Creating accessible for wrong pres shell");
-  if (content->GetDocument() != aPresShell->GetDocument()) {
-    return NS_ERROR_FAILURE;
+
+  // Frames can be deallocated when we flush layout, or when we call into code
+  // that can flush layout, either directly, or via DOM manipulation, or some
+  // CSS styles like :hover. We use the weak frame checks to avoid calling
+  // methods on a dead frame pointer.
+  nsWeakFrame weakFrame = content->GetPrimaryFrame();
+
+  // Check frame to see if it is hidden.
+  if (!weakFrame.GetFrame() ||
+      !weakFrame.GetFrame()->GetStyleVisibility()->IsVisible()) {
+    if (aIsHidden)
+      *aIsHidden = PR_TRUE;
+
+    return nsnull;
   }
 
-  // We have a content node
-#ifdef DEBUG_A11Y
-  static int frameHintFailed, frameHintTried, frameHintNonexistant, frameHintFailedForText;
-  ++frameHintTried;
-#endif
+  if (weakFrame.GetFrame()->GetContent() != content) {
+    // Not the main content for this frame!
+    // For example, this happens because <area> elements return the
+    // image frame as their primary frame. The main content for the 
+    // image frame is the image content.
 
-  if (!weakFrame.GetFrame() || content != weakFrame.GetFrame()->GetContent()) {
-    // Frame hint not correct, get true frame, we try to optimize away from this
-    weakFrame = content->GetPrimaryFrame();
-    if (weakFrame.GetFrame()) {
-#ifdef DEBUG_A11Y_FRAME_OPTIMIZATION
-      // Frame hint debugging
-      ++frameHintFailed;
-      if (content->IsNodeOfType(nsINode::eTEXT)) {
-        ++frameHintFailedForText;
-      }
-      frameHintNonexistant += !aFrameHint;
-      printf("Frame hint failures: %d / %d . Text fails = %d. No hint fails = %d \n", frameHintFailed, frameHintTried, frameHintFailedForText, frameHintNonexistant);
-      if (frameHintTried >= 354) {
-        printf("* "); // Aaron's break point
-      }
-#endif
-      if (weakFrame.GetFrame()->GetContent() != content) {
-        // Not the main content for this frame!
-        // For example, this happens because <area> elements return the
-        // image frame as their primary frame. The main content for the 
-        // image frame is the image content.
-
-        // Check if frame is an image frame, and content is <area>
-        nsIImageFrame *imageFrame = do_QueryFrame(weakFrame.GetFrame());
-        nsCOMPtr<nsIDOMHTMLAreaElement> areaElmt = do_QueryInterface(content);
-        if (imageFrame && areaElmt) {
-          nsCOMPtr<nsIAccessible> imageAcc;
-          CreateHTMLImageAccessible(weakFrame.GetFrame(), getter_AddRefs(imageAcc));
-          if (imageAcc) {
-            // cache children
-            PRInt32 childCount;
-            imageAcc->GetChildCount(&childCount);
-            // area accessible should be in cache now
-            nsAccessNode* cachedAreaAcc = GetCachedAccessNode(aNode, aWeakShell);
-            if (cachedAreaAcc)
-              CallQueryInterface(cachedAreaAcc, aAccessible);
-          }
+    // Check if frame is an image frame, and content is <area>.
+    nsIImageFrame *imageFrame = do_QueryFrame(weakFrame.GetFrame());
+    nsCOMPtr<nsIDOMHTMLAreaElement> areaElmt = do_QueryInterface(content);
+    if (imageFrame && areaElmt) {
+      // XXX: it's a hack we should try the cache before or if failed cache
+      // the image accessible.
+      nsCOMPtr<nsIAccessible> imageAcc;
+      CreateHTMLImageAccessible(weakFrame.GetFrame(), getter_AddRefs(imageAcc));
+      if (imageAcc) {
+        // Cache children.
+        PRInt32 childCount;
+        imageAcc->GetChildCount(&childCount);
+        // <area> accessible should be in cache now.
+        nsAccessNode* cachedAreaAcc = GetCachedAccessNode(aNode, aWeakShell);
+        if (cachedAreaAcc) {
+          newAcc = nsAccUtils::QueryObject<nsAccessible>(cachedAreaAcc);
+          return newAcc.forget();
         }
-
-        return NS_OK;
       }
     }
+
+    return nsnull;
   }
 
-  // Check frame to see if it is hidden
-  if (!weakFrame.GetFrame() ||
-      !weakFrame.GetFrame()->GetStyleVisibility()->IsVisible()) {
-    *aIsHidden = PR_TRUE;
-  }
-
-  if (*aIsHidden)
-    return NS_OK;
-
-  /**
-   * Attempt to create an accessible based on what we know
-   */
+  // Attempt to create an accessible based on what we know.
   if (content->IsNodeOfType(nsINode::eTEXT)) {
     // --- Create HTML for visible text frames ---
     nsIFrame* f = weakFrame.GetFrame();
     if (f && f->IsEmpty()) {
       nsAutoString renderedWhitespace;
       f->GetRenderedText(&renderedWhitespace, nsnull, nsnull, 0, 1);
       if (renderedWhitespace.IsEmpty()) {
         // Really empty -- nothing is rendered
-        *aIsHidden = PR_TRUE;
-        return NS_OK;
+        if (aIsHidden)
+          *aIsHidden = PR_TRUE;
+
+        return nsnull;
       }
     }
     if (weakFrame.IsAlive()) {
-      weakFrame.GetFrame()->GetAccessible(getter_AddRefs(newAcc));
+      nsCOMPtr<nsIAccessible> newAccessible;
+      weakFrame.GetFrame()->GetAccessible(getter_AddRefs(newAccessible));
+      if (newAccessible) {
+        newAcc = nsAccUtils::QueryObject<nsAccessible>(newAccessible);
+        if (InitAccessible(newAcc, nsnull))
+          return newAcc.forget();
+        return nsnull;
+      }
     }
 
-    return InitAccessible(newAcc, aAccessible, nsnull);
+    return nsnull;
   }
 
   PRBool isHTML = content->IsHTML();
   if (isHTML && content->Tag() == nsAccessibilityAtoms::map) {
     // Create hyper text accessible for HTML map if it is used to group links
     // (see http://www.w3.org/TR/WCAG10-HTML-TECHS/#group-bypass). If the HTML
     // map doesn't have 'name' attribute (or has empty name attribute) then we
     // suppose it is used for links grouping. Otherwise we think it is used in
     // conjuction with HTML image element and in this case we don't create any
     // accessible for it and don't walk into it. The accessibles for HTML area
     // (nsHTMLAreaAccessible) the map contains are attached as children of the
     // appropriate accessible for HTML image (nsHTMLImageAccessible).
     nsAutoString name;
     content->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::name, name);
     if (!name.IsEmpty()) {
-      *aIsHidden = PR_TRUE;
-      return NS_OK;
+      if (aIsHidden)
+        *aIsHidden = PR_TRUE;
+
+      return nsnull;
     }
-    
-    nsresult rv =
-      CreateHyperTextAccessible(weakFrame.GetFrame(), getter_AddRefs(newAcc));
-    NS_ENSURE_SUCCESS(rv, rv);
+
+    newAcc = new nsHyperTextAccessibleWrap(aNode, aWeakShell);
+    if (InitAccessible(newAcc, nsAccUtils::GetRoleMapEntry(aNode)))
+      return newAcc.forget();
+    return nsnull;
   }
 
   nsRoleMapEntry *roleMapEntry = nsAccUtils::GetRoleMapEntry(aNode);
   if (roleMapEntry && !nsCRT::strcmp(roleMapEntry->roleString, "presentation") &&
       !content->IsFocusable()) { // For presentation only
     // Only create accessible for role of "presentation" if it is focusable --
     // in that case we need an accessible in case it gets focused, we
     // don't want focus ever to be 'lost'
-    return NS_OK;
+    return nsnull;
   }
 
   if (weakFrame.IsAlive() && !newAcc && isHTML) {  // HTML accessibles
     PRBool tryTagNameOrFrame = PR_TRUE;
 
     nsIAtom *frameType = weakFrame.GetFrame()->GetType();
 
     PRBool partOfHTMLTable =
@@ -1461,18 +1482,18 @@ nsAccessibilityService::GetAccessible(ns
       while ((tableContent = tableContent->GetParent()) != nsnull) {
         nsIFrame *tableFrame = tableContent->GetPrimaryFrame();
         if (!tableFrame)
           continue;
 
         if (tableFrame->GetType() == nsAccessibilityAtoms::tableOuterFrame) {
           nsCOMPtr<nsIDOMNode> tableNode(do_QueryInterface(tableContent));
           nsCOMPtr<nsIAccessible> tableAccessible;
-          GetAccessibleInShell(tableNode, aPresShell,
-                               getter_AddRefs(tableAccessible));
+          GetAccessibleInWeakShell(tableNode, aWeakShell,
+                                   getter_AddRefs(tableAccessible));
 
           if (tableAccessible) {
             if (!roleMapEntry) {
               PRUint32 role = nsAccUtils::Role(tableAccessible);
               if (role != nsIAccessibleRole::ROLE_TABLE &&
                   role != nsIAccessibleRole::ROLE_TREE_TABLE) {
                 // No ARIA role and not in table: override role. For example,
                 // <table role="label"><td>content</td></table>
@@ -1491,17 +1512,17 @@ nsAccessibilityService::GetAccessible(ns
                        "No accessible for parent table and it didn't have role of presentation");
 #endif
 
           if (!roleMapEntry && !content->IsFocusable()) {
             // Table-related descendants of presentation table are also
             // presentation if they aren't focusable and have not explicit ARIA
             // role (don't create accessibles for them unless they need to fire
             // focus events).
-            return NS_OK;
+            return nsnull;
           }
 
           // otherwise create ARIA based accessible.
           tryTagNameOrFrame = PR_FALSE;
           break;
         }
 
         if (tableContent->Tag() == nsAccessibilityAtoms::table) {
@@ -1535,49 +1556,52 @@ nsAccessibilityService::GetAccessible(ns
     }
 
     if (!newAcc && tryTagNameOrFrame) {
       // Prefer to use markup (mostly tag name, perhaps attributes) to
       // decide if and what kind of accessible to create.
       // The method creates accessibles for table related content too therefore
       // we do not call it if accessibles for table related content are
       // prevented above.
-      nsresult rv =
-        CreateHTMLAccessibleByMarkup(weakFrame.GetFrame(), aWeakShell, aNode,
-                                     getter_AddRefs(newAcc));
-      NS_ENSURE_SUCCESS(rv, rv);
+      newAcc = CreateHTMLAccessibleByMarkup(weakFrame.GetFrame(), aWeakShell,
+                                            aNode);
 
       if (!newAcc) {
         // Do not create accessible object subtrees for non-rendered table
         // captions. This could not be done in
         // nsTableCaptionFrame::GetAccessible() because the descendants of
         // the table caption would still be created. By setting
         // *aIsHidden = PR_TRUE we ensure that no descendant accessibles are
         // created.
         nsIFrame* f = weakFrame.GetFrame();
         if (!f) {
           f = aPresShell->GetRealPrimaryFrameFor(content);
         }
         if (f->GetType() == nsAccessibilityAtoms::tableCaptionFrame &&
            f->GetRect().IsEmpty()) {
           // XXX This is not the ideal place for this code, but right now there
           // is no better place:
-          *aIsHidden = PR_TRUE;
-          return NS_OK;
+          if (aIsHidden)
+            *aIsHidden = PR_TRUE;
+
+          return nsnull;
         }
-        f->GetAccessible(getter_AddRefs(newAcc)); // Try using frame to do it
+
+        // Try using frame to do it.
+        nsCOMPtr<nsIAccessible> newAccessible;
+        f->GetAccessible(getter_AddRefs(newAccessible));
+        newAcc = nsAccUtils::QueryObject<nsAccessible>(newAccessible);
       }
     }
   }
 
   if (!newAcc) {
     // Elements may implement nsIAccessibleProvider via XBL. This allows them to
     // say what kind of accessible to create.
-    nsresult rv = GetAccessibleByType(aNode, getter_AddRefs(newAcc));
-    NS_ENSURE_SUCCESS(rv, rv);
+    newAcc = CreateAccessibleByType(aNode, aWeakShell);
   }
 
   if (!newAcc) {
     // Create generic accessibles for SVG and MathML nodes.
     if (content->GetNameSpaceID() == kNameSpaceID_SVG &&
         content->Tag() == nsAccessibilityAtoms::svg) {
       newAcc = new nsEnumRoleAccessible(aNode, aWeakShell,
                                         nsIAccessibleRole::ROLE_DIAGRAM);
@@ -1585,42 +1609,45 @@ nsAccessibilityService::GetAccessible(ns
     else if (content->GetNameSpaceID() == kNameSpaceID_MathML &&
              content->Tag() == nsAccessibilityAtoms::math) {
       newAcc = new nsEnumRoleAccessible(aNode, aWeakShell,
                                         nsIAccessibleRole::ROLE_EQUATION);
     }
   }
 
   if (!newAcc) {
-    GetAccessibleForDeckChildren(aNode, getter_AddRefs(newAcc));
+    newAcc = CreateAccessibleForDeckChild(weakFrame.GetFrame(), aNode,
+                                          aWeakShell);
   }
 
   // If no accessible, see if we need to create a generic accessible because
   // of some property that makes this object interesting
   // We don't do this for <body>, <html>, <window>, <dialog> etc. which 
   // correspond to the doc accessible and will be created in any case
   if (!newAcc && content->Tag() != nsAccessibilityAtoms::body && content->GetParent() && 
       ((weakFrame.GetFrame() && weakFrame.GetFrame()->IsFocusable()) ||
        (isHTML && nsCoreUtils::HasClickListener(content)) ||
        HasUniversalAriaProperty(content, aWeakShell) || roleMapEntry ||
        HasRelatedContent(content) || nsCoreUtils::IsXLink(content))) {
     // This content is focusable or has an interesting dynamic content accessibility property.
     // If it's interesting we need it in the accessibility hierarchy so that events or
     // other accessibles can point to it, or so that it can hold a state, etc.
     if (isHTML) {
       // Interesting HTML container which may have selectable text and/or embedded objects
-      CreateHyperTextAccessible(weakFrame.GetFrame(), getter_AddRefs(newAcc));
+      newAcc = new nsHyperTextAccessibleWrap(aNode, aWeakShell);
     }
     else {  // XUL, SVG, MathML etc.
       // Interesting generic non-HTML container
       newAcc = new nsAccessibleWrap(aNode, aWeakShell);
     }
   }
 
-  return InitAccessible(newAcc, aAccessible, roleMapEntry);
+  if (InitAccessible(newAcc, roleMapEntry))
+    return newAcc.forget();
+  return nsnull;
 }
 
 PRBool
 nsAccessibilityService::HasUniversalAriaProperty(nsIContent *aContent,
                                                  nsIWeakReference *aWeakShell)
 {
   // ARIA attributes that take token values (NMTOKEN, bool) are special cased.
   return nsAccUtils::HasDefinedARIAToken(aContent, nsAccessibilityAtoms::aria_atomic) ||
@@ -1636,16 +1663,17 @@ nsAccessibilityService::HasUniversalAria
          aContent->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_labelledby) ||
          nsAccUtils::HasDefinedARIAToken(aContent, nsAccessibilityAtoms::aria_live) ||
          nsAccUtils::HasDefinedARIAToken(aContent, nsAccessibilityAtoms::aria_owns) ||
          nsAccUtils::HasDefinedARIAToken(aContent, nsAccessibilityAtoms::aria_relevant) ||
          nsAccUtils::HasDefinedARIAToken(aContent, nsAccessibilityAtoms::aria_required) ||
          nsAccUtils::HasDefinedARIAToken(aContent, nsAccessibilityAtoms::aria_sort);
 }
 
+// nsIAccessibleRetrieval
 NS_IMETHODIMP
 nsAccessibilityService::GetRelevantContentNodeFor(nsIDOMNode *aNode,
                                                   nsIDOMNode **aRelevantNode)
 {
   // The method returns node that is relevant for attached accessible check.
   // Sometimes element that is XBL widget hasn't accessible children in
   // anonymous content. This method check whether given node can be accessible
   // by looking through all nested bindings that given node is anonymous for. If
@@ -1662,17 +1690,16 @@ nsAccessibilityService::GetRelevantConte
   // 3. xforms:input that is hosted in xul document contains xul:textbox
   // element. When given node is html:input or xul:textbox then we return
   // xforms:input element since xforms:input hasn't accessible anonymous
   // children.
 
   NS_ENSURE_ARG(aNode);
   NS_ENSURE_ARG_POINTER(aRelevantNode);
 
-  nsresult rv;
   nsCOMPtr<nsIContent> content(do_QueryInterface(aNode));
   if (content) {
     // Build stack of binding parents so we can walk it in reverse.
     nsIContent *bindingParent;
     nsCOMArray<nsIContent> bindingsStack;
 
     for (bindingParent = content->GetBindingParent(); bindingParent != nsnull &&
          bindingParent != bindingParent->GetBindingParent();
@@ -1682,282 +1709,282 @@ nsAccessibilityService::GetRelevantConte
 
     PRInt32 bindingsCount = bindingsStack.Count();
     for (PRInt32 index = bindingsCount - 1; index >= 0 ; index--) {
       bindingParent = bindingsStack[index];
       nsCOMPtr<nsIDOMNode> bindingNode(do_QueryInterface(bindingParent));
       if (bindingNode) {
         // Try to get an accessible by type since XBL widget can be accessible
         // only if it implements nsIAccessibleProvider interface.
-        nsCOMPtr<nsIAccessible> accessible;
-        rv = GetAccessibleByType(bindingNode, getter_AddRefs(accessible));
+        nsCOMPtr<nsIWeakReference> weakShell;
+        GetShellFromNode(bindingNode, getter_AddRefs(weakShell));
 
-        if (NS_SUCCEEDED(rv)) {
-          nsRefPtr<nsAccessible> acc(nsAccUtils::QueryAccessible(accessible));
-          if (acc) {
-            PRBool allowsAnonChildren = acc->GetAllowsAnonChildAccessibles();
-            if (!allowsAnonChildren) {
-              NS_ADDREF(*aRelevantNode = bindingNode);
-              return NS_OK;
-            }
+        // XXX: it's a hack we should try the cache before, otherwise to cache
+        // the accessible.
+        nsRefPtr<nsAccessible> accessible =
+          CreateAccessibleByType(bindingNode, weakShell);
+
+        if (accessible) {
+          if (!accessible->GetAllowsAnonChildAccessibles()) {
+            NS_ADDREF(*aRelevantNode = bindingNode);
+            return NS_OK;
           }
         }
       }
     }
   }
 
   NS_ADDREF(*aRelevantNode = aNode);
   return NS_OK;
 }
 
-nsresult nsAccessibilityService::GetAccessibleByType(nsIDOMNode *aNode,
-                                                     nsIAccessible **aAccessible)
+already_AddRefed<nsAccessible>
+nsAccessibilityService::CreateAccessibleByType(nsIDOMNode *aNode,
+                                               nsIWeakReference *aWeakShell)
 {
-  NS_ENSURE_ARG(aNode);
-  NS_ENSURE_ARG_POINTER(aAccessible);
-
-  *aAccessible = nsnull;
-
   nsCOMPtr<nsIAccessibleProvider> accessibleProvider(do_QueryInterface(aNode));
   if (!accessibleProvider)
-    return NS_OK;
+    return nsnull;
 
   PRInt32 type;
   nsresult rv = accessibleProvider->GetAccessibleType(&type);
-  NS_ENSURE_SUCCESS(rv, rv);
+  if (NS_FAILED(rv))
+    return nsnull;
 
-  if (type == nsIAccessibleProvider::OuterDoc)
-    return CreateOuterDocAccessible(aNode, aAccessible);
-
-  nsCOMPtr<nsIWeakReference> weakShell;
-  GetShellFromNode(aNode, getter_AddRefs(weakShell));
+  nsRefPtr<nsAccessible> accessible;
+  if (type == nsIAccessibleProvider::OuterDoc) {
+    accessible = new nsOuterDocAccessible(aNode, aWeakShell);
+    return accessible.forget();
+  }
 
   switch (type)
   {
 #ifdef MOZ_XUL
     case nsIAccessibleProvider::NoAccessible:
-      return NS_OK;
+      return nsnull;
+
     // XUL controls
     case nsIAccessibleProvider::XULAlert:
-      *aAccessible = new nsXULAlertAccessible(aNode, weakShell);
+      accessible = new nsXULAlertAccessible(aNode, aWeakShell);
       break;
     case nsIAccessibleProvider::XULButton:
-      *aAccessible = new nsXULButtonAccessible(aNode, weakShell);
+      accessible = new nsXULButtonAccessible(aNode, aWeakShell);
       break;
     case nsIAccessibleProvider::XULCheckbox:
-      *aAccessible = new nsXULCheckboxAccessible(aNode, weakShell);
+      accessible = new nsXULCheckboxAccessible(aNode, aWeakShell);
       break;
     case nsIAccessibleProvider::XULColorPicker:
-      *aAccessible = new nsXULColorPickerAccessible(aNode, weakShell);
+      accessible = new nsXULColorPickerAccessible(aNode, aWeakShell);
       break;
     case nsIAccessibleProvider::XULColorPickerTile:
-      *aAccessible = new nsXULColorPickerTileAccessible(aNode, weakShell);
+      accessible = new nsXULColorPickerTileAccessible(aNode, aWeakShell);
       break;
     case nsIAccessibleProvider::XULCombobox:
-      *aAccessible = new nsXULComboboxAccessible(aNode, weakShell);
+      accessible = new nsXULComboboxAccessible(aNode, aWeakShell);
       break;
     case nsIAccessibleProvider::XULDropmarker:
-      *aAccessible = new nsXULDropmarkerAccessible(aNode, weakShell);
+      accessible = new nsXULDropmarkerAccessible(aNode, aWeakShell);
       break;
     case nsIAccessibleProvider::XULGroupbox:
-      *aAccessible = new nsXULGroupboxAccessible(aNode, weakShell);
+      accessible = new nsXULGroupboxAccessible(aNode, aWeakShell);
       break;
     case nsIAccessibleProvider::XULImage:
     {
       // Don't include nameless images in accessible tree
       nsCOMPtr<nsIDOMElement> elt(do_QueryInterface(aNode));
       if (!elt)
-        return NS_ERROR_FAILURE;
+        return nsnull;
 
       PRBool hasTextEquivalent;
       // Prefer value over tooltiptext
       elt->HasAttribute(NS_LITERAL_STRING("tooltiptext"), &hasTextEquivalent);
       if (!hasTextEquivalent)
-        return NS_OK;
+        return nsnull;
 
-      *aAccessible = new nsHTMLImageAccessibleWrap(aNode, weakShell);
+      accessible = new nsHTMLImageAccessibleWrap(aNode, aWeakShell);
       break;
     }
     case nsIAccessibleProvider::XULLink:
-      *aAccessible = new nsXULLinkAccessible(aNode, weakShell);
+      accessible = new nsXULLinkAccessible(aNode, aWeakShell);
       break;
     case nsIAccessibleProvider::XULListbox:
-      *aAccessible = new nsXULListboxAccessibleWrap(aNode, weakShell);
+      accessible = new nsXULListboxAccessibleWrap(aNode, aWeakShell);
       break;
     case nsIAccessibleProvider::XULListCell:
-      *aAccessible = new nsXULListCellAccessibleWrap(aNode, weakShell);
+      accessible = new nsXULListCellAccessibleWrap(aNode, aWeakShell);
       break;
     case nsIAccessibleProvider::XULListHead:
-      *aAccessible = new nsXULColumnsAccessible(aNode, weakShell);
+      accessible = new nsXULColumnsAccessible(aNode, aWeakShell);
       break;
     case nsIAccessibleProvider::XULListHeader:
-      *aAccessible = new nsXULColumnItemAccessible(aNode, weakShell);
+      accessible = new nsXULColumnItemAccessible(aNode, aWeakShell);
       break;
     case nsIAccessibleProvider::XULListitem:
-      *aAccessible = new nsXULListitemAccessible(aNode, weakShell);
+      accessible = new nsXULListitemAccessible(aNode, aWeakShell);
       break;
     case nsIAccessibleProvider::XULMenubar:
-      *aAccessible = new nsXULMenubarAccessible(aNode, weakShell);
+      accessible = new nsXULMenubarAccessible(aNode, aWeakShell);
       break;
     case nsIAccessibleProvider::XULMenuitem:
-      *aAccessible = new nsXULMenuitemAccessibleWrap(aNode, weakShell);
+      accessible = new nsXULMenuitemAccessibleWrap(aNode, aWeakShell);
       break;
     case nsIAccessibleProvider::XULMenupopup:
     {
 #ifdef MOZ_ACCESSIBILITY_ATK
       // ATK considers this node to be redundant when within menubars, and it makes menu
       // navigation with assistive technologies more difficult
       // XXX In the future we will should this for consistency across the nsIAccessible
       // implementations on each platform for a consistent scripting environment, but
       // then strip out redundant accessibles in the nsAccessibleWrap class for each platform.
       nsCOMPtr<nsIContent> content = do_QueryInterface(aNode);
       if (content) {
         nsIContent *parent = content->GetParent();
         if (parent && parent->NodeInfo()->Equals(nsAccessibilityAtoms::menu, kNameSpaceID_XUL)) {
-          return NS_OK;
+          return nsnull;
         }
       }
 #endif
-      *aAccessible = new nsXULMenupopupAccessible(aNode, weakShell);
+      accessible = new nsXULMenupopupAccessible(aNode, aWeakShell);
       break;
     }
     case nsIAccessibleProvider::XULMenuSeparator:
-      *aAccessible = new nsXULMenuSeparatorAccessible(aNode, weakShell);
+      accessible = new nsXULMenuSeparatorAccessible(aNode, aWeakShell);
       break;
     case nsIAccessibleProvider::XULPane:
-      *aAccessible = new nsEnumRoleAccessible(aNode, weakShell, nsIAccessibleRole::ROLE_PANE);
+      accessible = new nsEnumRoleAccessible(aNode, aWeakShell,
+                                            nsIAccessibleRole::ROLE_PANE);
       break;
     case nsIAccessibleProvider::XULProgressMeter:
-      *aAccessible = new nsXULProgressMeterAccessible(aNode, weakShell);
+      accessible = new nsXULProgressMeterAccessible(aNode, aWeakShell);
       break;
     case nsIAccessibleProvider::XULStatusBar:
-      *aAccessible = new nsXULStatusBarAccessible(aNode, weakShell);
+      accessible = new nsXULStatusBarAccessible(aNode, aWeakShell);
       break;
     case nsIAccessibleProvider::XULScale:
-      *aAccessible = new nsXULSliderAccessible(aNode, weakShell);
+      accessible = new nsXULSliderAccessible(aNode, aWeakShell);
       break;
     case nsIAccessibleProvider::XULRadioButton:
-      *aAccessible = new nsXULRadioButtonAccessible(aNode, weakShell);
+      accessible = new nsXULRadioButtonAccessible(aNode, aWeakShell);
       break;
     case nsIAccessibleProvider::XULRadioGroup:
-      *aAccessible = new nsXULRadioGroupAccessible(aNode, weakShell);
+      accessible = new nsXULRadioGroupAccessible(aNode, aWeakShell);
       break;
     case nsIAccessibleProvider::XULTab:
-      *aAccessible = new nsXULTabAccessible(aNode, weakShell);
+      accessible = new nsXULTabAccessible(aNode, aWeakShell);
       break;
     case nsIAccessibleProvider::XULTabBox:
-      *aAccessible = new nsXULTabBoxAccessible(aNode, weakShell);
+      accessible = new nsXULTabBoxAccessible(aNode, aWeakShell);
       break;
     case nsIAccessibleProvider::XULTabs:
-      *aAccessible = new nsXULTabsAccessible(aNode, weakShell);
+      accessible = new nsXULTabsAccessible(aNode, aWeakShell);
       break;
     case nsIAccessibleProvider::XULText:
-      *aAccessible = new nsXULTextAccessible(aNode, weakShell);
+      accessible = new nsXULTextAccessible(aNode, aWeakShell);
       break;
     case nsIAccessibleProvider::XULTextBox:
-      *aAccessible = new nsXULTextFieldAccessible(aNode, weakShell);
+      accessible = new nsXULTextFieldAccessible(aNode, aWeakShell);
       break;
     case nsIAccessibleProvider::XULThumb:
-      *aAccessible = new nsXULThumbAccessible(aNode, weakShell);
+      accessible = new nsXULThumbAccessible(aNode, aWeakShell);
       break;
     case nsIAccessibleProvider::XULTree:
-      return GetAccessibleForXULTree(aNode, weakShell, aAccessible);
+      return CreateAccessibleForXULTree(aNode, aWeakShell);
+
     case nsIAccessibleProvider::XULTreeColumns:
-      *aAccessible = new nsXULTreeColumnsAccessible(aNode, weakShell);
+      accessible = new nsXULTreeColumnsAccessible(aNode, aWeakShell);
       break;
     case nsIAccessibleProvider::XULTreeColumnItem:
-      *aAccessible = new nsXULColumnItemAccessible(aNode, weakShell);
+      accessible = new nsXULColumnItemAccessible(aNode, aWeakShell);
       break;
     case nsIAccessibleProvider::XULToolbar:
-      *aAccessible = new nsXULToolbarAccessible(aNode, weakShell);
+      accessible = new nsXULToolbarAccessible(aNode, aWeakShell);
       break;
     case nsIAccessibleProvider::XULToolbarSeparator:
-      *aAccessible = new nsXULToolbarSeparatorAccessible(aNode, weakShell);
+      accessible = new nsXULToolbarSeparatorAccessible(aNode, aWeakShell);
       break;
     case nsIAccessibleProvider::XULTooltip:
-      *aAccessible = new nsXULTooltipAccessible(aNode, weakShell);
+      accessible = new nsXULTooltipAccessible(aNode, aWeakShell);
       break;
     case nsIAccessibleProvider::XULToolbarButton:
-      *aAccessible = new nsXULToolbarButtonAccessible(aNode, weakShell);
+      accessible = new nsXULToolbarButtonAccessible(aNode, aWeakShell);
       break;
 #endif // MOZ_XUL
 
 #ifndef DISABLE_XFORMS_HOOKS
     // XForms elements
     case nsIAccessibleProvider::XFormsContainer:
-      *aAccessible = new nsXFormsContainerAccessible(aNode, weakShell);
+      accessible = new nsXFormsContainerAccessible(aNode, aWeakShell);
       break;
 
     case nsIAccessibleProvider::XFormsLabel:
-      *aAccessible = new nsXFormsLabelAccessible(aNode, weakShell);
+      accessible = new nsXFormsLabelAccessible(aNode, aWeakShell);
       break;
     case nsIAccessibleProvider::XFormsOuput:
-      *aAccessible = new nsXFormsOutputAccessible(aNode, weakShell);
+      accessible = new nsXFormsOutputAccessible(aNode, aWeakShell);
       break;
     case nsIAccessibleProvider::XFormsTrigger:
-      *aAccessible = new nsXFormsTriggerAccessible(aNode, weakShell);
+      accessible = new nsXFormsTriggerAccessible(aNode, aWeakShell);
       break;
     case nsIAccessibleProvider::XFormsInput:
-      *aAccessible = new nsXFormsInputAccessible(aNode, weakShell);
+      accessible = new nsXFormsInputAccessible(aNode, aWeakShell);
       break;
     case nsIAccessibleProvider::XFormsInputBoolean:
-      *aAccessible = new nsXFormsInputBooleanAccessible(aNode, weakShell);
+      accessible = new nsXFormsInputBooleanAccessible(aNode, aWeakShell);
       break;
     case nsIAccessibleProvider::XFormsInputDate:
-      *aAccessible = new nsXFormsInputDateAccessible(aNode, weakShell);
+      accessible = new nsXFormsInputDateAccessible(aNode, aWeakShell);
       break;
     case nsIAccessibleProvider::XFormsSecret:
-      *aAccessible = new nsXFormsSecretAccessible(aNode, weakShell);
+      accessible = new nsXFormsSecretAccessible(aNode, aWeakShell);
       break;
     case nsIAccessibleProvider::XFormsSliderRange:
-      *aAccessible = new nsXFormsRangeAccessible(aNode, weakShell);
+      accessible = new nsXFormsRangeAccessible(aNode, aWeakShell);
       break;
     case nsIAccessibleProvider::XFormsSelect:
-      *aAccessible = new nsXFormsSelectAccessible(aNode, weakShell);
+      accessible = new nsXFormsSelectAccessible(aNode, aWeakShell);
       break;
     case nsIAccessibleProvider::XFormsChoices:
-      *aAccessible = new nsXFormsChoicesAccessible(aNode, weakShell);
+      accessible = new nsXFormsChoicesAccessible(aNode, aWeakShell);
       break;
     case nsIAccessibleProvider::XFormsSelectFull:
-      *aAccessible = new nsXFormsSelectFullAccessible(aNode, weakShell);
+      accessible = new nsXFormsSelectFullAccessible(aNode, aWeakShell);
       break;
     case nsIAccessibleProvider::XFormsItemCheckgroup:
-      *aAccessible = new nsXFormsItemCheckgroupAccessible(aNode, weakShell);
+      accessible = new nsXFormsItemCheckgroupAccessible(aNode, aWeakShell);
       break;
     case nsIAccessibleProvider::XFormsItemRadiogroup:
-      *aAccessible = new nsXFormsItemRadiogroupAccessible(aNode, weakShell);
+      accessible = new nsXFormsItemRadiogroupAccessible(aNode, aWeakShell);
       break;
     case nsIAccessibleProvider::XFormsSelectCombobox:
-      *aAccessible = new nsXFormsSelectComboboxAccessible(aNode, weakShell);
+      accessible = new nsXFormsSelectComboboxAccessible(aNode, aWeakShell);
       break;
     case nsIAccessibleProvider::XFormsItemCombobox:
-      *aAccessible = new nsXFormsItemComboboxAccessible(aNode, weakShell);
+      accessible = new nsXFormsItemComboboxAccessible(aNode, aWeakShell);
       break;
 
     case nsIAccessibleProvider::XFormsDropmarkerWidget:
-      *aAccessible = new nsXFormsDropmarkerWidgetAccessible(aNode, weakShell);
+      accessible = new nsXFormsDropmarkerWidgetAccessible(aNode, aWeakShell);
       break;
     case nsIAccessibleProvider::XFormsCalendarWidget:
-      *aAccessible = new nsXFormsCalendarWidgetAccessible(aNode, weakShell);
+      accessible = new nsXFormsCalendarWidgetAccessible(aNode, aWeakShell);
       break;
     case nsIAccessibleProvider::XFormsComboboxPopupWidget:
-      *aAccessible = new nsXFormsComboboxPopupWidgetAccessible(aNode, weakShell);
+      accessible = new nsXFormsComboboxPopupWidgetAccessible(aNode, aWeakShell);
       break;
 #endif
 
     default:
-      return NS_ERROR_FAILURE;
+      return nsnull;
   }
 
-  if (!*aAccessible)
-    return NS_ERROR_OUT_OF_MEMORY;
+  return accessible.forget();
+}
 
-  NS_ADDREF(*aAccessible);
-  return NS_OK;
-}
+////////////////////////////////////////////////////////////////////////////////
+// nsIAccessibilityService (DON'T put methods here)
 
 NS_IMETHODIMP nsAccessibilityService::AddNativeRootAccessible(void * aAtkAccessible,  nsIAccessible **aRootAccessible)
 {
 #ifdef MOZ_ACCESSIBILITY_ATK
   nsNativeRootAccessibleWrap* rootAccWrap =
     new nsNativeRootAccessibleWrap((AtkObject*)aAtkAccessible);
 
   *aRootAccessible = static_cast<nsIAccessible*>(rootAccWrap);
@@ -2014,18 +2041,19 @@ nsAccessibilityService::InvalidateSubtre
   nsRefPtr<nsDocAccessible> docAcc =
     nsAccUtils::QueryAccessibleDocument(accessibleDoc);
   if (docAcc)
     docAcc->InvalidateCacheSubtree(aChangeContent, aChangeType);
 
   return NS_OK;
 }
 
-//////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+// NS_GetAccessibilityService
+////////////////////////////////////////////////////////////////////////////////
 
 /**
  * Return accessibility service; creating one if necessary.
  */
 nsresult
 NS_GetAccessibilityService(nsIAccessibilityService** aResult)
 {
    NS_ENSURE_TRUE(aResult, NS_ERROR_NULL_POINTER);
@@ -2037,81 +2065,68 @@ NS_GetAccessibilityService(nsIAccessibil
  
     nsAccessibilityService::gIsShutdown = PR_FALSE;
    }
  
   NS_ADDREF(*aResult = nsAccessibilityService::gAccessibilityService);
   return NS_OK;
 }
 
-nsresult
-nsAccessibilityService::GetAccessibleForDeckChildren(nsIDOMNode *aNode, nsIAccessible** aAccessible)
+////////////////////////////////////////////////////////////////////////////////
+// nsAccessibilityService private (DON'T put methods here)
+
+already_AddRefed<nsAccessible>
+nsAccessibilityService::CreateAccessibleForDeckChild(nsIFrame* aFrame,
+                                                     nsIDOMNode *aNode,
+                                                     nsIWeakReference *aWeakShell)
 {
-  nsCOMPtr<nsIWeakReference> weakShell;
-  GetShellFromNode(aNode, getter_AddRefs(weakShell));
-  NS_ENSURE_TRUE(weakShell, NS_ERROR_FAILURE);
-  nsCOMPtr<nsIPresShell> shell(do_QueryReferent(weakShell));
-  NS_ENSURE_TRUE(shell, NS_ERROR_FAILURE);
-  
-  nsIFrame* frame = nsnull;
-  nsIFrame* parentFrame = nsnull;
-  nsCOMPtr<nsIContent> content(do_QueryInterface(aNode));
+  nsRefPtr<nsAccessible> accessible;
 
-  if (content) {
-    frame = content->GetPrimaryFrame();
-  }
+  if (aFrame->GetType() == nsAccessibilityAtoms::boxFrame ||
+      aFrame->GetType() == nsAccessibilityAtoms::scrollFrame) {
 
-  if (frame && (frame->GetType() == nsAccessibilityAtoms::boxFrame ||
-                frame->GetType() == nsAccessibilityAtoms::scrollFrame)) { 
-    parentFrame = frame->GetParent();
+    nsIFrame* parentFrame = aFrame->GetParent();
     if (parentFrame && parentFrame->GetType() == nsAccessibilityAtoms::deckFrame) {
       // If deck frame is for xul:tabpanels element then the given node has
       // tabpanel accessible.
       nsCOMPtr<nsIContent> parentContent = parentFrame->GetContent();
 #ifdef MOZ_XUL
       if (parentContent->NodeInfo()->Equals(nsAccessibilityAtoms::tabpanels,
                                             kNameSpaceID_XUL)) {
-        *aAccessible = new nsXULTabpanelAccessible(aNode, weakShell);
+        accessible = new nsXULTabpanelAccessible(aNode, aWeakShell);
       } else
 #endif
-        *aAccessible =
-          new nsEnumRoleAccessible(aNode, weakShell,
+        accessible =
+          new nsEnumRoleAccessible(aNode, aWeakShell,
                                    nsIAccessibleRole::ROLE_PROPERTYPAGE);
-
-      NS_ENSURE_TRUE(*aAccessible, NS_ERROR_OUT_OF_MEMORY);
-
-      NS_ADDREF(*aAccessible);
     }
   }
 
-  return NS_OK;
+  return accessible.forget();
 }
 
 #ifdef MOZ_XUL
-nsresult
-nsAccessibilityService::GetAccessibleForXULTree(nsIDOMNode *aNode,
-                                                nsIWeakReference *aWeakShell,
-                                                nsIAccessible **aAccessible)
+already_AddRefed<nsAccessible>
+nsAccessibilityService::CreateAccessibleForXULTree(nsIDOMNode *aNode,
+                                                   nsIWeakReference *aWeakShell)
 {
   nsCOMPtr<nsITreeBoxObject> treeBoxObj;
   nsCoreUtils::GetTreeBoxObject(aNode, getter_AddRefs(treeBoxObj));
   if (!treeBoxObj)
-    return NS_ERROR_FAILURE;
+    return nsnull;
 
   nsCOMPtr<nsITreeColumns> treeColumns;
   treeBoxObj->GetColumns(getter_AddRefs(treeColumns));
   if (!treeColumns)
-    return NS_OK;
+    return nsnull;
+
+  nsRefPtr<nsAccessible> accessible;
 
   PRInt32 count = 0;
   treeColumns->GetCount(&count);
   if (count == 1) // outline of list accessible
-    *aAccessible = new nsXULTreeAccessible(aNode, aWeakShell);
+    accessible = new nsXULTreeAccessible(aNode, aWeakShell);
   else // table or tree table accessible
-    *aAccessible = new nsXULTreeGridAccessibleWrap(aNode, aWeakShell);
+    accessible = new nsXULTreeGridAccessibleWrap(aNode, aWeakShell);
 
-  if (!*aAccessible)
-    return NS_ERROR_OUT_OF_MEMORY;
-
-  NS_ADDREF(*aAccessible);
-  return NS_OK;
+  return accessible.forget();
 }
 #endif
--- a/accessible/src/base/nsAccessibilityService.h
+++ b/accessible/src/base/nsAccessibilityService.h
@@ -45,16 +45,17 @@
 
 #include "nsCOMArray.h"
 #include "nsIObserver.h"
 #include "nsIWebProgress.h"
 #include "nsIWebProgressListener.h"
 #include "nsWeakReference.h"
 
 class nsAccessNode;
+class nsAccessible;
 class nsIFrame;
 class nsIWeakReference;
 class nsIDOMNode;
 class nsObjectFrame;
 class nsIDocShell;
 class nsIPresShell;
 class nsIContent;
 struct nsRoleMapEntry;
@@ -88,22 +89,22 @@ public:
   static PRBool gIsShutdown;
 
   /**
    * Return an accessible for the given DOM node.
    *
    * @param  aNode       [in] the given node
    * @param  aPresShell  [in] the pres shell of the node
    * @param  aWeakShell  [in] the weak shell for the pres shell
-   * @param  aFrameHint  [in] the frame of the given node
-   * @param  aIsHidden   [out] indicates whether the node's frame is hidden
+   * @param  aIsHidden   [out, optional] indicates whether the node's frame is
+   *                       hidden
    */
-  nsresult GetAccessible(nsIDOMNode *aNode, nsIPresShell *aPresShell,
-                         nsIWeakReference *aWeakShell, nsIFrame *aFrameHint,
-                         PRBool *aIsHidden, nsIAccessible **aAccessible);
+  already_AddRefed<nsAccessible>
+    GetAccessible(nsIDOMNode *aNode, nsIPresShell *aPresShell,
+                  nsIWeakReference *aWeakShell, PRBool *aIsHidden = nsnull);
 
   /**
    * Return an accessible for a DOM node in the given pres shell.
    * 
    * @param aNode       [in] the given node.
    * @param aPresShell  [in] the presentation shell of the given node.
    * @param aAccessible [out] the nsIAccessible for the given node.
    */
@@ -134,48 +135,58 @@ private:
   nsresult GetInfo(nsIFrame *aFrame,
                    nsIWeakReference **aShell,
                    nsIDOMNode **aContent);
 
   /**
    * Initialize an accessible and cache it. The method should be called for
    * every created accessible.
    *
-   * @param aAccessibleIn - accessible to initialize.
-   * @param aAcccessibleOut - set to the same thing as aAccessibleIn, unless there was
-   *                          an error initializing the accessible, in which case
-   *                          it is set to nsnull
-   * @param aRoleMapEntry - The role map entry role the ARIA role or nsnull if none
+   * @param  aAccessible    [in] accessible to initialize.
+   * @param  aRoleMapEntry  [in] the role map entry role the ARIA role or nsnull
+   *                          if none
+   *
+   * @return true if the accessible was initialized, otherwise false
    */
-  nsresult InitAccessible(nsIAccessible *aAccessibleIn, nsIAccessible **aAccessibleOut,
-                          nsRoleMapEntry *aRoleMapEntry = nsnull);
+  PRBool InitAccessible(nsAccessible *aAccessible,
+                        nsRoleMapEntry *aRoleMapEntry);
+
+  /**
+   * Create accessible for the element implementing nsIAccessibleProvider
+   * interface.
+   */
+  already_AddRefed<nsAccessible>
+    CreateAccessibleByType(nsIDOMNode *aNode, nsIWeakReference *aWeakShell);
 
   /**
-   * Return accessible object for elements implementing nsIAccessibleProvider
-   * interface.
-   *
-   * @param aNode - DOM node that accessible is returned for.
+   * Create document or root accessible.
    */
-  nsresult GetAccessibleByType(nsIDOMNode *aNode, nsIAccessible **aAccessible);
+  already_AddRefed<nsAccessible>
+    CreateDocOrRootAccessible(nsIPresShell *aShell, nsIDocument *aDocument);
 
   /**
-   * Return accessible object if parent is a deck frame.
-   *
-   * @param aNode - DOMNode that accessible is returned for.
+   * Create accessible for HTML node by tag name.
    */
-  nsresult GetAccessibleForDeckChildren(nsIDOMNode *aNode,
-                                        nsIAccessible **aAccessible);
+  already_AddRefed<nsAccessible>
+    CreateHTMLAccessibleByMarkup(nsIFrame *aFrame, nsIWeakReference *aWeakShell,
+                                 nsIDOMNode *aNode);
+
+  /**
+   * Create accessible if parent is a deck frame.
+   */
+  already_AddRefed<nsAccessible>
+    CreateAccessibleForDeckChild(nsIFrame *aFrame, nsIDOMNode *aNode,
+                                 nsIWeakReference *aWeakShell);
 
 #ifdef MOZ_XUL
   /**
    * Create accessible for XUL tree element.
    */
-  nsresult GetAccessibleForXULTree(nsIDOMNode *aNode,
-                                   nsIWeakReference *aWeakShell,
-                                   nsIAccessible **aAccessible);
+  already_AddRefed<nsAccessible>
+    CreateAccessibleForXULTree(nsIDOMNode *aNode, nsIWeakReference *aWeakShell);
 #endif
   
   static nsAccessibilityService *gAccessibilityService;
 
   /**
    * Does this content node have a universal ARIA property set on it?
    * A universal ARIA property is one that can be defined on any element even if there is no role.
    *
--- a/accessible/src/base/nsAccessible.cpp
+++ b/accessible/src/base/nsAccessible.cpp
@@ -2985,24 +2985,20 @@ nsAccessible::GetCachedFirstChild()
 // nsAccessible protected methods
 
 void
 nsAccessible::CacheChildren()
 {
   nsAccTreeWalker walker(mWeakShell, nsCoreUtils::GetRoleContent(mDOMNode),
                          GetAllowsAnonChildAccessibles());
 
-  nsCOMPtr<nsIAccessible> child;
+  nsRefPtr<nsAccessible> child;
   while ((child = walker.GetNextChild())) {
-    nsRefPtr<nsAccessible> acc =
-      nsAccUtils::QueryObject<nsAccessible>(child);
-
-    mChildren.AppendElement(acc);
-
-    acc->SetParent(this);
+    mChildren.AppendElement(child);
+    child->SetParent(this);
   }
 }
 
 void
 nsAccessible::TestChildCache(nsAccessible *aCachedChild)
 {
 #ifdef DEBUG
   // All cached accessible nodes should be in the parent
--- a/accessible/src/base/nsDocAccessible.cpp
+++ b/accessible/src/base/nsDocAccessible.cpp
@@ -567,26 +567,26 @@ nsDocAccessible::GetCachedAccessNode(voi
       parent->TestChildCache(acc);
   }
 #endif
 
   return accessNode;
 }
 
 // nsDocAccessible public method
-void
+PRBool
 nsDocAccessible::CacheAccessNode(void *aUniqueID, nsAccessNode *aAccessNode)
 {
   // If there is already an access node with the given unique ID, shut it down
   // because the DOM node has changed.
   nsAccessNode* accessNode = mAccessNodeCache.GetWeak(aUniqueID);
   if (accessNode)
     accessNode->Shutdown();
 
-  mAccessNodeCache.Put(aUniqueID, aAccessNode);
+  return mAccessNodeCache.Put(aUniqueID, aAccessNode);
 }
 
 // nsDocAccessible public method
 void
 nsDocAccessible::RemoveAccessNodeFromCache(nsIAccessNode *aAccessNode)
 {
   if (!aAccessNode)
     return;
@@ -597,30 +597,36 @@ nsDocAccessible::RemoveAccessNodeFromCac
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccessNode
 
 nsresult
 nsDocAccessible::Init()
 {
-  gGlobalDocAccessibleCache.Put(static_cast<void*>(mDocument), this);
+  // Put the document into the global cache.
+  if (!gGlobalDocAccessibleCache.Put(static_cast<void*>(mDocument), this))
+    return NS_ERROR_OUT_OF_MEMORY;
+
+  // Initialize event queue.
+  mEventQueue = new nsAccEventQueue(this);
+  if (!mEventQueue)
+    return NS_ERROR_OUT_OF_MEMORY;
 
   AddEventListeners();
 
-  GetParent(); // Ensure outer doc mParent accessible.
-
-  // Initialize event queue.
-  mEventQueue = new nsAccEventQueue(this);
+  // Ensure outer doc mParent accessible.
+  GetParent();
 
   // Fire reorder event to notify new accessible document has been created and
   // attached to the tree.
   nsRefPtr<nsAccEvent> reorderEvent =
     new nsAccReorderEvent(mParent, PR_FALSE, PR_TRUE, mDOMNode);
-  NS_ENSURE_TRUE(reorderEvent, NS_ERROR_OUT_OF_MEMORY);
+  if (!reorderEvent)
+    return NS_ERROR_OUT_OF_MEMORY;
 
   FireDelayedAccessibleEvent(reorderEvent);
   return NS_OK;
 }
 
 nsresult
 nsDocAccessible::Shutdown()
 {
--- a/accessible/src/base/nsDocAccessible.h
+++ b/accessible/src/base/nsDocAccessible.h
@@ -162,18 +162,20 @@ public:
    */
   nsAccessNode* GetCachedAccessNode(void *aUniqueID);
 
   /**
    * Cache the access node.
    *
    * @param  aUniquID     [in] the unique identifier of accessible
    * @param  aAccessNode  [in] accessible to cache
+   *
+   * @return true if node beign cached, otherwise false
    */
-  void CacheAccessNode(void *aUniqueID, nsAccessNode *aAccessNode);
+  PRBool CacheAccessNode(void *aUniqueID, nsAccessNode *aAccessNode);
 
   /**
    * Remove the given access node from document cache.
    */
   void RemoveAccessNodeFromCache(nsIAccessNode *aAccessNode);
 
   /**
    * Fire document load events.
--- a/accessible/src/xul/nsXULColorPickerAccessible.cpp
+++ b/accessible/src/xul/nsXULColorPickerAccessible.cpp
@@ -164,24 +164,21 @@ nsXULColorPickerAccessible::GetRoleInter
 // nsXULColorPickerAccessible: protected nsAccessible
 
 void
 nsXULColorPickerAccessible::CacheChildren()
 {
   nsCOMPtr<nsIContent> node(do_QueryInterface(mDOMNode));
   nsAccTreeWalker walker(mWeakShell, node, PR_TRUE);
 
-  nsCOMPtr<nsIAccessible> child;
+  nsRefPtr<nsAccessible> child;
   while ((child = walker.GetNextChild())) {
     PRUint32 role = nsAccUtils::Role(child);
 
     // Get an accessbile for menupopup or panel elements.
     if (role == nsIAccessibleRole::ROLE_ALERT) {
-      nsRefPtr<nsAccessible> menupopupAcc =
-        nsAccUtils::QueryObject<nsAccessible>(child);
-
-      mChildren.AppendElement(menupopupAcc);
-      menupopupAcc->SetParent(this);
+      mChildren.AppendElement(child);
+      child->SetParent(this);
 
       return;
     }
   }
 }
--- a/accessible/src/xul/nsXULFormControlAccessible.cpp
+++ b/accessible/src/xul/nsXULFormControlAccessible.cpp
@@ -199,52 +199,46 @@ nsXULButtonAccessible::CacheChildren()
   PRBool isMenuButton = isMenu ?
     PR_FALSE :
     content->AttrValueIs(kNameSpaceID_None, nsAccessibilityAtoms::type,
                          nsAccessibilityAtoms::menuButton, eCaseMatters);
 
   if (!isMenu && !isMenuButton)
     return;
 
-  nsCOMPtr<nsIAccessible> buttonAccessible;
-  nsCOMPtr<nsIAccessible> menupopupAccessible;
+  nsRefPtr<nsAccessible> menupopupAccessible;
+  nsRefPtr<nsAccessible> buttonAccessible;
 
   nsAccTreeWalker walker(mWeakShell, content, PR_TRUE);
 
-  nsCOMPtr<nsIAccessible> child;
+  nsRefPtr<nsAccessible> child;
   while ((child = walker.GetNextChild())) {
     PRUint32 role = nsAccUtils::Role(child);
 
     if (role == nsIAccessibleRole::ROLE_MENUPOPUP) {
       // Get an accessbile for menupopup or panel elements.
-      child.swap(menupopupAccessible);
+      menupopupAccessible.swap(child);
 
     } else if (isMenuButton && role == nsIAccessibleRole::ROLE_PUSHBUTTON) {
       // Button type="menu-button" contains a real button. Get an accessible
       // for it. Ignore dropmarker button what is placed as a last child.
-      child.swap(buttonAccessible);
+      buttonAccessible.swap(child);
       break;
     }
   }
 
   if (!menupopupAccessible)
     return;
 
-  nsRefPtr<nsAccessible> menupopupAcc =
-    nsAccUtils::QueryObject<nsAccessible>(menupopupAccessible);
-
-  mChildren.AppendElement(menupopupAcc);
-  menupopupAcc->SetParent(this);
+  mChildren.AppendElement(menupopupAccessible);
+  menupopupAccessible->SetParent(this);
 
   if (buttonAccessible) {
-    nsRefPtr<nsAccessible> buttonAcc =
-      nsAccUtils::QueryObject<nsAccessible>(buttonAccessible);
-
-    mChildren.AppendElement(buttonAcc);
-    buttonAcc->SetParent(this);
+    mChildren.AppendElement(buttonAccessible);
+    buttonAccessible->SetParent(this);
   }
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsXULButtonAccessible protected
 
 PRBool
 nsXULButtonAccessible::ContainsMenu()
@@ -1075,18 +1069,14 @@ nsXULTextFieldAccessible::CacheChildren(
   // input element.
   nsCOMPtr<nsIDOMNode> inputNode(GetInputField());
   nsCOMPtr<nsIContent> inputContent(do_QueryInterface(inputNode));
   if (!inputContent)
     return;
 
   nsAccTreeWalker walker(mWeakShell, inputContent, PR_FALSE);
 
-  nsCOMPtr<nsIAccessible> child;
+  nsRefPtr<nsAccessible> child;
   while ((child = walker.GetNextChild())) {
-    nsRefPtr<nsAccessible> acc =
-      nsAccUtils::QueryObject<nsAccessible>(child);
-
-    mChildren.AppendElement(acc);
-
-    acc->SetParent(this);
+    mChildren.AppendElement(child);
+    child->SetParent(this);
   }
 }