Bug 538633 - nsAccessible tree navigation methods should deal with nsAccessible pointers, r=marcoz, davidb, sr=neil
authorAlexander Surkov <surkov.alexander@gmail.com>
Mon, 11 Jan 2010 22:14:06 +0800
changeset 36989 8551655e7bac22e2a62f64f0cb4e9edfca5617b3
parent 36988 e7633625eabdc3d98360f8c7df7e8bb2276febbe
child 36990 502ed2576efcee59f104cd7ae3ddc8cb5199eeea
child 46501 c6c3b6f9cf71f674693042c259664e6f9c54cc3e
push idunknown
push userunknown
push dateunknown
reviewersmarcoz, davidb, neil
bugs538633
milestone1.9.3a1pre
Bug 538633 - nsAccessible tree navigation methods should deal with nsAccessible pointers, r=marcoz, davidb, sr=neil
accessible/src/atk/nsApplicationAccessibleWrap.cpp
accessible/src/base/nsAccUtils.h
accessible/src/base/nsAccessible.cpp
accessible/src/base/nsAccessible.h
accessible/src/base/nsApplicationAccessible.cpp
accessible/src/base/nsApplicationAccessible.h
accessible/src/base/nsDocAccessible.cpp
accessible/src/base/nsDocAccessible.h
accessible/src/base/nsOuterDocAccessible.cpp
accessible/src/base/nsRootAccessible.cpp
accessible/src/base/nsRootAccessible.h
accessible/src/html/nsHTMLFormControlAccessible.cpp
accessible/src/html/nsHTMLImageAccessible.cpp
accessible/src/html/nsHTMLSelectAccessible.cpp
accessible/src/html/nsHTMLSelectAccessible.h
accessible/src/html/nsHTMLTableAccessible.cpp
accessible/src/html/nsHTMLTextAccessible.cpp
accessible/src/html/nsHTMLTextAccessible.h
accessible/src/html/nsHyperTextAccessible.cpp
accessible/src/mac/nsAccessibleWrap.h
accessible/src/mac/nsAccessibleWrap.mm
accessible/src/msaa/nsAccessibleWrap.cpp
accessible/src/msaa/nsHTMLWin32ObjectAccessible.cpp
accessible/src/msaa/nsHTMLWin32ObjectAccessible.h
accessible/src/xforms/nsXFormsAccessible.cpp
accessible/src/xul/nsXULColorPickerAccessible.cpp
accessible/src/xul/nsXULFormControlAccessible.cpp
accessible/src/xul/nsXULFormControlAccessible.h
accessible/src/xul/nsXULMenuAccessible.cpp
accessible/src/xul/nsXULTabAccessible.cpp
accessible/src/xul/nsXULTreeAccessible.cpp
accessible/src/xul/nsXULTreeAccessible.h
accessible/src/xul/nsXULTreeGridAccessible.cpp
accessible/src/xul/nsXULTreeGridAccessible.h
--- a/accessible/src/atk/nsApplicationAccessibleWrap.cpp
+++ b/accessible/src/atk/nsApplicationAccessibleWrap.cpp
@@ -660,17 +660,17 @@ nsApplicationAccessibleWrap::AddRootAcce
 
     // add by weak reference
     nsresult rv = nsApplicationAccessible::AddRootAccessible(aRootAccWrap);
     NS_ENSURE_SUCCESS(rv, rv);
 
     AtkObject *atkAccessible = nsAccessibleWrap::GetAtkObject(aRootAccWrap);
     atk_object_set_parent(atkAccessible, mAtkObject);
 
-    PRUint32 count = mChildren.Count();
+    PRUint32 count = mChildren.Length();
 
     // Emit children_changed::add in a timeout
     // to make sure aRootAccWrap is fully initialized.
     AtkRootAccessibleAddedEvent* eventData = (AtkRootAccessibleAddedEvent*)
       malloc(sizeof(AtkRootAccessibleAddedEvent));
     if (eventData) {
       eventData->app_accessible = mAtkObject;
       eventData->root_accessible = atkAccessible;
--- a/accessible/src/base/nsAccUtils.h
+++ b/accessible/src/base/nsAccUtils.h
@@ -330,16 +330,25 @@ public:
     already_AddRefed<DestinationType> QueryObject(nsCOMPtr<SourceType>& aObject)
   {
     DestinationType* object = nsnull;
     if (aObject)
       CallQueryInterface(aObject, &object);
 
     return object;
   }
+  template<class DestinationType, class SourceType> static inline
+  already_AddRefed<DestinationType> QueryObject(nsRefPtr<SourceType>& aObject)
+  {
+    DestinationType* object = nsnull;
+    if (aObject)
+      CallQueryInterface(aObject.get(), &object);
+    
+    return object;
+  }
 
   /**
    * Query nsAccessNode from the given nsIAccessible.
    */
   static already_AddRefed<nsAccessNode>
     QueryAccessNode(nsIAccessible *aAccessible)
   {
     nsAccessNode* accessNode = nsnull;
--- a/accessible/src/base/nsAccessible.cpp
+++ b/accessible/src/base/nsAccessible.cpp
@@ -143,23 +143,29 @@ nsAccessibleDOMStringList::Contains(cons
  */
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccessible. nsISupports
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsAccessible)
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsAccessible, nsAccessNode)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mParent)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mChildren)
+  NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mParent");
+  cb.NoteXPCOMChild(static_cast<nsIAccessible*>(tmp->mParent.get()));
+
+  PRUint32 i, length = tmp->mChildren.Length();
+  for (i = 0; i < length; ++i) {
+    NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mChildren[i]");
+    cb.NoteXPCOMChild(static_cast<nsIAccessible*>(tmp->mChildren[i].get()));
+  }
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsAccessible, nsAccessNode)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mParent)
-  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMARRAY(mChildren)
+  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSTARRAY(mChildren)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_IMPL_ADDREF_INHERITED(nsAccessible, nsAccessNode)
 NS_IMPL_RELEASE_INHERITED(nsAccessible, nsAccessNode)
 
 nsresult nsAccessible::QueryInterface(REFNSIID aIID, void** aInstancePtr)
 {
   // Custom-built QueryInterface() knows when we support nsIAccessibleSelectable
@@ -204,18 +210,19 @@ nsresult nsAccessible::QueryInterface(RE
     if (mRoleMapEntry && mRoleMapEntry->valueRule != eNoValue) {
       *aInstancePtr = static_cast<nsIAccessibleValue*>(this);
       NS_ADDREF_THIS();
       return NS_OK;
     }
   }                       
 
   if (aIID.Equals(NS_GET_IID(nsIAccessibleHyperLink))) {
-    nsCOMPtr<nsIAccessible> parent(GetParent());
-    nsCOMPtr<nsIAccessibleHyperText> hyperTextParent(do_QueryInterface(parent));
+    nsCOMPtr<nsIAccessibleHyperText> hyperTextParent =
+      nsAccUtils::QueryObject<nsIAccessibleHyperText>(GetParent());
+
     if (hyperTextParent) {
       *aInstancePtr = static_cast<nsIAccessibleHyperLink*>(this);
       NS_ADDREF_THIS();
       return NS_OK;
     }
     return NS_ERROR_NO_INTERFACE;
   }
 
@@ -478,18 +485,17 @@ nsAccessible::GetKeyboardShortcut(nsAStr
 
 nsresult
 nsAccessible::Shutdown()
 {
   // Invalidate the child count and pointers to other accessibles, also make
   // sure none of its children point to this parent
   InvalidateChildren();
   if (mParent) {
-    nsRefPtr<nsAccessible> parent(nsAccUtils::QueryAccessible(mParent));
-    parent->InvalidateChildren();
+    mParent->InvalidateChildren();
     mParent = nsnull;
   }
 
   return nsAccessNodeWrap::Shutdown();
 }
 
 NS_IMETHODIMP
 nsAccessible::GetParent(nsIAccessible **aParent)
@@ -564,17 +570,17 @@ nsAccessible::GetChildAt(PRInt32 aChildI
   PRInt32 childCount = GetChildCount();
   NS_ENSURE_TRUE(childCount != -1, NS_ERROR_FAILURE);
 
   // If child index is negative, then return last child.
   // XXX: do we really need this?
   if (aChildIndex < 0)
     aChildIndex = childCount - 1;
 
-  nsIAccessible* child = GetChildAt(aChildIndex);
+  nsAccessible* child = GetChildAt(aChildIndex);
   if (!child)
     return NS_ERROR_INVALID_ARG;
 
   NS_ADDREF(*aChild = child);
   return NS_OK;
 }
 
 // readonly attribute nsIArray children;
@@ -2338,19 +2344,17 @@ nsAccessible::GetRelationByType(PRUint32
       // (because it is system generated and has no idea about the hierarchy
       // above it).
       nsIFrame *frame = GetFrame();
       if (frame) {
         nsIView *view = frame->GetViewExternal();
         if (view) {
           nsIScrollableFrame *scrollFrame = do_QueryFrame(frame);
           if (scrollFrame || view->GetWidget() || !frame->GetParent()) {
-            nsCOMPtr<nsIAccessible> accTarget;
-            GetParent(getter_AddRefs(accTarget));
-            return nsRelUtils::AddTarget(aRelationType, aRelation, accTarget);
+            return nsRelUtils::AddTarget(aRelationType, aRelation, GetParent());
           }
         }
       }
 
       return NS_OK;
     }
 
   case nsIAccessibleRelation::RELATION_CONTROLLED_BY:
@@ -2687,38 +2691,34 @@ NS_IMETHODIMP nsAccessible::GetSelection
 NS_IMETHODIMP nsAccessible::AddChildToSelection(PRInt32 aIndex)
 {
   // Tree views and other container widgets which may have grandchildren should
   // implement a selection methods for their specific interfaces, because being
   // able to deal with selection on a per-child basis would not be enough.
 
   NS_ENSURE_TRUE(aIndex >= 0, NS_ERROR_FAILURE);
 
-  nsCOMPtr<nsIAccessible> child;
-  GetChildAt(aIndex, getter_AddRefs(child));
-
+  nsAccessible* child = GetChildAt(aIndex);
   PRUint32 state = nsAccUtils::State(child);
   if (!(state & nsIAccessibleStates::STATE_SELECTABLE)) {
     return NS_OK;
   }
 
   return child->SetSelected(PR_TRUE);
 }
 
 NS_IMETHODIMP nsAccessible::RemoveChildFromSelection(PRInt32 aIndex)
 {
   // Tree views and other container widgets which may have grandchildren should
   // implement a selection methods for their specific interfaces, because being
   // able to deal with selection on a per-child basis would not be enough.
 
   NS_ENSURE_TRUE(aIndex >= 0, NS_ERROR_FAILURE);
 
-  nsCOMPtr<nsIAccessible> child;
-  GetChildAt(aIndex, getter_AddRefs(child));
-
+  nsAccessible* child = GetChildAt(aIndex);
   PRUint32 state = nsAccUtils::State(child);
   if (!(state & nsIAccessibleStates::STATE_SELECTED)) {
     return NS_OK;
   }
 
   return child->SetSelected(PR_FALSE);
 }
 
@@ -2726,19 +2726,17 @@ NS_IMETHODIMP nsAccessible::IsChildSelec
 {
   // Tree views and other container widgets which may have grandchildren should
   // implement a selection methods for their specific interfaces, because being
   // able to deal with selection on a per-child basis would not be enough.
 
   *aIsSelected = PR_FALSE;
   NS_ENSURE_TRUE(aIndex >= 0, NS_ERROR_FAILURE);
 
-  nsCOMPtr<nsIAccessible> child;
-  GetChildAt(aIndex, getter_AddRefs(child));
-
+  nsAccessible* child = GetChildAt(aIndex);
   PRUint32 state = nsAccUtils::State(child);
   if (state & nsIAccessibleStates::STATE_SELECTED) {
     *aIsSelected = PR_TRUE;
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP nsAccessible::ClearSelection()
@@ -2855,17 +2853,17 @@ nsAccessible::GetSelected(PRBool *aSelec
   NS_ENSURE_ARG_POINTER(aSelected);
   *aSelected = (gLastFocusedNode == mDOMNode);
   return NS_OK;
 }
 
 nsresult nsAccessible::GetLinkOffset(PRInt32* aStartOffset, PRInt32* aEndOffset)
 {
   *aStartOffset = *aEndOffset = 0;
-  nsCOMPtr<nsIAccessible> parent(GetParent());
+  nsAccessible* parent = GetParent();
   if (!parent) {
     return NS_ERROR_FAILURE;
   }
 
   nsCOMPtr<nsIAccessible> accessible, nextSibling;
   PRInt32 characterCount = 0;
   parent->GetFirstChild(getter_AddRefs(accessible));
 
@@ -2935,49 +2933,47 @@ nsAccessible::GetNameInternal(nsAString&
 
   if (content->IsXUL())
     return GetXULName(aName);
 
   return NS_OK;
 }
 
 void
-nsAccessible::SetParent(nsIAccessible *aParent)
+nsAccessible::SetParent(nsAccessible *aParent)
 {
   NS_PRECONDITION(aParent, "This method isn't used to set null parent!");
 
   if (mParent && mParent != aParent) {
     // Adopt a child -- we allow this now. the new parent
     // may be a dom node which wasn't previously accessible but now is.
     // The old parent's children now need to be invalidated, since 
     // it no longer owns the child, the new parent does
     NS_ASSERTION(PR_FALSE, "Adopting child!");
-    nsRefPtr<nsAccessible> oldParent = nsAccUtils::QueryAccessible(mParent);
-    if (oldParent)
-      oldParent->InvalidateChildren();
+    if (mParent)
+      mParent->InvalidateChildren();
   }
 
   mParent = aParent;
 }
 
 void
 nsAccessible::InvalidateChildren()
 {
-  PRInt32 childCount = mChildren.Count();
+  PRInt32 childCount = mChildren.Length();
   for (PRInt32 childIdx = 0; childIdx < childCount; childIdx++) {
-    nsRefPtr<nsAccessible> child =
-      nsAccUtils::QueryObject<nsAccessible>(mChildren.ObjectAt(childIdx));
+    nsAccessible* child = mChildren.ElementAt(childIdx);
     child->mParent = nsnull;
   }
 
   mChildren.Clear();
   mAreChildrenInitialized = PR_FALSE;
 }
 
-nsIAccessible*
+nsAccessible*
 nsAccessible::GetParent()
 {
   if (IsDefunct())
     return nsnull;
 
   if (mParent)
     return mParent;
 
@@ -2986,90 +2982,83 @@ nsAccessible::GetParent()
 
   if (!docAccessible)
     return nsnull;
 
   nsCOMPtr<nsIAccessible> parent;
   docAccessible->GetAccessibleInParentChain(mDOMNode, PR_TRUE,
                                             getter_AddRefs(parent));
 
+  nsRefPtr<nsAccessible> parentAcc = nsAccUtils::QueryAccessible(parent);
+
 #ifdef DEBUG
-  nsRefPtr<nsAccessible> parentAcc = nsAccUtils::QueryAccessible(parent);
   NS_ASSERTION(!parentAcc->IsDefunct(), "Defunct parent!");
 
   parentAcc->EnsureChildren();
   if (parent != mParent)
     NS_WARNING("Bad accessible tree!");
 #endif
 
-  return parent;
+  return parentAcc;
 }
 
-nsIAccessible*
+nsAccessible*
 nsAccessible::GetChildAt(PRUint32 aIndex)
 {
   if (EnsureChildren())
     return nsnull;
 
-  nsIAccessible *child = mChildren.SafeObjectAt(aIndex);
+  nsAccessible *child = mChildren.SafeElementAt(aIndex, nsnull);
   if (!child)
     return nsnull;
 
 #ifdef DEBUG
-  nsRefPtr<nsAccessible> childAcc = nsAccUtils::QueryAccessible(child);
-  nsCOMPtr<nsIAccessible> realParent = childAcc->mParent;
+  nsAccessible* realParent = child->mParent;
   NS_ASSERTION(!realParent || realParent == this,
                "Two accessibles have the same first child accessible!");
 #endif
 
   return child;
 }
 
 PRInt32
 nsAccessible::GetChildCount()
 {
-  return EnsureChildren() ? -1 : mChildren.Count();
+  return EnsureChildren() ? -1 : mChildren.Length();
 }
 
 PRInt32
 nsAccessible::GetIndexOf(nsIAccessible *aChild)
 {
   return EnsureChildren() ? -1 : mChildren.IndexOf(aChild);
 }
 
 PRInt32
 nsAccessible::GetIndexInParent()
 {
-  nsIAccessible *parent = GetParent();
-  if (!parent)
-    return -1;
-
-  nsRefPtr<nsAccessible> parentAcc =
-    nsAccUtils::QueryObject<nsAccessible>(parent);
-  return parentAcc->GetIndexOf(this);
+  nsAccessible *parent = GetParent();
+  return parent ? parent->GetIndexOf(this) : -1;
 }
 
-already_AddRefed<nsIAccessible>
+nsAccessible*
 nsAccessible::GetCachedParent()
 {
   if (IsDefunct())
     return nsnull;
 
-  nsCOMPtr<nsIAccessible> cachedParent = mParent;
-  return cachedParent.forget();
+  return mParent;
 }
 
-already_AddRefed<nsIAccessible>
+nsAccessible*
 nsAccessible::GetCachedFirstChild()
 {
   if (IsDefunct())
     return nsnull;
 
-  nsCOMPtr<nsIAccessible> cachedFirstChild = GetChildAt(0);
-  return cachedFirstChild.forget();
+  return mChildren.SafeElementAt(0, nsnull);
 }
 
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccessible protected methods
 
 void
 nsAccessible::CacheChildren()
@@ -3080,43 +3069,44 @@ nsAccessible::CacheChildren()
   // Seed the frame hint early while we're still on a container node.
   // This is better than doing the GetPrimaryFrameFor() later on
   // a text node, because text nodes aren't in the frame map.
   // XXXbz is this code still needed?
   walker.mState.frame = GetFrame();
 
   walker.GetFirstChild();
   while (walker.mState.accessible) {
-    mChildren.AppendObject(walker.mState.accessible);
-
     nsRefPtr<nsAccessible> acc =
       nsAccUtils::QueryObject<nsAccessible>(walker.mState.accessible);
+
+    mChildren.AppendElement(acc);
+
     acc->SetParent(this);
 
     walker.GetNextSibling();
   }
 }
 
 void
-nsAccessible::TestChildCache(nsIAccessible *aCachedChild)
+nsAccessible::TestChildCache(nsAccessible *aCachedChild)
 {
 #ifdef DEBUG_A11Y
   // All cached accessible nodes should be in the parent
   // It will assert if not all the children were created
   // when they were first cached, and no invalidation
   // ever corrected parent accessible's child cache.
-  PRUint32 childCount = mChildren.Count();
+  PRUint32 childCount = mChildren.Length();
   if (childCount == 0) {
     NS_ASSERTION(mAreChildrenInitialized,
                  "Children are stored but not initailzied!");
     return;
   }
 
   for (PRInt32 childIdx = 0; childIdx < childCount; childIdx++) {
-    nsIAccessible *child = GetChildAt(childIdx);
+    nsAccessible *child = GetChildAt(childIdx);
     if (child == aCachedChild)
       break;
   }
 
   NS_ASSERTION(child == aCachedChild,
                "[TestChildCache] cached accessible wasn't found. Wrong accessible tree!");  
 #endif
 }
@@ -3143,44 +3133,41 @@ nsAccessible::GetSiblingAtOffset(PRInt32
 {
   if (IsDefunct()) {
     if (aError)
       *aError = NS_ERROR_FAILURE;
 
     return nsnull;
   }
 
-  nsIAccessible *parent = GetParent();
+  nsAccessible *parent = GetParent();
   if (!parent) {
     if (aError)
       *aError = NS_ERROR_UNEXPECTED;
 
     return nsnull;
   }
 
-  nsRefPtr<nsAccessible> parentAcc =
-    nsAccUtils::QueryObject<nsAccessible>(parent);
-
-  PRInt32 indexInParent = parentAcc->GetIndexOf(this);
+  PRInt32 indexInParent = parent->GetIndexOf(this);
   if (indexInParent == -1) {
     if (aError)
       *aError = NS_ERROR_UNEXPECTED;
 
     return nsnull;
   }
 
   if (aError) {
-    PRInt32 childCount = parentAcc->GetChildCount();
+    PRInt32 childCount = parent->GetChildCount();
     if (indexInParent + aOffset >= childCount) {
       *aError = NS_OK; // fail peacefully
       return nsnull;
     }
   }
 
-  nsIAccessible *child = parentAcc->GetChildAt(indexInParent + aOffset);
+  nsAccessible *child = parent->GetChildAt(indexInParent + aOffset);
   if (aError && !child)
     *aError = NS_ERROR_UNEXPECTED;
 
   return child;
 }
 
 already_AddRefed<nsIAccessible>
 nsAccessible::GetFirstAvailableAccessible(nsIDOMNode *aStartNode)
@@ -3333,38 +3320,34 @@ nsAccessible::GetPositionAndSizeInternal
       role != nsIAccessibleRole::ROLE_RADIOBUTTON &&
       role != nsIAccessibleRole::ROLE_PAGETAB &&
       role != nsIAccessibleRole::ROLE_OPTION &&
       role != nsIAccessibleRole::ROLE_OUTLINEITEM &&
       role != nsIAccessibleRole::ROLE_ROW &&
       role != nsIAccessibleRole::ROLE_GRID_CELL)
     return;
 
+  PRInt32 positionInGroup = 0;
+  PRInt32 setSize = 0;
+
   PRUint32 baseRole = role;
   if (role == nsIAccessibleRole::ROLE_CHECK_MENU_ITEM ||
       role == nsIAccessibleRole::ROLE_RADIO_MENU_ITEM)
     baseRole = nsIAccessibleRole::ROLE_MENUITEM;
 
-  nsCOMPtr<nsIAccessible> parent = GetParent();
+  nsAccessible* parent = GetParent();
   NS_ENSURE_TRUE(parent,);
 
-  // Compute 'posinset' and 'setsize' attributes.
-  PRInt32 positionInGroup = 0;
-  PRInt32 setSize = 0;
-
-  nsCOMPtr<nsIAccessible> sibling, nextSibling;
-  parent->GetFirstChild(getter_AddRefs(sibling));
-  NS_ENSURE_TRUE(sibling,);
-
   PRBool foundCurrent = PR_FALSE;
-  PRUint32 siblingRole, siblingBaseRole;
-  while (sibling) {
-    siblingRole = nsAccUtils::Role(sibling);
-
-    siblingBaseRole = siblingRole;
+  PRInt32 siblingCount = parent->GetChildCount();
+  for (PRInt32 siblingIdx = 0; siblingIdx < siblingCount; siblingIdx++) {
+    nsAccessible* sibling = parent->GetChildAt(siblingIdx);
+
+    PRUint32 siblingRole = siblingRole = nsAccUtils::Role(sibling);
+    PRUint32 siblingBaseRole = siblingRole;
     if (siblingRole == nsIAccessibleRole::ROLE_CHECK_MENU_ITEM ||
         siblingRole == nsIAccessibleRole::ROLE_RADIO_MENU_ITEM)
       siblingBaseRole = nsIAccessibleRole::ROLE_MENUITEM;
 
     // If sibling is visible and has the same base role.
     if (siblingBaseRole == baseRole &&
         !(nsAccUtils::State(sibling) & nsIAccessibleStates::STATE_INVISIBLE)) {
       ++ setSize;
@@ -3379,90 +3362,81 @@ nsAccessible::GetPositionAndSizeInternal
     if (siblingRole == nsIAccessibleRole::ROLE_SEPARATOR) {
       if (foundCurrent) // the our group is ended
         break;
 
       // not our group, continue the searching
       positionInGroup = 0;
       setSize = 0;
     }
-
-    sibling->GetNextSibling(getter_AddRefs(nextSibling));
-    sibling = nextSibling;
   }
 
   *aPosInSet = positionInGroup;
   *aSetSize = setSize;
 }
 
 PRInt32
 nsAccessible::GetLevelInternal()
 {
   PRUint32 role = nsAccUtils::Role(this);
-  nsCOMPtr<nsIAccessible> parent = GetParent();
+  nsAccessible* parent = GetParent();
 
   if (role == nsIAccessibleRole::ROLE_OUTLINEITEM) {
     // Always expose 'level' attribute for 'outlineitem' accessible. The number
     // of nested 'grouping' accessibles containing 'outlineitem' accessible is
     // its level.
     PRInt32 level = 1;
-    nsCOMPtr<nsIAccessible> nextParent;
     while (parent) {
       PRUint32 parentRole = nsAccUtils::Role(parent);
 
       if (parentRole == nsIAccessibleRole::ROLE_OUTLINE)
         break;
       if (parentRole == nsIAccessibleRole::ROLE_GROUPING)
         ++ level;
 
-      parent->GetParent(getter_AddRefs(nextParent));
-      parent.swap(nextParent);
+      parent = parent->GetParent();
     }
 
     return level;
   }
 
   if (role == nsIAccessibleRole::ROLE_LISTITEM) {
     // Expose 'level' attribute on nested lists. We assume nested list is a last
     // child of listitem of parent list. We don't handle the case when nested
     // lists have more complex structure, for example when there are accessibles
     // between parent listitem and nested list.
 
     // Calculate 'level' attribute based on number of parent listitems.
     PRInt32 level = 0;
-    nsCOMPtr<nsIAccessible> nextParent;
 
     while (parent) {
       PRUint32 parentRole = nsAccUtils::Role(parent);
 
       if (parentRole == nsIAccessibleRole::ROLE_LISTITEM)
         ++ level;
       else if (parentRole != nsIAccessibleRole::ROLE_LIST)
         break;
 
-      parent->GetParent(getter_AddRefs(nextParent));
-      parent.swap(nextParent);
+      parent = parent->GetParent();
     }
 
     if (level == 0) {
       // If this listitem is on top of nested lists then expose 'level'
       // attribute.
-      nsCOMPtr<nsIAccessible> parent(GetParent()), sibling, nextSibling;
-      parent->GetFirstChild(getter_AddRefs(sibling));
-
-      while (sibling) {
+      nsAccessible* parent(GetParent());
+      PRInt32 siblingCount = parent->GetChildCount();
+      for (PRInt32 siblingIdx = 0; siblingIdx < siblingCount; siblingIdx++) {
+        nsAccessible* sibling = parent->GetChildAt(siblingIdx);
+
         nsCOMPtr<nsIAccessible> siblingChild;
         sibling->GetLastChild(getter_AddRefs(siblingChild));
         if (nsAccUtils::Role(siblingChild) == nsIAccessibleRole::ROLE_LIST) {
           level = 1;
           break;
         }
-
-        sibling->GetNextSibling(getter_AddRefs(nextSibling));
-        sibling.swap(nextSibling);
       }
     } else {
       ++ level; // level is 1-index based
     }
 
     return level;
   }
 
--- a/accessible/src/base/nsAccessible.h
+++ b/accessible/src/base/nsAccessible.h
@@ -98,21 +98,21 @@ public:
   }
 
 private:
   nsTArray<nsString> mNames;
 };
 
 
 #define NS_ACCESSIBLE_IMPL_CID                          \
-{  /* 81a84b69-de5a-412f-85ff-deb005c5a68d */           \
-  0x81a84b69,                                           \
-  0xde5a,                                               \
-  0x412f,                                               \
-  { 0x85, 0xff, 0xde, 0xb0, 0x05, 0xc5, 0xa6, 0x8d }    \
+{  /* c734df37-7e12-49ec-8983-eea88a186bb8 */           \
+  0xc734df37,                                           \
+  0x7e12,                                               \
+  0x49ec,                                               \
+  { 0x89, 0x83, 0xee, 0xa8, 0x8a, 0x18, 0x6b, 0xb8 }    \
 }
 
 class nsAccessible : public nsAccessNodeWrap, 
                      public nsIAccessible, 
                      public nsIAccessibleHyperLink,
                      public nsIAccessibleSelectable,
                      public nsIAccessibleValue
 {
@@ -223,37 +223,37 @@ public:
    * @param aRoleMapEntry The ARIA nsRoleMapEntry* for the accessible, or 
    *                      nsnull if none.
    */
   virtual void SetRoleMapEntry(nsRoleMapEntry *aRoleMapEntry);
 
   /**
    * Set accessible parent.
    */
-  void SetParent(nsIAccessible *aParent);
+  void SetParent(nsAccessible *aParent);
 
   /**
    * Set the child count to -1 (unknown) and null out cached child pointers.
    * Should be called when accessible tree is changed because document has
    * transformed.
    */
   virtual void InvalidateChildren();
 
   //////////////////////////////////////////////////////////////////////////////
   // Accessible tree traverse methods
 
   /**
    * Return parent accessible.
    */
-  virtual nsIAccessible* GetParent();
+  virtual nsAccessible* GetParent();
 
   /**
    * Return child accessible at the given index.
    */
-  virtual nsIAccessible* GetChildAt(PRUint32 aIndex);
+  virtual nsAccessible* GetChildAt(PRUint32 aIndex);
 
   /**
    * Return child accessible count.
    */
   virtual PRInt32 GetChildCount();
 
   /**
    * Return index of the given child accessible.
@@ -263,22 +263,22 @@ public:
   /**
    * Return index in parent accessible.
    */
   PRInt32 GetIndexInParent();
 
   /**
    * Return parent accessible only if cached.
    */
-  already_AddRefed<nsIAccessible> GetCachedParent();
+  nsAccessible* GetCachedParent();
 
   /**
    * Return first child accessible only if cached.
    */
-  already_AddRefed<nsIAccessible> GetCachedFirstChild();
+  nsAccessible* GetCachedFirstChild();
 
   //////////////////////////////////////////////////////////////////////////////
   // Miscellaneous methods
 
   /**
    * Fire accessible event.
    */
   virtual nsresult FireAccessibleEvent(nsIAccessibleEvent *aAccEvent);
@@ -307,17 +307,17 @@ protected:
   /**
    * Cache accessible children.
    */
   virtual void CacheChildren();
 
   /**
    * Assert if child not in parent's cache.
    */
-  void TestChildCache(nsIAccessible *aCachedChild);
+  void TestChildCache(nsAccessible *aCachedChild);
 
   /**
    * Cache children if necessary. Return true if the accessible is defunct.
    */
   PRBool EnsureChildren();
 
   /**
    * Return sibling accessible at the given offset.
@@ -449,18 +449,18 @@ protected:
    * nsIAccessible::FireAccessibleEvent excepting special cases like we have
    * in xul:tree accessible to lie to AT. Must be overridden in wrap classes.
    *
    * @param aEvent  the accessible event to fire.
    */
   virtual nsresult FirePlatformEvent(nsIAccessibleEvent *aEvent) = 0;
 
   // Data Members
-  nsCOMPtr<nsIAccessible> mParent;
-  nsCOMArray<nsIAccessible> mChildren;
+  nsRefPtr<nsAccessible> mParent;
+  nsTArray<nsRefPtr<nsAccessible> > mChildren;
   PRBool mAreChildrenInitialized;
 
   nsRoleMapEntry *mRoleMapEntry; // Non-null indicates author-supplied role; possibly state & value as well
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsAccessible,
                               NS_ACCESSIBLE_IMPL_CID)
 
--- a/accessible/src/base/nsApplicationAccessible.cpp
+++ b/accessible/src/base/nsApplicationAccessible.cpp
@@ -155,17 +155,17 @@ nsApplicationAccessible::GetStateInterna
 {
   *aState = 0;
   if (aExtraState)
     *aExtraState = 0;
 
   return NS_OK;
 }
 
-nsIAccessible*
+nsAccessible*
 nsApplicationAccessible::GetParent()
 {
   return nsnull;
 }
 
 void
 nsApplicationAccessible::InvalidateChildren()
 {
@@ -202,27 +202,29 @@ nsApplicationAccessible::GetSiblingAtOff
 ////////////////////////////////////////////////////////////////////////////////
 // Public methods
 
 nsresult
 nsApplicationAccessible::AddRootAccessible(nsIAccessible *aRootAccessible)
 {
   NS_ENSURE_ARG_POINTER(aRootAccessible);
 
-  if (!mChildren.AppendObject(aRootAccessible))
+  nsRefPtr<nsAccessible> rootAcc =
+    nsAccUtils::QueryObject<nsAccessible>(aRootAccessible);
+
+  if (!mChildren.AppendElement(rootAcc))
     return NS_ERROR_FAILURE;
 
-  nsRefPtr<nsAccessible> rootAcc = nsAccUtils::QueryAccessible(aRootAccessible);
   rootAcc->SetParent(this);
 
   return NS_OK;
 }
 
 nsresult
 nsApplicationAccessible::RemoveRootAccessible(nsIAccessible *aRootAccessible)
 {
   NS_ENSURE_ARG_POINTER(aRootAccessible);
 
   // It's not needed to void root accessible parent because this method is
   // called on root accessible shutdown and its parent will be cleared
   // properly.
-  return mChildren.RemoveObject(aRootAccessible) ? NS_OK : NS_ERROR_FAILURE;
+  return mChildren.RemoveElement(aRootAccessible) ? NS_OK : NS_ERROR_FAILURE;
 }
--- a/accessible/src/base/nsApplicationAccessible.h
+++ b/accessible/src/base/nsApplicationAccessible.h
@@ -74,17 +74,17 @@ public:
 
   // nsAccessNode
   virtual PRBool IsDefunct();
   virtual nsresult Init();
 
   // nsAccessible
   virtual nsresult GetRoleInternal(PRUint32 *aRole);
   virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
-  virtual nsIAccessible* GetParent();
+  virtual nsAccessible* GetParent();
 
   virtual void InvalidateChildren();
 
   // nsApplicationAccessible
   virtual nsresult AddRootAccessible(nsIAccessible *aRootAccWrap);
   virtual nsresult RemoveRootAccessible(nsIAccessible *aRootAccWrap);
 
 protected:
--- a/accessible/src/base/nsDocAccessible.cpp
+++ b/accessible/src/base/nsDocAccessible.cpp
@@ -341,19 +341,18 @@ nsDocAccessible::GetStateInternal(PRUint
 nsresult
 nsDocAccessible::GetARIAState(PRUint32 *aState, PRUint32 *aExtraState)
 {
   // Combine with states from outer doc
   NS_ENSURE_ARG_POINTER(aState);
   nsresult rv = nsAccessible::GetARIAState(aState, aExtraState);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  nsRefPtr<nsAccessible> parent = nsAccUtils::QueryAccessible(mParent);
-  if (parent)  // Allow iframe/frame etc. to have final state override via ARIA
-    return parent->GetARIAState(aState, aExtraState);
+  if (mParent)  // Allow iframe/frame etc. to have final state override via ARIA
+    return mParent->GetARIAState(aState, aExtraState);
 
   return rv;
 }
 
 NS_IMETHODIMP
 nsDocAccessible::GetAttributes(nsIPersistentProperties **aAttributes)
 {
   nsAccessible::GetAttributes(aAttributes);
@@ -549,23 +548,23 @@ NS_IMETHODIMP nsDocAccessible::GetAssoci
 NS_IMETHODIMP nsDocAccessible::GetCachedAccessNode(void *aUniqueID, nsIAccessNode **aAccessNode)
 {
   GetCacheEntry(mAccessNodeCache, aUniqueID, aAccessNode); // Addrefs for us
 #ifdef DEBUG_A11Y
   // All cached accessible nodes should be in the parent
   // It will assert if not all the children were created
   // when they were first cached, and no invalidation
   // ever corrected parent accessible's child cache.
-  nsCOMPtr<nsIAccessible> accessible = do_QueryInterface(*aAccessNode);
-  nsRefPtr<nsAccessible> acc = nsAccUtils::QueryAccessible(accessible);
+  nsRefPtr<nsAccessible> acc =
+    nsAccUtils::QueryObject<nsAccessible>(*aAccessNode);
+
   if (acc) {
-    nsCOMPtr<nsIAccessible> parent = acc->GetCachedParent();
-    nsRefPtr<nsAccessible> parentAcc(nsAccUtils::QueryAccessible(parent));
-    if (parentAcc)
-      parentAcc->TestChildCache(accessible);
+    nsAccessible* parent(acc->GetCachedParent());
+    if (parent)
+      parent->TestChildCache(acc);
   }
 #endif
   return NS_OK;
 }
 
 // nsDocAccessible public method
 void
 nsDocAccessible::CacheAccessNode(void *aUniqueID, nsIAccessNode *aAccessNode)
@@ -875,17 +874,17 @@ nsDocAccessible::FireDocLoadEvents(PRUin
     return;
 
   nsCOMPtr<nsIDocShellTreeItem> sameTypeRoot;
   treeItem->GetSameTypeRootTreeItem(getter_AddRefs(sameTypeRoot));
 
   if (isFinished) {
     // Need to wait until scrollable view is available
     AddScrollListener();
-    nsRefPtr<nsAccessible> acc(nsAccUtils::QueryAccessible(GetParent()));
+    nsRefPtr<nsAccessible> acc(GetParent());
     if (acc) {
       // Make the parent forget about the old document as a child
       acc->InvalidateChildren();
     }
 
     if (sameTypeRoot != treeItem) {
       // Fire show/hide events to indicate frame/iframe content is new, rather than
       // doc load event which causes screen readers to act is if entire page is reloaded
@@ -1416,17 +1415,17 @@ void
 nsDocAccessible::ParentChainChanged(nsIContent *aContent)
 {
 }
 
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccessible
 
-nsIAccessible*
+nsAccessible*
 nsDocAccessible::GetParent()
 {
   if (IsDefunct())
     return nsnull;
 
   if (mParent)
     return mParent;
 
@@ -1439,17 +1438,19 @@ nsDocAccessible::GetParent()
   if (ownerNode) {
     nsCOMPtr<nsIAccessibilityService> accService = GetAccService();
     if (accService) {
       // XXX aaronl: ideally we would traverse the presshell chain. Since
       // there's no easy way to do that, we cheat and use the document
       // hierarchy. GetAccessibleFor() is bad because it doesn't support our
       // concept of multiple presshells per doc.
       // It should be changed to use GetAccessibleInWeakShell()
-      accService->GetAccessibleFor(ownerNode, getter_AddRefs(mParent));
+      nsCOMPtr<nsIAccessible> parent;
+      accService->GetAccessibleFor(ownerNode, getter_AddRefs(parent));
+      mParent = nsAccUtils::QueryObject<nsAccessible>(parent);
     }
   }
 
   NS_ASSERTION(mParent, "No parent for not root document accessible!");
   return mParent;
 }
 
 
@@ -1926,18 +1927,17 @@ void nsDocAccessible::RefreshNodes(nsIDO
         nsAccUtils::FireAccEvent(nsIAccessibleEvent::EVENT_MENUPOPUP_END,
                                  accessible);
       }
     }
     nsRefPtr<nsAccessible> acc = nsAccUtils::QueryAccessible(accessible);
 
     // We only need to shutdown the accessibles here if one of them has been
     // created.
-    nsCOMPtr<nsIAccessible> childAccessible = acc->GetCachedFirstChild();
-    if (childAccessible) {
+    if (acc->GetCachedFirstChild()) {
       nsCOMPtr<nsIArray> children;
       // use GetChildren() to fetch children at one time, instead of using
       // GetNextSibling(), because after we shutdown the first child,
       // mNextSibling will be set null.
       accessible->GetChildren(getter_AddRefs(children));
       PRUint32 childCount =0;
       if (children)
         children->GetLength(&childCount);
--- a/accessible/src/base/nsDocAccessible.h
+++ b/accessible/src/base/nsDocAccessible.h
@@ -107,17 +107,17 @@ public:
   virtual PRBool IsDefunct();
 
   // nsAccessible
   virtual nsresult GetRoleInternal(PRUint32 *aRole);
   virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
   virtual nsresult GetARIAState(PRUint32 *aState, PRUint32 *aExtraState);
 
   virtual void SetRoleMapEntry(nsRoleMapEntry* aRoleMapEntry);
-  virtual nsIAccessible* GetParent();
+  virtual nsAccessible* GetParent();
 
   // nsIAccessibleText
   NS_IMETHOD GetAssociatedEditor(nsIEditor **aEditor);
 
   // nsDocAccessible
 
   /**
    * Non-virtual method to fire a delayed event after a 0 length timeout.
--- a/accessible/src/base/nsOuterDocAccessible.cpp
+++ b/accessible/src/base/nsOuterDocAccessible.cpp
@@ -122,17 +122,17 @@ nsOuterDocAccessible::CacheChildren()
   nsCOMPtr<nsIAccessible> innerAccessible;
   nsCOMPtr<nsIAccessibilityService> accService = GetAccService();
   accService->GetAccessibleFor(innerNode, getter_AddRefs(innerAccessible));
   nsRefPtr<nsAccessible> innerAcc(nsAccUtils::QueryAccessible(innerAccessible));
   if (!innerAcc)
     return;
 
   // Success getting inner document as first child -- now we cache it.
-  mChildren.AppendObject(innerAccessible);
+  mChildren.AppendElement(innerAcc);
   innerAcc->SetParent(this);
 }
 
 nsresult
 nsOuterDocAccessible::GetAttributesInternal(nsIPersistentProperties *aAttributes)
 {
   nsAutoString tag;
   aAttributes->GetStringProperty(NS_LITERAL_CSTRING("tag"), tag);
--- a/accessible/src/base/nsRootAccessible.cpp
+++ b/accessible/src/base/nsRootAccessible.cpp
@@ -1057,17 +1057,17 @@ nsRootAccessible::GetRelationByType(PRUi
   }
 
   return NS_OK;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccessible
 
-nsIAccessible*
+nsAccessible*
 nsRootAccessible::GetParent()
 {
   // Parent has been setted in nsApplicationAccesible::AddRootAccessible()
   // when root accessible was intialized.
   return mParent;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
--- a/accessible/src/base/nsRootAccessible.h
+++ b/accessible/src/base/nsRootAccessible.h
@@ -82,17 +82,17 @@ public:
 
   // nsAccessNode
   virtual nsresult Init();
   virtual nsresult Shutdown();
 
   // nsAccessible
   virtual nsresult GetRoleInternal(PRUint32 *aRole);
   virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
-  virtual nsIAccessible* GetParent();
+  virtual nsAccessible* GetParent();
 
   // nsDocAccessible
   virtual void FireDocLoadEvents(PRUint32 aEventType);
 
   // nsRootAccessible
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_ROOTACCESSIBLE_IMPL_CID)
 
     /**
--- a/accessible/src/html/nsHTMLFormControlAccessible.cpp
+++ b/accessible/src/html/nsHTMLFormControlAccessible.cpp
@@ -668,29 +668,30 @@ nsHTMLLegendAccessible::GetRelationByTyp
                                           nsIAccessibleRelation **aRelation)
 {
   nsresult rv = nsHyperTextAccessibleWrap::
     GetRelationByType(aRelationType, aRelation);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (aRelationType == nsIAccessibleRelation::RELATION_LABEL_FOR) {
     // Look for groupbox parent
-    nsCOMPtr<nsIAccessible> groupboxAccessible = GetParent();
-    if (nsAccUtils::Role(groupboxAccessible) == nsIAccessibleRole::ROLE_GROUPING) {
+    nsAccessible* groupbox = GetParent();
+
+    if (nsAccUtils::Role(groupbox) == nsIAccessibleRole::ROLE_GROUPING) {
       // XXX: if group box exposes more than one relation of the given type
       // then we fail.
       nsCOMPtr<nsIAccessible> testLabelAccessible =
-        nsRelUtils::GetRelatedAccessible(groupboxAccessible,
+        nsRelUtils::GetRelatedAccessible(groupbox,
                                          nsIAccessibleRelation::RELATION_LABELLED_BY);
 
       if (testLabelAccessible == this) {
         // We're the first child of the parent groupbox, see
         // nsHTMLGroupboxAccessible::GetRelationByType().
         return nsRelUtils::
-          AddTarget(aRelationType, aRelation, groupboxAccessible);
+          AddTarget(aRelationType, aRelation, groupbox);
       }
     }
   }
 
   return NS_OK;
 }
 
 nsresult
--- a/accessible/src/html/nsHTMLImageAccessible.cpp
+++ b/accessible/src/html/nsHTMLImageAccessible.cpp
@@ -168,18 +168,18 @@ nsHTMLImageAccessible::CacheChildren()
   nsCOMPtr<nsIAccessible> areaAccessible;
   nsRefPtr<nsAccessible> areaAcc;
 
   for (PRUint32 areaIdx = 0; areaIdx < areaCount; areaIdx++) {
     areaAccessible = GetAreaAccessible(mapAreas, areaIdx);
     if (!areaAccessible)
       return;
 
-    mChildren.AppendObject(areaAccessible);
     areaAcc = nsAccUtils::QueryObject<nsAccessible>(areaAccessible);
+    mChildren.AppendElement(areaAcc);
     areaAcc->SetParent(this);
   }
 }
 
 NS_IMETHODIMP
 nsHTMLImageAccessible::GetNumActions(PRUint8 *aNumActions)
 {
   NS_ENSURE_ARG_POINTER(aNumActions);
--- a/accessible/src/html/nsHTMLSelectAccessible.cpp
+++ b/accessible/src/html/nsHTMLSelectAccessible.cpp
@@ -398,20 +398,20 @@ nsHTMLSelectListAccessible::CacheOptSibl
 
       // Get an accessible for option or optgroup and cache it.
       nsCOMPtr<nsIDOMNode> childNode(do_QueryInterface(childContent));
 
       nsCOMPtr<nsIAccessible> accessible;
       GetAccService()->GetAccessibleInWeakShell(childNode, mWeakShell,
                                                 getter_AddRefs(accessible));
       if (accessible) {
-        mChildren.AppendObject(accessible);
-
         nsRefPtr<nsAccessible> acc =
           nsAccUtils::QueryObject<nsAccessible>(accessible);
+
+        mChildren.AppendElement(acc);
         acc->SetParent(this);
       }
 
       // Deep down into optgroup element.
       if (tag == nsAccessibilityAtoms::optgroup)
         CacheOptSiblings(childContent);
     }
   }
@@ -440,17 +440,20 @@ nsHyperTextAccessibleWrap(aDOMNode, aShe
     if (parentAccessible) {
       if (nsAccUtils::RoleInternal(parentAccessible) ==
           nsIAccessibleRole::ROLE_COMBOBOX) {
         nsCOMPtr<nsIAccessible> comboAccessible(parentAccessible);
         comboAccessible->GetLastChild(getter_AddRefs(parentAccessible));
       }
     }
   }
-  SetParent(parentAccessible);
+
+  nsRefPtr<nsAccessible> parentAcc =
+    nsAccUtils::QueryObject<nsAccessible>(parentAccessible);
+  SetParent(parentAcc);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsHTMLSelectOptionAccessible: nsAccessible public
 
 nsresult
 nsHTMLSelectOptionAccessible::GetRoleInternal(PRUint32 *aRole)
 {
@@ -580,22 +583,22 @@ nsHTMLSelectOptionAccessible::GetStateIn
        }
     }
   }
   else {
     // XXX list frames are weird, don't rely on nsAccessible's general
     // visibility implementation unless they get reimplemented in layout
     *aState &= ~nsIAccessibleStates::STATE_OFFSCREEN;
     // <select> is not collapsed: compare bounds to calculate STATE_OFFSCREEN
-    nsCOMPtr<nsIAccessible> listAccessible = GetParent();
-    if (listAccessible) {
+    nsAccessible* listAcc = GetParent();
+    if (listAcc) {
       PRInt32 optionX, optionY, optionWidth, optionHeight;
       PRInt32 listX, listY, listWidth, listHeight;
       GetBounds(&optionX, &optionY, &optionWidth, &optionHeight);
-      listAccessible->GetBounds(&listX, &listY, &listWidth, &listHeight);
+      listAcc->GetBounds(&listX, &listY, &listWidth, &listHeight);
       if (optionY < listY || optionY + optionHeight > listY + listHeight) {
         *aState |= nsIAccessibleStates::STATE_OFFSCREEN;
       }
     }
   }
  
   return NS_OK;
 }
@@ -667,20 +670,20 @@ NS_IMETHODIMP nsHTMLSelectOptionAccessib
 NS_IMETHODIMP nsHTMLSelectOptionAccessible::DoAction(PRUint8 index)
 {
   if (index == eAction_Select) {   // default action
     nsCOMPtr<nsIDOMHTMLOptionElement> newHTMLOption(do_QueryInterface(mDOMNode));
     if (!newHTMLOption) 
       return NS_ERROR_FAILURE;
     // Clear old selection
     nsCOMPtr<nsIDOMNode> oldHTMLOptionNode, selectNode;
-    nsCOMPtr<nsIAccessible> parent(GetParent());
-    nsCOMPtr<nsIAccessNode> accessNode(do_QueryInterface(parent));
-    NS_ASSERTION(accessNode, "Unable to QI to nsIAccessNode");
-    accessNode->GetDOMNode(getter_AddRefs(selectNode));
+    nsAccessible* parent = GetParent();
+    NS_ASSERTION(parent, "No parent!");
+
+    parent->GetDOMNode(getter_AddRefs(selectNode));
     GetFocusedOptionNode(selectNode, getter_AddRefs(oldHTMLOptionNode));
     nsCOMPtr<nsIDOMHTMLOptionElement> oldHTMLOption(do_QueryInterface(oldHTMLOptionNode));
     if (oldHTMLOption)
       oldHTMLOption->SetSelected(PR_FALSE);
     // Set new selection
     newHTMLOption->SetSelected(PR_TRUE);
 
     // If combo box, and open, close it
@@ -948,17 +951,17 @@ nsHTMLComboboxAccessible::CacheChildren(
     mListAccessible = 
       new nsHTMLComboboxListAccessible(mParent, mDOMNode, mWeakShell);
     if (!mListAccessible)
       return;
 
     mListAccessible->Init();
   }
 
-  mChildren.AppendObject(mListAccessible);
+  mChildren.AppendElement(mListAccessible);
   mListAccessible->SetParent(this);
 }
 
 nsresult
 nsHTMLComboboxAccessible::Shutdown()
 {
   nsAccessibleWrap::Shutdown();
 
@@ -1165,21 +1168,21 @@ NS_IMETHODIMP nsHTMLComboboxListAccessib
 /**
   * Gets the bounds for the areaFrame.
   *     Walks the Frame tree and checks for proper frames.
   */
 void nsHTMLComboboxListAccessible::GetBoundsRect(nsRect& aBounds, nsIFrame** aBoundingFrame)
 {
   *aBoundingFrame = nsnull;
 
-  nsCOMPtr<nsIAccessible> comboAccessible = GetParent();
-  if (!comboAccessible)
+  nsAccessible* comboAcc = GetParent();
+  if (!comboAcc)
     return;
 
-  if (0 == (nsAccUtils::State(comboAccessible) & nsIAccessibleStates::STATE_COLLAPSED)) {
+  if (0 == (nsAccUtils::State(comboAcc) & nsIAccessibleStates::STATE_COLLAPSED)) {
     nsHTMLSelectListAccessible::GetBoundsRect(aBounds, aBoundingFrame);
     return;
   }
    // get our first option
   nsCOMPtr<nsIDOMNode> child;
   mDOMNode->GetFirstChild(getter_AddRefs(child));
 
   // now get its frame
@@ -1193,13 +1196,13 @@ void nsHTMLComboboxListAccessible::GetBo
     return;
   }
 
   *aBoundingFrame = frame->GetParent();
   aBounds = (*aBoundingFrame)->GetRect();
 }
 
 // nsHTMLComboboxListAccessible. nsAccessible public mehtod
-nsIAccessible*
+nsAccessible*
 nsHTMLComboboxListAccessible::GetParent()
 {
   return mParent;
 }
--- a/accessible/src/html/nsHTMLSelectAccessible.h
+++ b/accessible/src/html/nsHTMLSelectAccessible.h
@@ -266,12 +266,12 @@ public:
   NS_IMETHOD GetUniqueID(void **aUniqueID);
 
   // nsAccessNode
   virtual nsIFrame* GetFrame();
 
   // nsAccessible
   virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
   virtual void GetBoundsRect(nsRect& aBounds, nsIFrame** aBoundingFrame);
-  virtual nsIAccessible* GetParent();
+  virtual nsAccessible* GetParent();
 };
 
 #endif
--- a/accessible/src/html/nsHTMLTableAccessible.cpp
+++ b/accessible/src/html/nsHTMLTableAccessible.cpp
@@ -456,30 +456,30 @@ NS_IMPL_ISUPPORTS_INHERITED2(nsHTMLTable
 // nsHTMLTableAccessible: nsAccessible implementation
 
 void
 nsHTMLTableAccessible::CacheChildren()
 {
   nsAccessible::CacheChildren();
 
   // Move caption accessible so that it's the first child.
-  PRInt32 length = mChildren.Count();
+  PRInt32 length = mChildren.Length();
   for (PRInt32 idx = 0; idx < length; idx++) {
     // Check for the first caption, because nsAccessibilityService ensures we
     // don't create accessibles for the other captions, since only the first is
     // actually visible.
 
-    nsIAccessible* child = mChildren.ObjectAt(idx);
+    nsAccessible* child = mChildren.ElementAt(idx);
     if (nsAccUtils::Role(child) == nsIAccessibleRole::ROLE_CAPTION) {
       if (idx == 0)
         break;
 
-      nsCOMPtr<nsIAccessible> tmp = mChildren.ObjectAt(0);
-      mChildren.ReplaceObjectAt(child, 0);
-      mChildren.ReplaceObjectAt(tmp, idx);
+      nsRefPtr<nsAccessible> tmp = mChildren[0];
+      mChildren[0] = child;
+      mChildren[idx] = tmp;
       break;
     }
   }
 }
 
 nsresult
 nsHTMLTableAccessible::GetRoleInternal(PRUint32 *aResult)
 {
--- a/accessible/src/html/nsHTMLTextAccessible.cpp
+++ b/accessible/src/html/nsHTMLTextAccessible.cpp
@@ -265,17 +265,17 @@ NS_IMETHODIMP nsHTMLLIAccessible::GetBou
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsHTMLLIAccessible: nsAccessible protected
 
 void
 nsHTMLLIAccessible::CacheChildren()
 {
   if (mBulletAccessible) {
-    mChildren.AppendObject(mBulletAccessible);
+    mChildren.AppendElement(mBulletAccessible);
     mBulletAccessible->SetParent(this);
   }
 
   // Cache children from subtree.
   nsAccessibleWrap::CacheChildren();
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -338,17 +338,17 @@ nsHTMLListBulletAccessible::AppendTextTo
   PRUint32 maxLength = mBulletText.Length() - aStartOffset;
   if (aLength > maxLength) {
     aLength = maxLength;
   }
   aText += nsDependentSubstring(mBulletText, aStartOffset, aLength);
   return NS_OK;
 }
 
-nsIAccessible*
+nsAccessible*
 nsHTMLListBulletAccessible::GetParent()
 {
   return mParent;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsHTMLListAccessible
 ////////////////////////////////////////////////////////////////////////////////
--- a/accessible/src/html/nsHTMLTextAccessible.h
+++ b/accessible/src/html/nsHTMLTextAccessible.h
@@ -111,17 +111,17 @@ public:
   virtual nsresult Shutdown();
 
   // nsAccessible
   virtual nsresult GetRoleInternal(PRUint32 *aRole);
   virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
   virtual nsresult AppendTextTo(nsAString& aText, PRUint32 aStartOffset,
                                 PRUint32 aLength);
 
-  virtual nsIAccessible* GetParent();
+  virtual nsAccessible* GetParent();
 
 protected:
   // XXX: Ideally we'd get the bullet text directly from the bullet frame via
   // nsBulletFrame::GetListItemText(), but we'd need an interface for getting
   // text from contentless anonymous frames. Perhaps something like
   // nsIAnonymousFrame::GetText() ? However, in practice storing the bullet text
   // here should not be a problem if we invalidate the right parts of
   // the accessibility cache when mutation events occur.
--- a/accessible/src/html/nsHyperTextAccessible.cpp
+++ b/accessible/src/html/nsHyperTextAccessible.cpp
@@ -227,20 +227,20 @@ nsHyperTextAccessible::CacheChildren()
   nsCOMPtr<nsIDOMNode> editorRootDOMNode = do_QueryInterface(editorRoot);
   if (!editorRootDOMNode)
     return;
 
   nsAccessibleTreeWalker walker(mWeakShell, editorRootDOMNode, PR_TRUE);
 
   walker.GetFirstChild();
   while (walker.mState.accessible) {
-    mChildren.AppendObject(walker.mState.accessible);
-
     nsRefPtr<nsAccessible> acc =
       nsAccUtils::QueryObject<nsAccessible>(walker.mState.accessible);
+
+    mChildren.AppendElement(acc);
     acc->SetParent(this);
 
     walker.GetNextSibling();
   }
 }
 
 // Substring must be entirely within the same text node
 nsIntRect nsHyperTextAccessible::GetBoundsForString(nsIFrame *aFrame, PRUint32 aStartRenderedOffset,
@@ -854,17 +854,17 @@ nsHyperTextAccessible::GetRelativeOffset
   NS_ENSURE_SUCCESS(rv, -1);
 
   if (!finalAccessible && aDirection == eDirPrevious) {
     // If we reached the end during search, this means we didn't find the DOM point
     // and we're actually at the start of the paragraph
     hyperTextOffset = 0;
   }  
   else if (aAmount == eSelectBeginLine) {
-    nsIAccessible *firstChild = mChildren.SafeObjectAt(0);
+    nsAccessible *firstChild = mChildren.SafeElementAt(0, nsnull);
     // For line selection with needsStart, set start of line exactly to line break
     if (pos.mContentOffset == 0 && firstChild &&
         nsAccUtils::Role(firstChild) == nsIAccessibleRole::ROLE_STATICTEXT &&
         nsAccUtils::TextLength(firstChild) == hyperTextOffset) {
       // XXX Bullet hack -- we should remove this once list bullets use anonymous content
       hyperTextOffset = 0;
     }
     if (!aNeedsStart && hyperTextOffset > 0) {
--- a/accessible/src/mac/nsAccessibleWrap.h
+++ b/accessible/src/mac/nsAccessibleWrap.h
@@ -100,25 +100,23 @@ class nsAccessibleWrap : public nsAccess
     virtual nsresult FirePlatformEvent(nsIAccessibleEvent *aEvent);
 
     PRBool AncestorIsFlat() {
       // we don't create a native object if we're child of a "flat" accessible; for example, on OS X buttons 
       // shouldn't have any children, because that makes the OS confused. 
       //
       // to maintain a scripting environment where the XPCOM accessible hierarchy look the same 
       // on all platforms, we still let the C++ objects be created though.
-      
-      nsCOMPtr<nsIAccessible> curParent = GetParent();
-      while (curParent) {
-        if (nsAccUtils::MustPrune(curParent))
+
+      nsAccessible* parent(GetParent());
+      while (parent) {
+        if (nsAccUtils::MustPrune(parent))
           return PR_TRUE;
 
-        nsCOMPtr<nsIAccessible> newParent;
-        curParent->GetParent(getter_AddRefs(newParent));
-        curParent.swap(newParent);
+        parent = parent->GetParent();
       }
       // no parent was flat
       return PR_FALSE;
     }
 
     // Wrapper around our native object.
     AccessibleWrapper *mNativeWrapper;
 };
--- a/accessible/src/mac/nsAccessibleWrap.mm
+++ b/accessible/src/mac/nsAccessibleWrap.mm
@@ -295,18 +295,17 @@ nsAccessibleWrap::GetUnignoredChildren(n
       // simply add the element, since it's not ignored.
       aChildrenArray.AppendElement(childWrap);
   }
 }
 
 already_AddRefed<nsIAccessible>
 nsAccessibleWrap::GetUnignoredParent()
 {
-  nsCOMPtr<nsIAccessible> parent(GetParent());
-  nsAccessibleWrap *parentWrap = static_cast<nsAccessibleWrap*>(parent.get());
+  nsAccessibleWrap *parentWrap = static_cast<nsAccessibleWrap*>(GetParent());
   if (!parentWrap)
     return nsnull;
     
   // recursively return the parent, until we find one that is not ignored.
   if (parentWrap->IsIgnored())
     return parentWrap->GetUnignoredParent();
   
   nsIAccessible *outValue = nsnull;
--- a/accessible/src/msaa/nsAccessibleWrap.cpp
+++ b/accessible/src/msaa/nsAccessibleWrap.cpp
@@ -232,22 +232,24 @@ STDMETHODIMP nsAccessibleWrap::get_accPa
     }
 
     if (hwnd && SUCCEEDED(AccessibleObjectFromWindow(hwnd, OBJID_WINDOW, IID_IAccessible,
                                               (void**)ppdispParent))) {
       return S_OK;
     }
   }
 
-  nsCOMPtr<nsIAccessible> xpParentAccessible(GetParent());
-  NS_ASSERTION(xpParentAccessible, "No parent accessible where we're not direct child of window");
-  if (!xpParentAccessible) {
+  nsAccessible* xpParentAcc = GetParent();
+  NS_ASSERTION(xpParentAcc,
+               "No parent accessible where we're not direct child of window");
+
+  if (!xpParentAcc)
     return E_UNEXPECTED;
-  }
-  *ppdispParent = NativeAccessible(xpParentAccessible);
+
+  *ppdispParent = NativeAccessible(xpParentAcc);
 
 } __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return S_OK;
 }
 
 STDMETHODIMP nsAccessibleWrap::get_accChildCount( long __RPC_FAR *pcountChildren)
 {
 __try {
@@ -273,21 +275,20 @@ STDMETHODIMP nsAccessibleWrap::get_accCh
     return E_FAIL;
 
   if (varChild.lVal == CHILDID_SELF) {
     *ppdispChild = static_cast<IDispatch*>(this);
     AddRef();
     return S_OK;
   }
 
-  nsCOMPtr<nsIAccessible> childAccessible;
   if (!nsAccUtils::MustPrune(this)) {
-    GetChildAt(varChild.lVal - 1, getter_AddRefs(childAccessible));
-    if (childAccessible) {
-      *ppdispChild = NativeAccessible(childAccessible);
+    nsAccessible* child = GetChildAt(varChild.lVal - 1);
+    if (child) {
+      *ppdispChild = NativeAccessible(child);
     }
   }
 } __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
 
   return (*ppdispChild)? S_OK: E_FAIL;
 }
 
 STDMETHODIMP nsAccessibleWrap::get_accName(
@@ -478,18 +479,17 @@ STDMETHODIMP nsAccessibleWrap::get_accRo
   msaaRole = gWindowsRoleMap[xpRole].msaaRole;
   NS_ASSERTION(gWindowsRoleMap[nsIAccessibleRole::ROLE_LAST_ENTRY].msaaRole == ROLE_WINDOWS_LAST_ENTRY,
                "MSAA role map skewed");
 
   // Special case, if there is a ROLE_ROW inside of a ROLE_TREE_TABLE, then call the MSAA role
   // a ROLE_OUTLINEITEM for consistency and compatibility.
   // We need this because ARIA has a role of "row" for both grid and treegrid
   if (xpRole == nsIAccessibleRole::ROLE_ROW) {
-    nsCOMPtr<nsIAccessible> parent = GetParent();
-    if (nsAccUtils::Role(parent) == nsIAccessibleRole::ROLE_TREE_TABLE)
+    if (nsAccUtils::Role(GetParent()) == nsIAccessibleRole::ROLE_TREE_TABLE)
       msaaRole = ROLE_SYSTEM_OUTLINEITEM;
   }
   
   // -- Try enumerated role
   if (msaaRole != USE_ROLE_STRING) {
     pvarRole->vt = VT_I4;
     pvarRole->lVal = msaaRole;  // Normal enumerated role
     return S_OK;
@@ -1097,17 +1097,17 @@ nsAccessibleWrap::Next(ULONG aNumElement
 
   if (mEnumVARIANTPosition == kIEnumVariantDisconnected)
     return CO_E_OBJNOTCONNECTED;
 
   PRUint32 numElementsFetched = 0;
   for (; numElementsFetched < aNumElementsRequested;
        numElementsFetched++, mEnumVARIANTPosition++) {
 
-    nsIAccessible* accessible = GetChildAt(mEnumVARIANTPosition);
+    nsAccessible* accessible = GetChildAt(mEnumVARIANTPosition);
     if (!accessible)
       break;
 
     VariantInit(&aPVar[numElementsFetched]);
 
     aPVar[numElementsFetched].pdispVal = NativeAccessible(accessible);
     aPVar[numElementsFetched].vt = VT_DISPATCH;
   }
@@ -1281,18 +1281,17 @@ nsAccessibleWrap::role(long *aRole)
   NS_ASSERTION(gWindowsRoleMap[nsIAccessibleRole::ROLE_LAST_ENTRY].ia2Role == ROLE_WINDOWS_LAST_ENTRY,
                "MSAA role map skewed");
 
   *aRole = gWindowsRoleMap[xpRole].ia2Role;
 
   // Special case, if there is a ROLE_ROW inside of a ROLE_TREE_TABLE, then call
   // the IA2 role a ROLE_OUTLINEITEM.
   if (xpRole == nsIAccessibleRole::ROLE_ROW) {
-    nsCOMPtr<nsIAccessible> parent = GetParent();
-    if (nsAccUtils::Role(parent) == nsIAccessibleRole::ROLE_TREE_TABLE)
+    if (nsAccUtils::Role(GetParent()) == nsIAccessibleRole::ROLE_TREE_TABLE)
       *aRole = ROLE_SYSTEM_OUTLINEITEM;
   }
 
   return S_OK;
 
 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return E_FAIL;
 }
--- a/accessible/src/msaa/nsHTMLWin32ObjectAccessible.cpp
+++ b/accessible/src/msaa/nsHTMLWin32ObjectAccessible.cpp
@@ -95,21 +95,18 @@ nsHTMLWin32ObjectOwnerAccessible::GetSta
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsHTMLWin32ObjectOwnerAccessible: nsAccessible protected implementation
 
 void
 nsHTMLWin32ObjectOwnerAccessible::CacheChildren()
 {
   if (mNativeAccessible) {
-    mChildren.AppendObject(mNativeAccessible);
-
-    nsRefPtr<nsAccessible> nativeAcc =
-      nsAccUtils::QueryObject<nsAccessible>(mNativeAccessible);
-    nativeAcc->SetParent(this);
+    mChildren.AppendElement(mNativeAccessible);
+    mNativeAccessible->SetParent(this);
   }
 }
 
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsHTMLWin32ObjectAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
--- a/accessible/src/msaa/nsHTMLWin32ObjectAccessible.h
+++ b/accessible/src/msaa/nsHTMLWin32ObjectAccessible.h
@@ -64,17 +64,17 @@ public:
   virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
 
 protected:
 
   // nsAccessible
   virtual void CacheChildren();
 
   void* mHwnd;
-  nsCOMPtr<nsIAccessible> mNativeAccessible;
+  nsRefPtr<nsAccessible> mNativeAccessible;
 };
 
 /**
   * This class is used only internally, we never! send out an IAccessible linked
   *   back to this object. This class is used to represent a plugin object when
   *   referenced as a child or sibling of another nsAccessible node. We need only
   *   a limited portion of the nsIAccessible interface implemented here. The
   *   in depth accessible information will be returned by the actual IAccessible
--- a/accessible/src/xforms/nsXFormsAccessible.cpp
+++ b/accessible/src/xforms/nsXFormsAccessible.cpp
@@ -131,18 +131,18 @@ nsXFormsAccessible::CacheSelectChildren(
     children->Item(index, getter_AddRefs(child));
     if (!child)
       continue;
 
     accService->GetAttachedAccessibleFor(child, getter_AddRefs(accessible));
     if (!accessible)
       continue;
 
-    mChildren.AppendObject(accessible);
     acc = nsAccUtils::QueryObject<nsAccessible>(accessible);
+    mChildren.AppendElement(acc);
     acc->SetParent(this);
   }
 }
 
 // nsIAccessible
 
 NS_IMETHODIMP
 nsXFormsAccessible::GetValue(nsAString& aValue)
--- a/accessible/src/xul/nsXULColorPickerAccessible.cpp
+++ b/accessible/src/xul/nsXULColorPickerAccessible.cpp
@@ -170,20 +170,20 @@ nsXULColorPickerAccessible::CacheChildre
   nsAccessibleTreeWalker walker(mWeakShell, mDOMNode, PR_TRUE);
   walker.GetFirstChild();
 
   while (walker.mState.accessible) {
     PRUint32 role = nsAccUtils::Role(walker.mState.accessible);
 
     // Get an accessbile for menupopup or panel elements.
     if (role == nsIAccessibleRole::ROLE_ALERT) {
-      mChildren.AppendObject(walker.mState.accessible);
-      
       nsRefPtr<nsAccessible> menupopupAcc =
         nsAccUtils::QueryObject<nsAccessible>(walker.mState.accessible);
+
+      mChildren.AppendElement(menupopupAcc);
       menupopupAcc->SetParent(this);
 
       return;
     }
 
     walker.GetNextSibling();
   }
 }
--- a/accessible/src/xul/nsXULFormControlAccessible.cpp
+++ b/accessible/src/xul/nsXULFormControlAccessible.cpp
@@ -224,27 +224,27 @@ nsXULButtonAccessible::CacheChildren()
     }
 
     walker.GetNextSibling();
   }
 
   if (!menupopupAccessible)
     return;
 
-  mChildren.AppendObject(menupopupAccessible);
-
   nsRefPtr<nsAccessible> menupopupAcc =
     nsAccUtils::QueryObject<nsAccessible>(menupopupAccessible);
+
+  mChildren.AppendElement(menupopupAcc);
   menupopupAcc->SetParent(this);
 
   if (buttonAccessible) {
-    mChildren.AppendObject(buttonAccessible);
-
     nsRefPtr<nsAccessible> buttonAcc =
       nsAccUtils::QueryObject<nsAccessible>(buttonAccessible);
+
+    mChildren.AppendElement(buttonAcc);
     buttonAcc->SetParent(this);
   }
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsXULButtonAccessible protected
 
 PRBool
@@ -771,49 +771,48 @@ nsXULToolbarButtonAccessible::nsXULToolb
 nsXULButtonAccessible(aNode, aShell)
 {
 }
 
 void
 nsXULToolbarButtonAccessible::GetPositionAndSizeInternal(PRInt32 *aPosInSet,
                                                          PRInt32 *aSetSize)
 {
-  nsCOMPtr<nsIAccessible> parent(GetParent());
   PRInt32 setSize = 0;
   PRInt32 posInSet = 0;
 
-  if (parent) {
-    nsCOMPtr<nsIAccessible> sibling;
-    nsCOMPtr<nsIAccessible> tempSibling;
-    parent->GetFirstChild(getter_AddRefs(sibling));
-    while (sibling) {
-      if (IsSeparator(sibling)) { // end of a group of buttons
-        if (posInSet)
-          break; // we've found our group, so we're done
-        setSize = 0; // not our group, so start a new group
-      } else {
-        setSize++; // another button in the group
-        if (sibling == this)
-          posInSet = setSize; // we've found our button
-      }
-      sibling->GetNextSibling(getter_AddRefs(tempSibling));
-      sibling.swap(tempSibling);
+  nsAccessible* parent(GetParent());
+  NS_ENSURE_TRUE(parent,);
+
+  PRInt32 childCount = parent->GetChildCount();
+  for (PRInt32 childIdx = 0; childIdx < childCount; childIdx++) {
+    nsAccessible* child = parent->GetChildAt(childIdx);
+    if (IsSeparator(child)) { // end of a group of buttons
+      if (posInSet)
+        break; // we've found our group, so we're done
+
+      setSize = 0; // not our group, so start a new group
+
+    } else {
+      setSize++; // another button in the group
+
+      if (child == this)
+        posInSet = setSize; // we've found our button
     }
   }
 
   *aPosInSet = posInSet;
   *aSetSize = setSize;
 }
 
 PRBool
-nsXULToolbarButtonAccessible::IsSeparator(nsIAccessible *aAccessible)
+nsXULToolbarButtonAccessible::IsSeparator(nsAccessible *aAccessible)
 {
   nsCOMPtr<nsIDOMNode> domNode;
-  nsCOMPtr<nsIAccessNode> accessNode(do_QueryInterface(aAccessible));
-  accessNode->GetDOMNode(getter_AddRefs(domNode));
+  aAccessible->GetDOMNode(getter_AddRefs(domNode));
   nsCOMPtr<nsIContent> contentDomNode(do_QueryInterface(domNode));
 
   if (!contentDomNode)
     return PR_FALSE;
 
   return (contentDomNode->Tag() == nsAccessibilityAtoms::toolbarseparator) ||
          (contentDomNode->Tag() == nsAccessibilityAtoms::toolbarspacer) ||
          (contentDomNode->Tag() == nsAccessibilityAtoms::toolbarspring);
--- a/accessible/src/xul/nsXULFormControlAccessible.h
+++ b/accessible/src/xul/nsXULFormControlAccessible.h
@@ -186,17 +186,18 @@ class nsXULToolbarButtonAccessible : pub
 {
 public:
   nsXULToolbarButtonAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell);
 
   // nsAccessible
   virtual void GetPositionAndSizeInternal(PRInt32 *aPosInSet,
                                           PRInt32 *aSetSize);
 
-  static PRBool IsSeparator(nsIAccessible *aAccessible);
+  // nsXULToolbarButtonAccessible
+  static PRBool IsSeparator(nsAccessible *aAccessible);
 };
 
 class nsXULToolbarAccessible : public nsAccessibleWrap
 {
 public:
   nsXULToolbarAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell);
 
   // nsAccessible
--- a/accessible/src/xul/nsXULMenuAccessible.cpp
+++ b/accessible/src/xul/nsXULMenuAccessible.cpp
@@ -80,23 +80,21 @@ nsXULSelectableAccessible::Shutdown()
 
 nsresult nsXULSelectableAccessible::ChangeSelection(PRInt32 aIndex, PRUint8 aMethod, PRBool *aSelState)
 {
   *aSelState = PR_FALSE;
 
   if (!mSelectControl) {
     return NS_ERROR_FAILURE;
   }
-  nsCOMPtr<nsIAccessible> childAcc;
-  GetChildAt(aIndex, getter_AddRefs(childAcc));
-  nsCOMPtr<nsIAccessNode> accNode = do_QueryInterface(childAcc);
-  NS_ENSURE_TRUE(accNode, NS_ERROR_FAILURE);
+  nsAccessible* child = GetChildAt(aIndex);
+  NS_ENSURE_TRUE(child, NS_ERROR_FAILURE);
 
   nsCOMPtr<nsIDOMNode> childNode;
-  accNode->GetDOMNode(getter_AddRefs(childNode));
+  child->GetDOMNode(getter_AddRefs(childNode));
   nsCOMPtr<nsIDOMXULSelectControlItemElement> item(do_QueryInterface(childNode));
   NS_ENSURE_TRUE(item, NS_ERROR_FAILURE);
 
   item->GetSelected(aSelState);
   if (eSelection_GetState == aMethod) {
     return NS_OK;
   }
 
@@ -333,28 +331,27 @@ nsXULMenuitemAccessible::GetStateInterna
     PRBool isSelected = PR_FALSE;
     nsCOMPtr<nsIDOMXULSelectControlItemElement>
       item(do_QueryInterface(mDOMNode));
     NS_ENSURE_TRUE(item, NS_ERROR_FAILURE);
     item->GetSelected(&isSelected);
 
     // Is collapsed?
     PRBool isCollapsed = PR_FALSE;
-    nsCOMPtr<nsIAccessible> parentAccessible(GetParent());
-    if (nsAccUtils::State(parentAccessible) & nsIAccessibleStates::STATE_INVISIBLE)
+    nsAccessible* parentAcc = GetParent();
+    if (nsAccUtils::State(parentAcc) & nsIAccessibleStates::STATE_INVISIBLE)
       isCollapsed = PR_TRUE;
-    
+
     if (isSelected) {
       *aState |= nsIAccessibleStates::STATE_SELECTED;
-      
+
       // Selected and collapsed?
       if (isCollapsed) {
         // Set selected option offscreen/invisible according to combobox state
-        nsCOMPtr<nsIAccessible> grandParentAcc;
-        parentAccessible->GetParent(getter_AddRefs(grandParentAcc));
+        nsAccessible* grandParentAcc = parentAcc->GetParent();
         NS_ENSURE_TRUE(grandParentAcc, NS_ERROR_FAILURE);
         NS_ASSERTION(nsAccUtils::Role(grandParentAcc) == nsIAccessibleRole::ROLE_COMBOBOX,
                      "grandparent of combobox listitem is not combobox");
         PRUint32 grandParentState, grandParentExtState;
         grandParentAcc->GetState(&grandParentState, &grandParentExtState);
         *aState &= ~(nsIAccessibleStates::STATE_OFFSCREEN |
                      nsIAccessibleStates::STATE_INVISIBLE);
         *aState |= grandParentState & nsIAccessibleStates::STATE_OFFSCREEN |
@@ -418,19 +415,19 @@ nsXULMenuitemAccessible::GetKeyboardShor
   if (elt) {
     nsAutoString accesskey;
     // We do not use nsCoreUtils::GetAccesskeyFor() because accesskeys for
     // menu are't registered by nsIEventStateManager.
     elt->GetAttribute(NS_LITERAL_STRING("accesskey"), accesskey);
     if (accesskey.IsEmpty())
       return NS_OK;
 
-    nsCOMPtr<nsIAccessible> parentAccessible(GetParent());
-    if (parentAccessible) {
-      if (nsAccUtils::RoleInternal(parentAccessible) ==
+    nsAccessible* parentAcc = GetParent();
+    if (parentAcc) {
+      if (nsAccUtils::RoleInternal(parentAcc) ==
           nsIAccessibleRole::ROLE_MENUBAR) {
         // If top level menu item, add Alt+ or whatever modifier text to string
         // No need to cache pref service, this happens rarely
         if (gMenuAccesskeyModifier == -1) {
           // Need to initialize cached global accesskey pref
           gMenuAccesskeyModifier = 0;
           nsCOMPtr<nsIPrefBranch> prefBranch(do_GetService(NS_PREFSERVICE_CONTRACTID));
           if (prefBranch)
--- a/accessible/src/xul/nsXULTabAccessible.cpp
+++ b/accessible/src/xul/nsXULTabAccessible.cpp
@@ -154,53 +154,45 @@ nsXULTabAccessible::GetRelationByType(PR
 
   if (rv != NS_OK_NO_RELATION_TARGET)
     return NS_OK;
 
   // If there is no 'linkedPanel' attribute on xul:tab element then we
   // assume tab and tabpanels are related 1 to 1. We follow algorithm from
   // the setter 'selectedIndex' of tabbox.xml#tabs binding.
 
-  nsCOMPtr<nsIAccessible> tabsAcc = GetParent();
+  nsAccessible* tabsAcc = GetParent();
   NS_ENSURE_TRUE(nsAccUtils::Role(tabsAcc) == nsIAccessibleRole::ROLE_PAGETABLIST,
                  NS_ERROR_FAILURE);
 
   PRInt32 tabIndex = -1;
 
-  nsCOMPtr<nsIAccessible> childAcc;
-  tabsAcc->GetFirstChild(getter_AddRefs(childAcc));
-  while (childAcc) {
+  PRInt32 childCount = tabsAcc->GetChildCount();
+  for (PRInt32 childIdx = 0; childIdx < childCount; childIdx++) {
+    nsAccessible* childAcc = tabsAcc->GetChildAt(childIdx);
     if (nsAccUtils::Role(childAcc) == nsIAccessibleRole::ROLE_PAGETAB)
       tabIndex++;
 
     if (childAcc == this)
       break;
-
-    nsCOMPtr<nsIAccessible> acc;
-    childAcc->GetNextSibling(getter_AddRefs(acc));
-    childAcc.swap(acc);
   }
 
-  nsCOMPtr<nsIAccessible> tabBoxAcc;
-  tabsAcc->GetParent(getter_AddRefs(tabBoxAcc));
+  nsAccessible* tabBoxAcc = tabsAcc->GetParent();
   NS_ENSURE_TRUE(nsAccUtils::Role(tabBoxAcc) == nsIAccessibleRole::ROLE_PANE,
                  NS_ERROR_FAILURE);
 
-  tabBoxAcc->GetFirstChild(getter_AddRefs(childAcc));
-  while (childAcc) {
+  childCount = tabBoxAcc->GetChildCount();
+  for (PRInt32 childIdx = 0; childIdx < childCount; childIdx++) {
+    nsAccessible* childAcc = tabBoxAcc->GetChildAt(childIdx);
     if (nsAccUtils::Role(childAcc) == nsIAccessibleRole::ROLE_PROPERTYPAGE) {
       if (tabIndex == 0)
         return nsRelUtils::AddTarget(aRelationType, aRelation, childAcc);
 
       tabIndex--;
     }
-
-    nsCOMPtr<nsIAccessible> acc;
-    childAcc->GetNextSibling(getter_AddRefs(acc));
-    childAcc.swap(acc);
   }
 
   return NS_OK;
 }
 
 void
 nsXULTabAccessible::GetPositionAndSizeInternal(PRInt32 *aPosInSet,
                                                PRInt32 *aSetSize)
--- a/accessible/src/xul/nsXULTreeAccessible.cpp
+++ b/accessible/src/xul/nsXULTreeAccessible.cpp
@@ -456,29 +456,32 @@ nsXULTreeAccessible::SelectAllSelection(
   }
 
   return NS_OK;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsXULTreeAccessible: nsAccessible implementation
 
-nsIAccessible*
+nsAccessible*
 nsXULTreeAccessible::GetChildAt(PRUint32 aIndex)
 {
   PRInt32 childCount = nsAccessible::GetChildCount();
   if (childCount == -1)
     return nsnull;
 
   if (static_cast<PRInt32>(aIndex) < childCount)
     return nsAccessible::GetChildAt(aIndex);
 
   nsCOMPtr<nsIAccessible> child;
   GetTreeItemAccessible(aIndex - childCount, getter_AddRefs(child));
-  return child;
+
+  nsRefPtr<nsAccessible> childAcc =
+    nsAccUtils::QueryObject<nsAccessible>(child);
+  return childAcc;
 }
 
 PRInt32
 nsXULTreeAccessible::GetChildCount()
 {
   // tree's children count is row count + treecols count.
   PRInt32 childCount = nsAccessible::GetChildCount();
   if (childCount == -1)
@@ -712,17 +715,17 @@ nsXULTreeAccessible::CreateTreeItemAcces
 }
                              
 ////////////////////////////////////////////////////////////////////////////////
 // nsXULTreeItemAccessibleBase
 ////////////////////////////////////////////////////////////////////////////////
 
 nsXULTreeItemAccessibleBase::
   nsXULTreeItemAccessibleBase(nsIDOMNode *aDOMNode, nsIWeakReference *aShell,
-                              nsIAccessible *aParent, nsITreeBoxObject *aTree,
+                              nsAccessible *aParent, nsITreeBoxObject *aTree,
                               nsITreeView *aTreeView, PRInt32 aRow) :
   mTree(aTree), mTreeView(aTreeView), mRow(aRow),
   nsAccessibleWrap(aDOMNode, aShell)
 {
   mParent = aParent;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -1077,17 +1080,17 @@ nsXULTreeItemAccessibleBase::GetStateInt
   mTree->GetFirstVisibleRow(&firstVisibleRow);
   mTree->GetLastVisibleRow(&lastVisibleRow);
   if (mRow < firstVisibleRow || mRow > lastVisibleRow)
     *aState |= nsIAccessibleStates::STATE_INVISIBLE;
 
   return NS_OK;
 }
 
-nsIAccessible*
+nsAccessible*
 nsXULTreeItemAccessibleBase::GetParent()
 {
   return IsDefunct() ? nsnull : mParent.get();
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsXULTreeItemAccessibleBase: nsAccessible protected methods
 
@@ -1179,19 +1182,19 @@ nsXULTreeItemAccessibleBase::IsExpandabl
 }
 
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsXULTreeItemAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
 nsXULTreeItemAccessible::
-nsXULTreeItemAccessible(nsIDOMNode *aDOMNode, nsIWeakReference *aShell,
-                        nsIAccessible *aParent, nsITreeBoxObject *aTree,
-                        nsITreeView *aTreeView, PRInt32 aRow) :
+  nsXULTreeItemAccessible(nsIDOMNode *aDOMNode, nsIWeakReference *aShell,
+                          nsAccessible *aParent, nsITreeBoxObject *aTree,
+                          nsITreeView *aTreeView, PRInt32 aRow) :
   nsXULTreeItemAccessibleBase(aDOMNode, aShell, aParent, aTree, aTreeView, aRow)
 {
   mColumn = nsCoreUtils::GetFirstSensibleColumn(mTree);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsXULTreeItemAccessible: nsIAccessible implementation
 
--- a/accessible/src/xul/nsXULTreeAccessible.h
+++ b/accessible/src/xul/nsXULTreeAccessible.h
@@ -84,17 +84,17 @@ public:
 
   // nsAccessible
   virtual nsresult GetRoleInternal(PRUint32 *aRole);
   virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
   virtual nsresult GetChildAtPoint(PRInt32 aX, PRInt32 aY,
                                    PRBool aDeepestChild,
                                    nsIAccessible **aChild);
 
-  virtual nsIAccessible* GetChildAt(PRUint32 aIndex);
+  virtual nsAccessible* GetChildAt(PRUint32 aIndex);
   virtual PRInt32 GetChildCount();
   virtual PRInt32 GetIndexOf(nsIAccessible *aChild);
 
   // nsXULTreeAccessible
 
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_XULTREEACCESSIBLE_IMPL_CID)
 
   /**
@@ -161,17 +161,17 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsXULTreeA
   0x443c,                                             \
   { 0x94, 0x0b, 0xb1, 0xe6, 0xb0, 0x83, 0x1d, 0xfc }  \
 }
 
 class nsXULTreeItemAccessibleBase : public nsAccessibleWrap
 {
 public:
   nsXULTreeItemAccessibleBase(nsIDOMNode *aDOMNode, nsIWeakReference *aShell,
-                              nsIAccessible *aParent, nsITreeBoxObject *aTree,
+                              nsAccessible *aParent, nsITreeBoxObject *aTree,
                               nsITreeView *aTreeView, PRInt32 aRow);
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIAccessNode
   NS_IMETHOD GetUniqueID(void **aUniqueID);
 
@@ -196,17 +196,17 @@ public:
   NS_IMETHOD DoAction(PRUint8 aIndex);
 
   // nsAccessNode
   virtual PRBool IsDefunct();
   virtual nsresult Shutdown();
 
   // nsAccessible
   virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
-  virtual nsIAccessible* GetParent();
+  virtual nsAccessible* GetParent();
 
   // nsXULTreeItemAccessibleBase
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_XULTREEITEMBASEACCESSIBLE_IMPL_CID)
 
   /**
    * Return row index associated with the accessible.
    */
   PRInt32 GetRowIndex() const { return mRow; }
@@ -250,17 +250,17 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsXULTreeI
 
 /**
  * Accessible class for items for XUL tree.
  */
 class nsXULTreeItemAccessible : public nsXULTreeItemAccessibleBase
 {
 public:
   nsXULTreeItemAccessible(nsIDOMNode *aDOMNode, nsIWeakReference *aShell,
-                          nsIAccessible *aParent, nsITreeBoxObject *aTree,
+                          nsAccessible *aParent, nsITreeBoxObject *aTree,
                           nsITreeView *aTreeView, PRInt32 aRow);
 
   NS_IMETHOD GetName(nsAString& aName);
 
   // nsAccessNode
   virtual PRBool IsDefunct();
   virtual nsresult Init();
   virtual nsresult Shutdown();
--- a/accessible/src/xul/nsXULTreeGridAccessible.cpp
+++ b/accessible/src/xul/nsXULTreeGridAccessible.cpp
@@ -599,17 +599,17 @@ nsXULTreeGridAccessible::CreateTreeItemA
 
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsXULTreeGridRowAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
 nsXULTreeGridRowAccessible::
   nsXULTreeGridRowAccessible(nsIDOMNode *aDOMNode, nsIWeakReference *aShell,
-                             nsIAccessible *aTreeAcc, nsITreeBoxObject* aTree,
+                             nsAccessible *aTreeAcc, nsITreeBoxObject* aTree,
                              nsITreeView *aTreeView, PRInt32 aRow) :
   nsXULTreeItemAccessibleBase(aDOMNode, aShell, aTreeAcc, aTree, aTreeView, aRow)
 {
   mAccessNodeCache.Init(kDefaultTreeCacheSize);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsXULTreeGridRowAccessible: nsISupports and cycle collection implementation
@@ -684,30 +684,32 @@ nsXULTreeGridRowAccessible::GetChildAtPo
   // Return if we failed to find tree cell in the row for the given point.
   if (row != mRow || !column)
     return NS_OK;
 
   GetCellAccessible(column, aChild);
   return NS_OK;
 }
 
-nsIAccessible*
+nsAccessible*
 nsXULTreeGridRowAccessible::GetChildAt(PRUint32 aIndex)
 {
   if (IsDefunct())
     return nsnull;
 
   nsCOMPtr<nsITreeColumn> column =
     nsCoreUtils::GetSensibleColumnAt(mTree, aIndex);
   if (!column)
     return nsnull;
 
   nsCOMPtr<nsIAccessible> cell;
   GetCellAccessible(column, getter_AddRefs(cell));
-  return cell;
+
+  nsRefPtr<nsAccessible> cellAcc = nsAccUtils::QueryObject<nsAccessible>(cell);
+  return cellAcc;
 }
 
 PRInt32
 nsXULTreeGridRowAccessible::GetChildCount()
 {
   if (IsDefunct())
     return -1;
 
@@ -989,20 +991,17 @@ NS_IMETHODIMP
 nsXULTreeGridCellAccessible::GetTable(nsIAccessibleTable **aTable)
 {
   NS_ENSURE_ARG_POINTER(aTable);
   *aTable = nsnull;
 
   if (IsDefunct())
     return NS_OK;
 
-  nsCOMPtr<nsIAccessible> accessible;
-  mParent->GetParent(getter_AddRefs(accessible));
-  CallQueryInterface(accessible, aTable);
-
+  CallQueryInterface(mParent->GetParent(), aTable);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXULTreeGridCellAccessible::GetColumnIndex(PRInt32 *aColumnIndex)
 {
   NS_ENSURE_ARG_POINTER(aColumnIndex);
   *aColumnIndex = -1;
@@ -1217,17 +1216,17 @@ nsXULTreeGridCellAccessible::GetStateInt
     mTreeView->GetCellValue(mRow, mColumn, checked);
     if (checked.EqualsIgnoreCase("true"))
       *aStates |= nsIAccessibleStates::STATE_CHECKED;
   }
 
   return NS_OK;
 }
 
-nsIAccessible*
+nsAccessible*
 nsXULTreeGridCellAccessible::GetParent()
 {
   return IsDefunct() ? nsnull : mParent.get();
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsXULTreeGridCellAccessible: public implementation
 
--- a/accessible/src/xul/nsXULTreeGridAccessible.h
+++ b/accessible/src/xul/nsXULTreeGridAccessible.h
@@ -73,34 +73,34 @@ protected:
 /**
  * Represents accessible for XUL tree item in the case when XUL tree has
  * multiple columns.
  */
 class nsXULTreeGridRowAccessible : public nsXULTreeItemAccessibleBase
 {
 public:
   nsXULTreeGridRowAccessible(nsIDOMNode *aDOMNode, nsIWeakReference *aShell,
-                             nsIAccessible *aParent, nsITreeBoxObject *aTree,
+                             nsAccessible *aParent, nsITreeBoxObject *aTree,
                              nsITreeView *aTreeView, PRInt32 aRow);
 
   // nsISupports and cycle collection
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsXULTreeGridRowAccessible,
                                            nsAccessible)
 
   // nsAccessNode
   virtual nsresult Shutdown();
 
   // nsAccessible
   virtual nsresult GetRoleInternal(PRUint32 *aRole);
   virtual nsresult GetChildAtPoint(PRInt32 aX, PRInt32 aY,
                                    PRBool aDeepestChild,
                                    nsIAccessible **aChild);
 
-  virtual nsIAccessible* GetChildAt(PRUint32 aIndex);
+  virtual nsAccessible* GetChildAt(PRUint32 aIndex);
   virtual PRInt32 GetChildCount();
   virtual PRInt32 GetIndexOf(nsIAccessible *aChild);
 
   // nsXULTreeItemAccessibleBase
   virtual void GetCellAccessible(nsITreeColumn *aColumn, nsIAccessible **aCell);
   virtual void RowInvalidated(PRInt32 aStartColIdx, PRInt32 aEndColIdx);
 
 protected:
@@ -159,17 +159,17 @@ public:
   virtual PRBool IsDefunct();
   virtual nsresult Init();
 
   // nsAccessible
   virtual nsresult GetAttributesInternal(nsIPersistentProperties *aAttributes);
   virtual nsresult GetRoleInternal(PRUint32 *aRole);
   virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
 
-  virtual nsIAccessible* GetParent();
+  virtual nsAccessible* GetParent();
 
   // nsXULTreeGridCellAccessible
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_XULTREEGRIDCELLACCESSIBLE_IMPL_CID)
 
   /**
    * Return index of the column.
    */
   PRInt32 GetColumnIndex() const;