Merge last green PGO changeset from inbound to central
authorMarco Bonardo <mbonardo@mozilla.com>
Tue, 17 Jan 2012 16:22:33 +0100
changeset 84653 ff1bedd7d4637cbef5d354765623c210ef0d2b89
parent 84611 0b4c58200e3a4ad1966d7f1cd244ab9bb73fa69a (current diff)
parent 84652 f43cfe78a5b4049cc8c1207437a805cb2f1f8ee6 (diff)
child 84654 1cfc17f1bd13a7220b0b90c822b98a91d7fdb6bf
child 84671 e6b4507afdf6a117e7e84d4cb863c3d62dfb1a49
push id21868
push usermak77@bonardo.net
push dateTue, 17 Jan 2012 15:23:07 +0000
treeherdermozilla-central@ff1bedd7d463 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone12.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge last green PGO changeset from inbound to central
--- a/accessible/src/atk/nsAccessibleWrap.cpp
+++ b/accessible/src/atk/nsAccessibleWrap.cpp
@@ -436,23 +436,19 @@ nsAccessibleWrap::CreateMaiInterfaces(vo
     //nsIAccessibleValue
     nsCOMPtr<nsIAccessibleValue> accessInterfaceValue;
     QueryInterface(NS_GET_IID(nsIAccessibleValue),
                    getter_AddRefs(accessInterfaceValue));
     if (accessInterfaceValue) {
        interfacesBits |= 1 << MAI_INTERFACE_VALUE; 
     }
 
-    //nsIAccessibleDocument
-    nsCOMPtr<nsIAccessibleDocument> accessInterfaceDocument;
-    QueryInterface(NS_GET_IID(nsIAccessibleDocument),
-                              getter_AddRefs(accessInterfaceDocument));
-    if (accessInterfaceDocument) {
+    // document accessible
+    if (IsDoc())
         interfacesBits |= 1 << MAI_INTERFACE_DOCUMENT;
-    }
 
     if (IsImageAccessible())
         interfacesBits |= 1 << MAI_INTERFACE_IMAGE;
 
   // HyperLinkAccessible
   if (IsLink())
     interfacesBits |= 1 << MAI_INTERFACE_HYPERLINK_IMPL;
 
--- a/accessible/src/atk/nsMaiInterfaceDocument.cpp
+++ b/accessible/src/atk/nsMaiInterfaceDocument.cpp
@@ -32,22 +32,32 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
-#include "nsAccessibleWrap.h"
 #include "nsMaiInterfaceDocument.h"
 
-const char *const kDocTypeName = "W3C-doctype";
-const char *const kDocUrlName = "DocURL";
-const char *const kMimeTypeName = "MimeType";
+#include "nsAccessibleWrap.h"
+#include "nsDocAccessible.h"
+
+static const char* const kDocTypeName = "W3C-doctype";
+static const char* const kDocUrlName = "DocURL";
+static const char* const kMimeTypeName = "MimeType";
+
+// below functions are vfuncs on an ATK  interface so they need to be C call
+extern "C" {
+
+static const gchar* getDocumentLocaleCB(AtkDocument* aDocument);
+static AtkAttributeSet* getDocumentAttributesCB(AtkDocument* aDocument);
+static const gchar* getDocumentAttributeValueCB(AtkDocument* aDocument,
+                                                const gchar* aAttrName);
 
 void
 documentInterfaceInitCB(AtkDocumentIface *aIface)
 {
     NS_ASSERTION(aIface, "Invalid Interface");
     if(!aIface)
         return;
 
@@ -59,101 +69,82 @@ documentInterfaceInitCB(AtkDocumentIface
     aIface->get_document_attributes = getDocumentAttributesCB;
     aIface->get_document_attribute_value = getDocumentAttributeValueCB;
     aIface->get_document_locale = getDocumentLocaleCB;
 }
 
 const gchar *
 getDocumentLocaleCB(AtkDocument *aDocument)
 {
-    nsAccessibleWrap *accWrap = GetAccessibleWrap(ATK_OBJECT(aDocument));
-    if (!accWrap)
-        return nsnull;
+  nsAccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aDocument));
+  if (!accWrap)
+    return nsnull;
 
-    nsCOMPtr<nsIAccessNode> docAccessNode;
-    accWrap->QueryInterface(NS_GET_IID(nsIAccessNode),
-                            getter_AddRefs(docAccessNode));
-    NS_ENSURE_TRUE(docAccessNode, nsnull);
-
-    nsAutoString locale;
-    docAccessNode->GetLanguage(locale);
-    if (locale.IsEmpty()) {
-      return nsnull;
-    }
-    return nsAccessibleWrap::ReturnString(locale);
+  nsAutoString locale;
+  accWrap->GetLanguage(locale);
+  return locale.IsEmpty() ? nsnull : nsAccessibleWrap::ReturnString(locale);
 }
 
 static inline GSList *
 prependToList(GSList *aList, const char *const aName, const nsAutoString &aValue)
 {
+  if (aValue.IsEmpty())
+    return aList;
+
     // libspi will free these
     AtkAttribute *atkAttr = (AtkAttribute *)g_malloc(sizeof(AtkAttribute));
     atkAttr->name = g_strdup(aName);
     atkAttr->value = g_strdup(NS_ConvertUTF16toUTF8(aValue).get());
     return g_slist_prepend(aList, atkAttr);
 }
 
 AtkAttributeSet *
 getDocumentAttributesCB(AtkDocument *aDocument)
 {
-    nsAccessibleWrap *accWrap = GetAccessibleWrap(ATK_OBJECT(aDocument));
-    if (!accWrap)
-        return nsnull;
+  nsAccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aDocument));
+  if (!accWrap || !accWrap->IsDoc())
+    return nsnull;
 
-    nsCOMPtr<nsIAccessibleDocument> accDocument;
-    accWrap->QueryInterface(NS_GET_IID(nsIAccessibleDocument),
-                            getter_AddRefs(accDocument));
-    NS_ENSURE_TRUE(accDocument, nsnull);
-
-    // according to atkobject.h, AtkAttributeSet is a GSList
-    GSList *attributes = nsnull;
+  // according to atkobject.h, AtkAttributeSet is a GSList
+  GSList* attributes = nsnull;
+  nsDocAccessible* document = accWrap->AsDoc();
+  nsAutoString aURL;
+  nsresult rv = document->GetURL(aURL);
+  if (NS_SUCCEEDED(rv))
+    attributes = prependToList(attributes, kDocUrlName, aURL);
 
-    nsAutoString aURL;
-    nsresult rv = accDocument->GetURL(aURL);
-    if (NS_SUCCEEDED(rv)) {
-        attributes = prependToList(attributes, kDocUrlName, aURL);
-    }
-    nsAutoString aW3CDocType;
-    rv = accDocument->GetDocType(aW3CDocType);
-    if (NS_SUCCEEDED(rv)) {
-        attributes = prependToList(attributes, kDocTypeName, aW3CDocType);
-    }
-    nsAutoString aMimeType;
-    rv = accDocument->GetMimeType(aMimeType);
-    if (NS_SUCCEEDED(rv)) {
-        attributes = prependToList(attributes, kMimeTypeName, aMimeType);
-    }
-    
-    return attributes;
+  nsAutoString aW3CDocType;
+  rv = document->GetDocType(aW3CDocType);
+  if (NS_SUCCEEDED(rv))
+    attributes = prependToList(attributes, kDocTypeName, aW3CDocType);
+
+  nsAutoString aMimeType;
+  rv = document->GetMimeType(aMimeType);
+  if (NS_SUCCEEDED(rv))
+    attributes = prependToList(attributes, kMimeTypeName, aMimeType);
+
+  return attributes;
 }
 
 const gchar *
 getDocumentAttributeValueCB(AtkDocument *aDocument,
                             const gchar *aAttrName)
 {
-    nsAccessibleWrap *accWrap = GetAccessibleWrap(ATK_OBJECT(aDocument));
-    if (!accWrap)
-        return nsnull;
-
-    nsCOMPtr<nsIAccessibleDocument> accDocument;
-    accWrap->QueryInterface(NS_GET_IID(nsIAccessibleDocument),
-                            getter_AddRefs(accDocument));
-    NS_ENSURE_TRUE(accDocument, nsnull);
+  nsAccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aDocument));
+  if (!accWrap || !accWrap->IsDoc())
+    return nsnull;
 
-    nsresult rv;
-    nsAutoString attrValue;
-    if (!g_ascii_strcasecmp(aAttrName, kDocTypeName)) {
-        rv = accDocument->GetDocType(attrValue);
-        NS_ENSURE_SUCCESS(rv, nsnull);
-    }
-    else if (!g_ascii_strcasecmp(aAttrName, kDocUrlName)) {
-        rv = accDocument->GetURL(attrValue);
-        NS_ENSURE_SUCCESS(rv, nsnull);
-    }
-    else if (!g_ascii_strcasecmp(aAttrName, kMimeTypeName)) {
-        rv = accDocument->GetMimeType(attrValue);
-        NS_ENSURE_SUCCESS(rv, nsnull);
-    }
-    else {
-        return nsnull;
-    }
-    return nsAccessibleWrap::ReturnString(attrValue);
+  nsDocAccessible* document = accWrap->AsDoc();
+  nsresult rv;
+  nsAutoString attrValue;
+  if (!strcasecmp(aAttrName, kDocTypeName))
+    rv = document->GetDocType(attrValue);
+  else if (!strcasecmp(aAttrName, kDocUrlName))
+    rv = document->GetURL(attrValue);
+  else if (!strcasecmp(aAttrName, kMimeTypeName))
+    rv = document->GetMimeType(attrValue);
+  else
+    return nsnull;
+
+  NS_ENSURE_SUCCESS(rv, nsnull);
+  return attrValue.IsEmpty() ? nsnull : nsAccessibleWrap::ReturnString(attrValue);
 }
+}
--- a/accessible/src/atk/nsMaiInterfaceDocument.h
+++ b/accessible/src/atk/nsMaiInterfaceDocument.h
@@ -36,22 +36,17 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef __MAI_INTERFACE_DOCUMENT_H__
 #define __MAI_INTERFACE_DOCUMENT_H__
 
 #include "nsMai.h"
-#include "nsIAccessibleDocument.h"
 
 G_BEGIN_DECLS
 
 /* document interface callbacks */
 void documentInterfaceInitCB(AtkDocumentIface *aIface);
-AtkAttributeSet* getDocumentAttributesCB(AtkDocument *aDocument);
-const gchar* getDocumentLocaleCB(AtkDocument *aDocument);
-const gchar* getDocumentAttributeValueCB(AtkDocument *aDocument,
-                                         const gchar *aAttrName);
 
 G_END_DECLS
 
 #endif /* __MAI_INTERFACE_DOCUMENT_H__ */
--- a/accessible/src/atk/nsMaiInterfaceHypertext.cpp
+++ b/accessible/src/atk/nsMaiInterfaceHypertext.cpp
@@ -33,17 +33,16 @@
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsMaiInterfaceHypertext.h"
-#include "nsIAccessibleDocument.h"
 #include "nsHyperTextAccessible.h"
 
 void
 hypertextInterfaceInitCB(AtkHypertextIface *aIface)
 {
     g_return_if_fail(aIface != NULL);
 
     aIface->get_link = getLinkCB;
--- a/accessible/src/base/nsAccUtils.cpp
+++ b/accessible/src/base/nsAccUtils.cpp
@@ -603,25 +603,22 @@ nsAccUtils::GetLiveAttrValue(PRUint32 aR
   return false;
 }
 
 #ifdef DEBUG_A11Y
 
 bool
 nsAccUtils::IsTextInterfaceSupportCorrect(nsAccessible *aAccessible)
 {
+  // Don't test for accessible docs, it makes us create accessibles too
+  // early and fire mutation events before we need to
+  if (aAccessible->IsDoc())
+    return true;
+
   bool foundText = false;
-  
-  nsCOMPtr<nsIAccessibleDocument> accDoc = do_QueryObject(aAccessible);
-  if (accDoc) {
-    // Don't test for accessible docs, it makes us create accessibles too
-    // early and fire mutation events before we need to
-    return true;
-  }
-
   PRInt32 childCount = aAccessible->GetChildCount();
   for (PRint32 childIdx = 0; childIdx < childCount; childIdx++) {
     nsAccessible *child = GetChildAt(childIdx);
     if (IsText(child)) {
       foundText = true;
       break;
     }
   }
--- a/accessible/src/base/nsAccUtils.h
+++ b/accessible/src/base/nsAccUtils.h
@@ -36,17 +36,16 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef nsAccUtils_h_
 #define nsAccUtils_h_
 
 #include "nsIAccessible.h"
 #include "nsIAccessNode.h"
-#include "nsIAccessibleDocument.h"
 #include "nsIAccessibleRole.h"
 #include "nsIAccessibleText.h"
 #include "nsIAccessibleTable.h"
 
 #include "nsARIAMap.h"
 #include "nsAccessibilityService.h"
 #include "nsCoreUtils.h"
 
--- a/accessible/src/base/nsAccessNode.cpp
+++ b/accessible/src/base/nsAccessNode.cpp
@@ -42,17 +42,16 @@
 
 #include "nsAccCache.h"
 #include "nsAccUtils.h"
 #include "nsCoreUtils.h"
 
 #include "nsHashtable.h"
 #include "nsAccessibilityService.h"
 #include "nsApplicationAccessibleWrap.h"
-#include "nsIAccessibleDocument.h"
 #include "nsIDocShell.h"
 #include "nsIDocShellTreeItem.h"
 #include "nsIDocument.h"
 #include "nsIDOMCSSPrimitiveValue.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOMElement.h"
 #include "nsIDOMHTMLElement.h"
 #include "nsIDOMWindow.h"
--- a/accessible/src/base/nsAccessible.cpp
+++ b/accessible/src/base/nsAccessible.cpp
@@ -1001,17 +1001,17 @@ nsIFrame* nsAccessible::GetBoundsFrame()
 /* void removeSelection (); */
 NS_IMETHODIMP nsAccessible::SetSelected(bool aSelect)
 {
   // Add or remove selection
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
   if (State() & states::SELECTABLE) {
-    nsCOMPtr<nsIAccessible> multiSelect =
+    nsAccessible* multiSelect =
       nsAccUtils::GetMultiSelectableContainer(mContent);
     if (!multiSelect) {
       return aSelect ? TakeFocus() : NS_ERROR_FAILURE;
     }
 
     if (mRoleMapEntry) {
       if (aSelect) {
         return mContent->SetAttr(kNameSpaceID_None,
@@ -1029,22 +1029,21 @@ NS_IMETHODIMP nsAccessible::SetSelected(
 /* void takeSelection (); */
 NS_IMETHODIMP nsAccessible::TakeSelection()
 {
   // Select only this item
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
   if (State() & states::SELECTABLE) {
-    nsCOMPtr<nsIAccessible> multiSelect =
+    nsAccessible* multiSelect =
       nsAccUtils::GetMultiSelectableContainer(mContent);
-    if (multiSelect) {
-      nsCOMPtr<nsIAccessibleSelectable> selectable = do_QueryInterface(multiSelect);
-      selectable->ClearSelection();
-    }
+    if (multiSelect)
+      multiSelect->ClearSelection();
+
     return SetSelected(true);
   }
 
   return NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
 nsAccessible::TakeFocus()
--- a/accessible/src/base/nsRootAccessible.h
+++ b/accessible/src/base/nsRootAccessible.h
@@ -36,17 +36,16 @@
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef _nsRootAccessible_H_
 #define _nsRootAccessible_H_
 
 #include "nsCaretAccessible.h"
 #include "nsDocAccessibleWrap.h"
 
-#include "nsIAccessibleDocument.h"
 #ifdef MOZ_XUL
 #include "nsXULTreeAccessible.h"
 #endif
 
 #include "nsHashtable.h"
 #include "nsCaretAccessible.h"
 #include "nsIDocument.h"
 #include "nsIDOMEventListener.h"
--- a/accessible/src/msaa/nsAccessibleWrap.cpp
+++ b/accessible/src/msaa/nsAccessibleWrap.cpp
@@ -43,17 +43,16 @@
 #include "nsCoreUtils.h"
 #include "nsWinUtils.h"
 #include "Relation.h"
 #include "Role.h"
 #include "States.h"
 
 #include "ia2AccessibleRelation.h"
 
-#include "nsIAccessibleDocument.h"
 #include "nsIAccessibleEvent.h"
 #include "nsIAccessibleRelation.h"
 #include "nsIAccessibleWin32Object.h"
 
 #include "Accessible2_i.c"
 #include "AccessibleStates.h"
 
 #include "nsIMutableArray.h"
--- a/accessible/src/xul/Makefile.in
+++ b/accessible/src/xul/Makefile.in
@@ -45,16 +45,17 @@ include $(DEPTH)/config/autoconf.mk
 
 MODULE = accessibility
 LIBRARY_NAME = accessibility_xul_s
 LIBXUL_LIBRARY = 1
 
 
 
 CPPSRCS = \
+  XULSelectControlAccessible.cpp \
   nsXULAlertAccessible.cpp \
   nsXULColorPickerAccessible.cpp \
   nsXULComboboxAccessible.cpp \
   nsXULFormControlAccessible.cpp \
   nsXULListboxAccessible.cpp \
   nsXULMenuAccessible.cpp \
   nsXULSliderAccessible.cpp \
   nsXULTabAccessible.cpp \
new file mode 100644
--- /dev/null
+++ b/accessible/src/xul/XULSelectControlAccessible.cpp
@@ -0,0 +1,309 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2012
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Jignesh Kakadiya (jigneshhk1992@gmail.com)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "XULSelectControlAccessible.h"
+
+#include "nsAccessibilityService.h"
+#include "nsDocAccessible.h"
+
+#include "nsIDOMXULContainerElement.h"
+#include "nsIDOMXULSelectCntrlItemEl.h"
+#include "nsIDOMXULMultSelectCntrlEl.h"
+#include "nsIDOMKeyEvent.h"
+#include "nsIDOMElement.h"
+#include "nsIDOMXULElement.h"
+#include "nsIMutableArray.h"
+#include "nsIServiceManager.h"
+
+#include "mozilla/dom/Element.h"
+
+using namespace mozilla;
+using namespace mozilla::a11y;
+
+////////////////////////////////////////////////////////////////////////////////
+// XULSelectControlAccessible
+////////////////////////////////////////////////////////////////////////////////
+
+XULSelectControlAccessible::
+  XULSelectControlAccessible(nsIContent *aContent, nsIWeakReference *aShell) :
+  nsAccessibleWrap(aContent, aShell)
+{
+  mSelectControl = do_QueryInterface(aContent);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// XULSelectControlAccessible: nsAccessNode
+
+void
+XULSelectControlAccessible::Shutdown()
+{
+  mSelectControl = nsnull;
+  nsAccessibleWrap::Shutdown();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// XULSelectControlAccessible: SelectAccessible
+
+bool
+XULSelectControlAccessible::IsSelect()
+{
+  return !!mSelectControl;
+}
+
+// Interface methods
+already_AddRefed<nsIArray>
+XULSelectControlAccessible::SelectedItems()
+{
+  nsCOMPtr<nsIMutableArray> selectedItems =
+    do_CreateInstance(NS_ARRAY_CONTRACTID);
+  if (!selectedItems)
+    return nsnull;
+
+  // For XUL multi-select control
+  nsCOMPtr<nsIDOMXULMultiSelectControlElement> xulMultiSelect =
+    do_QueryInterface(mSelectControl);
+  if (xulMultiSelect) {
+    PRInt32 length = 0;
+    xulMultiSelect->GetSelectedCount(&length);
+    for (PRInt32 index = 0; index < length; index++) {
+      nsCOMPtr<nsIDOMXULSelectControlItemElement> itemElm;
+      xulMultiSelect->GetSelectedItem(index, getter_AddRefs(itemElm));
+      nsCOMPtr<nsINode> itemNode(do_QueryInterface(itemElm));
+      nsAccessible* item =
+        GetAccService()->GetAccessibleInWeakShell(itemNode, mWeakShell);
+      if (item)
+        selectedItems->AppendElement(static_cast<nsIAccessible*>(item),
+                                     false);
+    }
+  } else {  // Single select?
+      nsCOMPtr<nsIDOMXULSelectControlItemElement> itemElm;
+      mSelectControl->GetSelectedItem(getter_AddRefs(itemElm));
+      nsCOMPtr<nsINode> itemNode(do_QueryInterface(itemElm));
+      if(itemNode) {
+        nsAccessible* item =
+          GetAccService()->GetAccessibleInWeakShell(itemNode, mWeakShell);
+        if (item)
+          selectedItems->AppendElement(static_cast<nsIAccessible*>(item),
+                                     false);
+      }
+    }
+
+  nsIMutableArray* items = nsnull;
+  selectedItems.forget(&items);
+  return items;
+}
+
+nsAccessible*
+XULSelectControlAccessible::GetSelectedItem(PRUint32 aIndex)
+{
+  nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl =
+    do_QueryInterface(mSelectControl);
+
+  nsCOMPtr<nsIDOMXULSelectControlItemElement> itemElm;
+  if (multiSelectControl)
+    multiSelectControl->GetSelectedItem(aIndex, getter_AddRefs(itemElm));
+  else if (aIndex == 0)
+    mSelectControl->GetSelectedItem(getter_AddRefs(itemElm));
+
+  nsCOMPtr<nsINode> itemNode(do_QueryInterface(itemElm));
+  return itemNode ?
+    GetAccService()->GetAccessibleInWeakShell(itemNode, mWeakShell) : nsnull;
+}
+
+PRUint32
+XULSelectControlAccessible::SelectedItemCount()
+{
+  // For XUL multi-select control
+  nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl =
+    do_QueryInterface(mSelectControl);
+  if (multiSelectControl) {
+    PRInt32 count = 0;
+    multiSelectControl->GetSelectedCount(&count);
+    return count;
+  }
+
+  // For XUL single-select control/menulist
+  PRInt32 index;
+  mSelectControl->GetSelectedIndex(&index);
+  return (index >= 0) ? 1 : 0;
+}
+
+bool
+XULSelectControlAccessible::AddItemToSelection(PRUint32 aIndex)
+{
+  nsAccessible* item = GetChildAt(aIndex);
+  if (!item)
+    return false;
+
+  nsCOMPtr<nsIDOMXULSelectControlItemElement> itemElm =
+    do_QueryInterface(item->GetContent());
+  if (!itemElm)
+    return false;
+
+  bool isItemSelected = false;
+  itemElm->GetSelected(&isItemSelected);
+  if (isItemSelected)
+    return true;
+
+  nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl =
+    do_QueryInterface(mSelectControl);
+
+  if (multiSelectControl)
+    multiSelectControl->AddItemToSelection(itemElm);
+  else
+    mSelectControl->SetSelectedItem(itemElm);
+
+  return true;
+}
+
+bool
+XULSelectControlAccessible::RemoveItemFromSelection(PRUint32 aIndex)
+{
+  nsAccessible* item = GetChildAt(aIndex);
+  if (!item)
+    return false;
+
+  nsCOMPtr<nsIDOMXULSelectControlItemElement> itemElm =
+      do_QueryInterface(item->GetContent());
+  if (!itemElm)
+    return false;
+
+  bool isItemSelected = false;
+  itemElm->GetSelected(&isItemSelected);
+  if (!isItemSelected)
+    return true;
+
+  nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl =
+    do_QueryInterface(mSelectControl);
+
+  if (multiSelectControl)
+    multiSelectControl->RemoveItemFromSelection(itemElm);
+  else
+    mSelectControl->SetSelectedItem(nsnull);
+
+  return true;
+}
+
+bool
+XULSelectControlAccessible::IsItemSelected(PRUint32 aIndex)
+{
+  nsAccessible* item = GetChildAt(aIndex);
+  if (!item)
+    return false;
+
+  nsCOMPtr<nsIDOMXULSelectControlItemElement> itemElm =
+    do_QueryInterface(item->GetContent());
+  if (!itemElm)
+    return false;
+
+  bool isItemSelected = false;
+  itemElm->GetSelected(&isItemSelected);
+  return isItemSelected;
+}
+
+bool
+XULSelectControlAccessible::UnselectAll()
+{
+  nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl =
+    do_QueryInterface(mSelectControl);
+  multiSelectControl ?
+    multiSelectControl->ClearSelection() : mSelectControl->SetSelectedIndex(-1);
+
+  return true;
+}
+
+bool
+XULSelectControlAccessible::SelectAll()
+{
+  nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl =
+    do_QueryInterface(mSelectControl);
+  if (multiSelectControl) {
+    multiSelectControl->SelectAll();
+    return true;
+  }
+
+  // otherwise, don't support this method
+  return false;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// XULSelectControlAccessible: Widgets
+
+nsAccessible*
+XULSelectControlAccessible::CurrentItem()
+{
+  if (!mSelectControl)
+    return nsnull;
+
+  nsCOMPtr<nsIDOMXULSelectControlItemElement> currentItemElm;
+  nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl =
+    do_QueryInterface(mSelectControl);
+  if (multiSelectControl)
+    multiSelectControl->GetCurrentItem(getter_AddRefs(currentItemElm));
+  else
+    mSelectControl->GetSelectedItem(getter_AddRefs(currentItemElm));
+
+  nsCOMPtr<nsINode> DOMNode;
+  if (currentItemElm)
+    DOMNode = do_QueryInterface(currentItemElm);
+
+  if (DOMNode) {
+    nsDocAccessible* document = GetDocAccessible();
+    if (document)
+      return document->GetAccessible(DOMNode);
+  }
+
+  return nsnull;
+}
+
+void
+XULSelectControlAccessible::SetCurrentItem(nsAccessible* aItem)
+{
+  if (!mSelectControl)
+    return;
+
+  nsCOMPtr<nsIDOMXULSelectControlItemElement> itemElm =
+    do_QueryInterface(aItem->GetContent());
+  nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl =
+    do_QueryInterface(mSelectControl);
+  if (multiSelectControl)
+    multiSelectControl->SetCurrentItem(itemElm);
+  else
+    mSelectControl->SetSelectedItem(itemElm);
+}
new file mode 100644
--- /dev/null
+++ b/accessible/src/xul/XULSelectControlAccessible.h
@@ -0,0 +1,80 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2012
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Jignesh Kakadiya (jigneshhk1992@gmail.com)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef _XULSelectControlAccessible_H_
+#define _XULSelectControlAccessible_H_
+
+#include "nsAccessibleWrap.h"
+#include "nsIDOMXULSelectCntrlEl.h"
+
+/**
+ * The basic implementation of accessible selection for XUL select controls.
+ */
+class XULSelectControlAccessible : public nsAccessibleWrap
+{
+public:
+  XULSelectControlAccessible(nsIContent *aContent, nsIWeakReference *aShell);
+  virtual ~XULSelectControlAccessible() {}
+
+  // nsAccessNode
+  virtual void Shutdown();
+
+  // SelectAccessible
+  virtual bool IsSelect();
+  virtual already_AddRefed<nsIArray> SelectedItems();
+  virtual PRUint32 SelectedItemCount();
+  virtual nsAccessible* GetSelectedItem(PRUint32 aIndex);
+  virtual bool IsItemSelected(PRUint32 aIndex);
+  virtual bool AddItemToSelection(PRUint32 aIndex);
+  virtual bool RemoveItemFromSelection(PRUint32 aIndex);
+  virtual bool SelectAll();
+  virtual bool UnselectAll();
+
+  // Widgets
+  virtual nsAccessible* CurrentItem();
+  virtual void SetCurrentItem(nsAccessible* aItem);
+
+protected:
+  // nsIDOMXULMultiSelectControlElement inherits from this, so we'll always have
+  // one of these if the widget is valid and not defunct
+  nsCOMPtr<nsIDOMXULSelectControlElement> mSelectControl;
+};
+
+#endif
+
--- a/accessible/src/xul/nsXULFormControlAccessible.cpp
+++ b/accessible/src/xul/nsXULFormControlAccessible.cpp
@@ -554,17 +554,17 @@ nsXULRadioButtonAccessible::ContainerWid
   *   focus whereas the Buttons do not. So we only have an accessible object for
   *   this for the purpose of getting the proper RadioButton. Need this here to 
   *   avoid circular reference problems when navigating the accessible tree and
   *   for getting to the radiobuttons.
   */
 
 nsXULRadioGroupAccessible::
   nsXULRadioGroupAccessible(nsIContent *aContent, nsIWeakReference *aShell) :
-  nsXULSelectableAccessible(aContent, aShell)
+  XULSelectControlAccessible(aContent, aShell)
 { 
 }
 
 role
 nsXULRadioGroupAccessible::NativeRole()
 {
   return roles::GROUPING;
 }
--- a/accessible/src/xul/nsXULFormControlAccessible.h
+++ b/accessible/src/xul/nsXULFormControlAccessible.h
@@ -38,18 +38,18 @@
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef _nsXULFormControlAccessible_H_
 #define _nsXULFormControlAccessible_H_
 
 // NOTE: alphabetically ordered
 #include "nsAccessibleWrap.h"
 #include "nsFormControlAccessible.h"
-#include "nsXULMenuAccessible.h"
 #include "nsHyperTextAccessibleWrap.h"
+#include "XULSelectControlAccessible.h"
 
 /**
  * Used for XUL progressmeter element.
  */
 typedef ProgressMeterAccessible<100> XULProgressMeterAccessible;
 
 /**
  * Used for XUL button.
@@ -168,17 +168,17 @@ public:
 
   // Widgets
   virtual nsAccessible* ContainerWidget() const;
 };
 
 /**
  * Used for XUL radiogroup element.
  */
-class nsXULRadioGroupAccessible : public nsXULSelectableAccessible
+class nsXULRadioGroupAccessible : public XULSelectControlAccessible
 {
 public:
   nsXULRadioGroupAccessible(nsIContent *aContent, nsIWeakReference *aShell);
 
   // nsAccessible
   virtual mozilla::a11y::role NativeRole();
   virtual PRUint64 NativeState();
 
@@ -279,10 +279,10 @@ protected:
   // nsHyperTextAccessible
   virtual already_AddRefed<nsFrameSelection> FrameSelection();
 
   // nsXULTextFieldAccessible
   already_AddRefed<nsIContent> GetInputField() const;
 };
 
 
-#endif  
+#endif
 
--- a/accessible/src/xul/nsXULListboxAccessible.cpp
+++ b/accessible/src/xul/nsXULListboxAccessible.cpp
@@ -128,34 +128,34 @@ nsXULColumnItemAccessible::DoAction(PRUi
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsXULListboxAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
 nsXULListboxAccessible::
   nsXULListboxAccessible(nsIContent *aContent, nsIWeakReference *aShell) :
-  nsXULSelectableAccessible(aContent, aShell)
+  XULSelectControlAccessible(aContent, aShell)
 {
   nsIContent* parentContent = mContent->GetParent();
   if (parentContent) {
     nsCOMPtr<nsIAutoCompletePopup> autoCompletePopupElm =
       do_QueryInterface(parentContent);
     if (autoCompletePopupElm)
       mFlags |= eAutoCompletePopupAccessible;
   }
 }
 
-NS_IMPL_ADDREF_INHERITED(nsXULListboxAccessible, nsXULSelectableAccessible)
-NS_IMPL_RELEASE_INHERITED(nsXULListboxAccessible, nsXULSelectableAccessible)
+NS_IMPL_ADDREF_INHERITED(nsXULListboxAccessible, XULSelectControlAccessible)
+NS_IMPL_RELEASE_INHERITED(nsXULListboxAccessible, XULSelectControlAccessible)
 
 nsresult
 nsXULListboxAccessible::QueryInterface(REFNSIID aIID, void** aInstancePtr)
 {
-  nsresult rv = nsXULSelectableAccessible::QueryInterface(aIID, aInstancePtr);
+  nsresult rv = XULSelectControlAccessible::QueryInterface(aIID, aInstancePtr);
   if (*aInstancePtr)
     return rv;
 
   if (aIID.Equals(NS_GET_IID(nsIAccessibleTable)) && IsMulticolumn()) {
     *aInstancePtr = static_cast<nsIAccessibleTable*>(this);
     NS_ADDREF_THIS();
     return NS_OK;
   }
--- a/accessible/src/xul/nsXULListboxAccessible.h
+++ b/accessible/src/xul/nsXULListboxAccessible.h
@@ -40,16 +40,17 @@
 #ifndef __nsXULListboxAccessible_h__
 #define __nsXULListboxAccessible_h__
 
 #include "nsIAccessibleTable.h"
 
 #include "nsCOMPtr.h"
 #include "nsXULMenuAccessible.h"
 #include "nsBaseWidgetAccessible.h"
+#include "XULSelectControlAccessible.h"
 
 class nsIWeakReference;
 
 /**
  * nsXULColumnsAccessible are accessible for list and tree columns elements
  * (xul:treecols and xul:listcols).
  */
 class nsXULColumnsAccessible : public nsAccessibleWrap
@@ -83,17 +84,17 @@ public:
   virtual PRUint8 ActionCount();
 
   enum { eAction_Click = 0 };
 };
 
 /*
  * A class the represents the XUL Listbox widget.
  */
-class nsXULListboxAccessible : public nsXULSelectableAccessible,
+class nsXULListboxAccessible : public XULSelectControlAccessible,
                                public nsIAccessibleTable
 {
 public:
   nsXULListboxAccessible(nsIContent *aContent, nsIWeakReference *aShell);
   virtual ~nsXULListboxAccessible() {}
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIACCESSIBLETABLE
--- a/accessible/src/xul/nsXULMenuAccessible.cpp
+++ b/accessible/src/xul/nsXULMenuAccessible.cpp
@@ -62,269 +62,16 @@
 #include "mozilla/Preferences.h"
 #include "mozilla/LookAndFeel.h"
 #include "mozilla/dom/Element.h"
 
 using namespace mozilla;
 using namespace mozilla::a11y;
 
 ////////////////////////////////////////////////////////////////////////////////
-// nsXULSelectableAccessible
-////////////////////////////////////////////////////////////////////////////////
-
-nsXULSelectableAccessible::
-  nsXULSelectableAccessible(nsIContent *aContent, nsIWeakReference *aShell) :
-  nsAccessibleWrap(aContent, aShell)
-{
-  mSelectControl = do_QueryInterface(aContent);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// nsXULSelectableAccessible: nsAccessNode
-
-void
-nsXULSelectableAccessible::Shutdown()
-{
-  mSelectControl = nsnull;
-  nsAccessibleWrap::Shutdown();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// nsXULSelectableAccessible: SelectAccessible
-
-bool
-nsXULSelectableAccessible::IsSelect()
-{
-  return !!mSelectControl;
-}
-
-// Interface methods
-already_AddRefed<nsIArray>
-nsXULSelectableAccessible::SelectedItems()
-{
-  nsCOMPtr<nsIMutableArray> selectedItems =
-    do_CreateInstance(NS_ARRAY_CONTRACTID);
-  if (!selectedItems)
-    return nsnull;
-
-  // For XUL multi-select control
-  nsCOMPtr<nsIDOMXULMultiSelectControlElement> xulMultiSelect =
-    do_QueryInterface(mSelectControl);
-  if (xulMultiSelect) {
-    PRInt32 length = 0;
-    xulMultiSelect->GetSelectedCount(&length);
-    for (PRInt32 index = 0; index < length; index++) {
-      nsCOMPtr<nsIDOMXULSelectControlItemElement> itemElm;
-      xulMultiSelect->GetSelectedItem(index, getter_AddRefs(itemElm));
-      nsCOMPtr<nsINode> itemNode(do_QueryInterface(itemElm));
-      nsAccessible* item =
-        GetAccService()->GetAccessibleInWeakShell(itemNode, mWeakShell);
-      if (item)
-        selectedItems->AppendElement(static_cast<nsIAccessible*>(item),
-                                     false);
-    }
-  }
-  else {  // Single select?
-    nsCOMPtr<nsIDOMXULSelectControlItemElement> itemElm;
-    mSelectControl->GetSelectedItem(getter_AddRefs(itemElm));
-    nsCOMPtr<nsINode> itemNode(do_QueryInterface(itemElm));
-    if(itemNode) {
-      nsAccessible* item =
-        GetAccService()->GetAccessibleInWeakShell(itemNode, mWeakShell);
-      if (item)
-        selectedItems->AppendElement(static_cast<nsIAccessible*>(item),
-                                     false);
-    }
-  }
-
-  nsIMutableArray* items = nsnull;
-  selectedItems.forget(&items);
-  return items;
-}
-
-nsAccessible*
-nsXULSelectableAccessible::GetSelectedItem(PRUint32 aIndex)
-{
-  nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl =
-    do_QueryInterface(mSelectControl);
-
-  nsCOMPtr<nsIDOMXULSelectControlItemElement> itemElm;
-  if (multiSelectControl)
-    multiSelectControl->GetSelectedItem(aIndex, getter_AddRefs(itemElm));
-  else if (aIndex == 0)
-    mSelectControl->GetSelectedItem(getter_AddRefs(itemElm));
-
-  nsCOMPtr<nsINode> itemNode(do_QueryInterface(itemElm));
-  return itemNode ?
-    GetAccService()->GetAccessibleInWeakShell(itemNode, mWeakShell) : nsnull;
-}
-
-PRUint32
-nsXULSelectableAccessible::SelectedItemCount()
-{
-  // For XUL multi-select control
-  nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl =
-    do_QueryInterface(mSelectControl);
-  if (multiSelectControl) {
-    PRInt32 count = 0;
-    multiSelectControl->GetSelectedCount(&count);
-    return count;
-  }
-
-  // For XUL single-select control/menulist
-  PRInt32 index;
-  mSelectControl->GetSelectedIndex(&index);
-  return (index >= 0) ? 1 : 0;
-}
-
-bool
-nsXULSelectableAccessible::AddItemToSelection(PRUint32 aIndex)
-{
-  nsAccessible* item = GetChildAt(aIndex);
-  if (!item)
-    return false;
-
-  nsCOMPtr<nsIDOMXULSelectControlItemElement> itemElm =
-    do_QueryInterface(item->GetContent());
-  if (!itemElm)
-    return false;
-
-  bool isItemSelected = false;
-  itemElm->GetSelected(&isItemSelected);
-  if (isItemSelected)
-    return true;
-
-  nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl =
-    do_QueryInterface(mSelectControl);
-
-  if (multiSelectControl)
-    multiSelectControl->AddItemToSelection(itemElm);
-  else
-    mSelectControl->SetSelectedItem(itemElm);
-
-  return true;
-}
-
-bool
-nsXULSelectableAccessible::RemoveItemFromSelection(PRUint32 aIndex)
-{
-  nsAccessible* item = GetChildAt(aIndex);
-  if (!item)
-    return false;
-
-  nsCOMPtr<nsIDOMXULSelectControlItemElement> itemElm =
-      do_QueryInterface(item->GetContent());
-  if (!itemElm)
-    return false;
-
-  bool isItemSelected = false;
-  itemElm->GetSelected(&isItemSelected);
-  if (!isItemSelected)
-    return true;
-
-  nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl =
-    do_QueryInterface(mSelectControl);
-
-  if (multiSelectControl)
-    multiSelectControl->RemoveItemFromSelection(itemElm);
-  else
-    mSelectControl->SetSelectedItem(nsnull);
-
-  return true;
-}
-
-bool
-nsXULSelectableAccessible::IsItemSelected(PRUint32 aIndex)
-{
-  nsAccessible* item = GetChildAt(aIndex);
-  if (!item)
-    return false;
-
-  nsCOMPtr<nsIDOMXULSelectControlItemElement> itemElm =
-    do_QueryInterface(item->GetContent());
-  if (!itemElm)
-    return false;
-
-  bool isItemSelected = false;
-  itemElm->GetSelected(&isItemSelected);
-  return isItemSelected;
-}
-
-bool
-nsXULSelectableAccessible::UnselectAll()
-{
-  nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl =
-    do_QueryInterface(mSelectControl);
-  multiSelectControl ?
-    multiSelectControl->ClearSelection() : mSelectControl->SetSelectedIndex(-1);
-
-  return true;
-}
-
-bool
-nsXULSelectableAccessible::SelectAll()
-{
-  nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl =
-    do_QueryInterface(mSelectControl);
-  if (multiSelectControl) {
-    multiSelectControl->SelectAll();
-    return true;
-  }
-
-  // otherwise, don't support this method
-  return false;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// nsXULSelectableAccessible: Widgets
-
-nsAccessible*
-nsXULSelectableAccessible::CurrentItem()
-{
-  if (!mSelectControl)
-    return nsnull;
-
-  nsCOMPtr<nsIDOMXULSelectControlItemElement> currentItemElm;
-  nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl =
-    do_QueryInterface(mSelectControl);
-  if (multiSelectControl)
-    multiSelectControl->GetCurrentItem(getter_AddRefs(currentItemElm));
-  else
-    mSelectControl->GetSelectedItem(getter_AddRefs(currentItemElm));
-
-  nsCOMPtr<nsINode> DOMNode;
-  if (currentItemElm)
-    DOMNode = do_QueryInterface(currentItemElm);
-
-  if (DOMNode) {
-    nsDocAccessible* document = GetDocAccessible();
-    if (document)
-      return document->GetAccessible(DOMNode);
-  }
-
-  return nsnull;
-}
-
-void
-nsXULSelectableAccessible::SetCurrentItem(nsAccessible* aItem)
-{
-  if (!mSelectControl)
-    return;
-
-  nsCOMPtr<nsIDOMXULSelectControlItemElement> itemElm =
-    do_QueryInterface(aItem->GetContent());
-  nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl =
-    do_QueryInterface(mSelectControl);
-  if (multiSelectControl)
-    multiSelectControl->SetCurrentItem(itemElm);
-  else
-    mSelectControl->SetSelectedItem(itemElm);
-}
-
-////////////////////////////////////////////////////////////////////////////////
 // nsXULMenuitemAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
 nsXULMenuitemAccessible::
   nsXULMenuitemAccessible(nsIContent *aContent, nsIWeakReference *aShell) :
   nsAccessibleWrap(aContent, aShell)
 {
 }
@@ -703,17 +450,17 @@ nsXULMenuSeparatorAccessible::ActionCoun
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsXULMenupopupAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
 nsXULMenupopupAccessible::
   nsXULMenupopupAccessible(nsIContent *aContent, nsIWeakReference *aShell) :
-  nsXULSelectableAccessible(aContent, aShell)
+  XULSelectControlAccessible(aContent, aShell)
 {
   nsMenuPopupFrame* menuPopupFrame = do_QueryFrame(GetFrame());
   if (menuPopupFrame && menuPopupFrame->IsMenu())
     mFlags |= eMenuPopupAccessible;
 
   // May be the anonymous <menupopup> inside <menulist> (a combobox)
   mSelectControl = do_QueryInterface(mContent->GetParent());
 }
--- a/accessible/src/xul/nsXULMenuAccessible.h
+++ b/accessible/src/xul/nsXULMenuAccessible.h
@@ -36,49 +36,17 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef _nsXULMenuAccessible_H_
 #define _nsXULMenuAccessible_H_
 
 #include "nsAccessibleWrap.h"
 #include "nsIDOMXULSelectCntrlEl.h"
-
-/**
- * The basic implementation of SelectAccessible for XUL select controls.
- */
-class nsXULSelectableAccessible : public nsAccessibleWrap
-{
-public:
-  nsXULSelectableAccessible(nsIContent *aContent, nsIWeakReference *aShell);
-  virtual ~nsXULSelectableAccessible() {}
-
-  // nsAccessNode
-  virtual void Shutdown();
-
-  // SelectAccessible
-  virtual bool IsSelect();
-  virtual already_AddRefed<nsIArray> SelectedItems();
-  virtual PRUint32 SelectedItemCount();
-  virtual nsAccessible* GetSelectedItem(PRUint32 aIndex);
-  virtual bool IsItemSelected(PRUint32 aIndex);
-  virtual bool AddItemToSelection(PRUint32 aIndex);
-  virtual bool RemoveItemFromSelection(PRUint32 aIndex);
-  virtual bool SelectAll();
-  virtual bool UnselectAll();
-
-  // Widgets
-  virtual nsAccessible* CurrentItem();
-  virtual void SetCurrentItem(nsAccessible* aItem);
-
-protected:
-  // nsIDOMXULMultiSelectControlElement inherits from this, so we'll always have
-  // one of these if the widget is valid and not defunct
-  nsCOMPtr<nsIDOMXULSelectControlElement> mSelectControl;
-};
+#include "XULSelectControlAccessible.h"
 
 /**
  * Used for XUL menu, menuitem elements.
  */
 class nsXULMenuitemAccessible : public nsAccessibleWrap
 {
 public:
   enum { eAction_Click = 0 };
@@ -131,17 +99,17 @@ public:
   // ActionAccessible
   virtual PRUint8 ActionCount();
 };
 
 
 /**
  * Used for XUL menupopup and panel.
  */
-class nsXULMenupopupAccessible : public nsXULSelectableAccessible
+class nsXULMenupopupAccessible : public XULSelectControlAccessible
 {
 public:
   nsXULMenupopupAccessible(nsIContent *aContent, nsIWeakReference *aShell);
 
   // nsAccessible
   virtual nsresult GetNameInternal(nsAString& aName);
   virtual mozilla::a11y::role NativeRole();
   virtual PRUint64 NativeState();
@@ -169,9 +137,9 @@ public:
 
   // Widget
   virtual bool IsActiveWidget() const;
   virtual bool AreItemsOperable() const;
   virtual nsAccessible* CurrentItem();
   virtual void SetCurrentItem(nsAccessible* aItem);
 };
 
-#endif  
+#endif
--- a/accessible/src/xul/nsXULTabAccessible.cpp
+++ b/accessible/src/xul/nsXULTabAccessible.cpp
@@ -174,17 +174,17 @@ nsXULTabAccessible::GetPositionAndSizeIn
 
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsXULTabsAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
 nsXULTabsAccessible::
   nsXULTabsAccessible(nsIContent *aContent, nsIWeakReference *aShell) :
-  nsXULSelectableAccessible(aContent, aShell)
+  XULSelectControlAccessible(aContent, aShell)
 {
 }
 
 role
 nsXULTabsAccessible::NativeRole()
 {
   return roles::PAGETABLIST;
 }
--- a/accessible/src/xul/nsXULTabAccessible.h
+++ b/accessible/src/xul/nsXULTabAccessible.h
@@ -37,16 +37,17 @@
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef _nsXULTabAccessible_H_
 #define _nsXULTabAccessible_H_
 
 // NOTE: alphabetically ordered
 #include "nsBaseWidgetAccessible.h"
 #include "nsXULMenuAccessible.h"
+#include "XULSelectControlAccessible.h"
 
 /**
  * An individual tab, xul:tab element.
  */
 class nsXULTabAccessible : public nsAccessibleWrap
 {
 public:
   enum { eAction_Switch = 0 };
@@ -67,17 +68,17 @@ public:
   // ActionAccessible
   virtual PRUint8 ActionCount();
 };
 
 
 /**
  * A container of tab objects, xul:tabs element.
  */
-class nsXULTabsAccessible : public nsXULSelectableAccessible
+class nsXULTabsAccessible : public XULSelectControlAccessible
 {
 public:
   nsXULTabsAccessible(nsIContent *aContent, nsIWeakReference *aShell);
 
   // nsIAccessible
   NS_IMETHOD GetValue(nsAString& _retval);
 
   // nsAccessible
--- a/embedding/android/Makefile.in
+++ b/embedding/android/Makefile.in
@@ -186,16 +186,16 @@ RES_DRAWABLE = $(addprefix res/drawable/
 	$(NSINSTALL) -D res/drawable
 	$(NSINSTALL) $^ res/drawable/
 
 $(RESOURCES): $(RES_DIRS) $(subst res/,$(srcdir)/resources/,$(RESOURCES))
 	@echo "creating $@"
 	$(NSINSTALL) $(subst res/,$(srcdir)/resources/,$@) $(dir $@)
 
 
-R.java: $(MOZ_APP_ICON) $(RES_LAYOUT) $(RES_DRAWABLE) $(RES_VALUES) res/drawable/icon.png res/drawable-hdpi/icon.png res/values/strings.xml AndroidManifest.xml
+R.java: $(MOZ_APP_ICON) $(RES_LAYOUT) $(RES_DRAWABLE) $(RES_VALUES) res/drawable/icon.png res/drawable-hdpi/icon.png AndroidManifest.xml chrome
 	$(AAPT) package -f -M AndroidManifest.xml -I $(ANDROID_SDK)/android.jar -S res -J . --custom-package org.mozilla.gecko
 
 gecko.ap_: AndroidManifest.xml res/drawable/icon.png res/drawable-hdpi/icon.png $(RES_LAYOUT) $(RES_DRAWABLE) $(RES_VALUES) res/values/strings.xml FORCE
 	$(AAPT) package -f -M AndroidManifest.xml -I $(ANDROID_SDK)/android.jar  -S res -F $@
 
 libs:: classes.dex
 	$(INSTALL) classes.dex $(FINAL_TARGET)
--- a/gfx/cairo/cairo/src/cairo-type1-subset.c
+++ b/gfx/cairo/cairo/src/cairo-type1-subset.c
@@ -64,18 +64,18 @@
 typedef struct _cairo_type1_font_subset {
     cairo_scaled_font_subset_t *scaled_font_subset;
 
     struct {
 	cairo_unscaled_font_t *unscaled_font;
 	unsigned int font_id;
 	char *base_font;
 	unsigned int num_glyphs;
-	long x_min, y_min, x_max, y_max;
-	long ascent, descent;
+	double x_min, y_min, x_max, y_max;
+	double ascent, descent;
 
 	const char    *data;
 	unsigned long  header_size;
 	unsigned long  data_size;
 	unsigned long  trailer_size;
     } base;
 
     FT_Face face;
@@ -141,22 +141,22 @@ static cairo_status_t
 	status = CAIRO_INT_STATUS_UNSUPPORTED;
         goto fail1;
     }
 #endif
 
     memset (font, 0, sizeof (*font));
     font->base.unscaled_font = _cairo_unscaled_font_reference (unscaled_font);
     font->base.num_glyphs = face->num_glyphs;
-    font->base.x_min = face->bbox.xMin;
-    font->base.y_min = face->bbox.yMin;
-    font->base.x_max = face->bbox.xMax;
-    font->base.y_max = face->bbox.yMax;
-    font->base.ascent = face->ascender;
-    font->base.descent = face->descender;
+    font->base.x_min = face->bbox.xMin / (double)face->units_per_EM;
+    font->base.y_min = face->bbox.yMin / (double)face->units_per_EM;
+    font->base.x_max = face->bbox.xMax / (double)face->units_per_EM;
+    font->base.y_max = face->bbox.yMax / (double)face->units_per_EM;
+    font->base.ascent = face->ascender / (double)face->units_per_EM;
+    font->base.descent = face->descender / (double)face->units_per_EM;
 
     if (face->family_name) {
 	font->base.base_font = strdup (face->family_name);
 	if (unlikely (font->base.base_font == NULL)) {
 	    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 	    goto fail2;
 	}
 	for (i = 0, j = 0; font->base.base_font[j]; j++) {
@@ -561,17 +561,17 @@ cairo_type1_font_subset_get_glyph_names_
 	if (error != FT_Err_Ok) {
 	    /* propagate fatal errors from FreeType */
 	    if (error == FT_Err_Out_Of_Memory)
 		return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
 	    return CAIRO_INT_STATUS_UNSUPPORTED;
 	}
 
-	font->glyphs[i].width = font->face->glyph->linearHoriAdvance / 65536.0; /* 16.16 format */
+	font->glyphs[i].width = font->face->glyph->metrics.horiAdvance / (double)font->face->units_per_EM;
 
 	error = FT_Get_Glyph_Name(font->face, i, buffer, sizeof buffer);
 	if (error != FT_Err_Ok) {
 	    /* propagate fatal errors from FreeType */
 	    if (error == FT_Err_Out_Of_Memory)
 		return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
 	    return CAIRO_INT_STATUS_UNSUPPORTED;
--- a/gfx/src/nsRect.h
+++ b/gfx/src/nsRect.h
@@ -76,16 +76,102 @@ struct NS_GFX nsRect :
   }
 
 #ifdef NS_BUILD_REFCNT_LOGGING
   ~nsRect() {
     MOZ_COUNT_DTOR(nsRect);
   }
 #endif
 
+  // A version of Inflate that caps the values to the nscoord range.
+  // x & y is capped at the minimum value nscoord_MIN and
+  // width & height is capped at the maximum value nscoord_MAX.
+  void SaturatingInflate(const nsMargin& aMargin)
+  {
+#ifdef NS_COORD_IS_FLOAT
+    Inflate(aMargin);
+#else
+    PRInt64 nx = PRInt64(x) - aMargin.left;
+    if (nx < nscoord_MIN) {
+      NS_WARNING("Underflowed nscoord_MIN in conversion to nscoord x");
+      nx = nscoord_MIN;
+    }
+    x = nscoord(nx);
+
+    PRInt64 ny = PRInt64(y) - aMargin.top;
+    if (ny < nscoord_MIN) {
+      NS_WARNING("Underflowed nscoord_MIN in conversion to nscoord y");
+      ny = nscoord_MIN;
+    }
+    y = nscoord(ny);
+
+    PRInt64 w = PRInt64(width) + PRInt64(aMargin.left) + aMargin.right;
+    if (w > nscoord_MAX) {
+      NS_WARNING("Overflowed nscoord_MAX in conversion to nscoord width");
+      w = nscoord_MAX;
+    }
+    width = nscoord(w);
+
+    PRInt64 h = PRInt64(height) + PRInt64(aMargin.top) + aMargin.bottom;
+    if (h > nscoord_MAX) {
+      NS_WARNING("Overflowed nscoord_MAX in conversion to nscoord height");
+      h = nscoord_MAX;
+    }
+    height = nscoord(h);
+#endif
+  }
+
+  // We have saturating versions of all the Union methods. These avoid
+  // overflowing nscoord values in the 'width' and 'height' fields by
+  // clamping the width and height values to nscoord_MAX if necessary.
+
+  nsRect SaturatingUnion(const nsRect& aRect) const
+  {
+    if (IsEmpty()) {
+      return aRect;
+    } else if (aRect.IsEmpty()) {
+      return *static_cast<const nsRect*>(this);
+    } else {
+      return SaturatingUnionEdges(aRect);
+    }
+  }
+
+  nsRect SaturatingUnionEdges(const nsRect& aRect) const
+  {
+#ifdef NS_COORD_IS_FLOAT
+    return UnionEdges(aRect);
+#else
+    nsRect result;
+    result.x = NS_MIN(aRect.x, x);
+    result.y = NS_MIN(aRect.y, y);
+    PRInt64 w = NS_MAX(PRInt64(aRect.x) + aRect.width, PRInt64(x) + width) - result.x;
+    PRInt64 h = NS_MAX(PRInt64(aRect.y) + aRect.height, PRInt64(y) + height) - result.y;
+    if (w > nscoord_MAX) {
+      NS_WARNING("Overflowed nscoord_MAX in conversion to nscoord width");
+      w = nscoord_MAX;
+    }
+    if (h > nscoord_MAX) {
+      NS_WARNING("Overflowed nscoord_MAX in conversion to nscoord height");
+      h = nscoord_MAX;
+    }
+    result.width = nscoord(w);
+    result.height = nscoord(h);
+    return result;
+#endif
+  }
+
+  void SaturatingUnionRect(const nsRect& aRect1, const nsRect& aRect2)
+  {
+    *this = aRect1.SaturatingUnion(aRect2);
+  }
+  void SaturatingUnionRectEdges(const nsRect& aRect1, const nsRect& aRect2)
+  {
+    *this = aRect1.SaturatingUnionEdges(aRect2);
+  }
+
   // Converts this rect from aFromAPP, an appunits per pixel ratio, to aToAPP.
   // In the RoundOut version we make the rect the smallest rect containing the
   // unrounded result. In the RoundIn version we make the rect the largest rect
   // contained in the unrounded result.
   // Note: this can turn an empty rectangle into a non-empty rectangle
   inline nsRect ConvertAppUnitsRoundOut(PRInt32 aFromAPP, PRInt32 aToAPP) const;
   inline nsRect ConvertAppUnitsRoundIn(PRInt32 aFromAPP, PRInt32 aToAPP) const;
 
new file mode 100644
--- /dev/null
+++ b/layout/base/crashtests/698335.html
@@ -0,0 +1,2 @@
+<!DOCTYPE html><html style="white-space: pre-wrap; direction: rtl; -moz-column-width: 1px;"><style style="display: none;">.fl:first-letter { }</style><body class="fl">&#xD288;&#x062A;
+D</body></html>
--- a/layout/base/crashtests/crashtests.list
+++ b/layout/base/crashtests/crashtests.list
@@ -37,17 +37,17 @@ load 244490-1.html
 load 254367-1.html
 load 263359-1.html
 load 265027-1.html
 load 265736-1.html
 load 265736-2.html
 asserts(2) load 265899-1.html # bug 575011
 load 265973-1.html
 asserts(6-12) load 265986-1.html # Bug 512405
-asserts(2-4) load 265999-1.html # bug 575011
+asserts(2-6) load 265999-1.html # bug 575011
 load 266222-1.html
 asserts(3-7) load 266360-1.html # bug 575011 / bug 576358
 asserts(4) load 266445-1.html # Bug 575011
 load 268157-1.html
 load 269566-1.html
 load 272647-1.html
 load 275746-1.html
 load 276053-1.html
@@ -340,9 +340,10 @@ load 663295.html
 load 663662-1.html
 load 663662-2.html
 load 665837.html
 load 668941.xhtml
 load 670226.html
 asserts(2) load 675246-1.xhtml # Bug 675713
 load 691118-1.html
 load 695861.html
+load 698335.html
 load 707098.html
--- a/layout/base/nsBidiPresUtils.cpp
+++ b/layout/base/nsBidiPresUtils.cpp
@@ -815,21 +815,21 @@ nsBidiPresUtils::ResolveParagraph(nsBloc
             do {
             } while (++newIndex < frameCount &&
                      aBpd->FrameAt(newIndex) == NS_BIDI_CONTROL_FRAME);
             if (newIndex < frameCount) {
               RemoveBidiContinuation(aBpd, frame,
                                      frameIndex, newIndex, lineOffset);
             }
           } else if (runLength == fragmentLength &&
-                     numRun + 1 < runCount) {
+                     frame->GetNextSibling()) {
             /*
              * If the directional run ends at the end of the frame, and this is
-             * not the end of our paragraph, make sure that the next frame is a
-             * non-fluid continuation
+             * not the containing frame's last child, make sure that the next
+             * frame is a non-fluid continuation
              */
             nsIFrame* next = frame->GetNextInFlow();
             if (next) {
               frame->SetNextContinuation(next);
               next->SetPrevContinuation(frame);
             }
           }
           frame->AdjustOffsetsForBidi(contentOffset, contentOffset + fragmentLength);
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -3796,32 +3796,38 @@ nsLayoutUtils::GetFrameTransparency(nsIF
   const nsStyleBackground* bg = bgSC->GetStyleBackground();
   if (NS_GET_A(bg->mBackgroundColor) < 255 ||
       // bottom layer's clip is used for the color
       bg->BottomLayer().mClip != NS_STYLE_BG_CLIP_BORDER)
     return eTransparencyTransparent;
   return eTransparencyOpaque;
 }
 
+static bool IsPopupFrame(nsIFrame* aFrame)
+{
+  // aFrame is a popup it's the list control frame dropdown for a combobox.
+  nsIAtom* frameType = aFrame->GetType();
+  if (frameType == nsGkAtoms::listControlFrame) {
+    nsListControlFrame* lcf = static_cast<nsListControlFrame*>(aFrame);
+    return lcf->IsInDropDownMode();
+  }
+
+  // ... or if it's a XUL menupopup frame.
+  return frameType == nsGkAtoms::menuPopupFrame;
+}
+
 /* static */ bool
 nsLayoutUtils::IsPopup(nsIFrame* aFrame)
 {
-  nsIAtom* frameType = aFrame->GetType();
-
-  // We're a popup if we're the list control frame dropdown for a combobox.
-  if (frameType == nsGkAtoms::listControlFrame) {
-    nsListControlFrame* listControlFrame = static_cast<nsListControlFrame*>(aFrame);
-
-    if (listControlFrame) {
-      return listControlFrame->IsInDropDownMode();
-    }
-  }
-
-  // ... or if we're a XUL menupopup frame.
-  return (frameType == nsGkAtoms::menuPopupFrame);
+  // Optimization: the frame can't possibly be a popup if it has no view.
+  if (!aFrame->HasView()) {
+    NS_ASSERTION(!IsPopupFrame(aFrame), "popup frame must have a view");
+    return false;
+  }
+  return IsPopupFrame(aFrame);
 }
 
 /* static */ nsIFrame*
 nsLayoutUtils::GetDisplayRootFrame(nsIFrame* aFrame)
 {
   nsIFrame* f = aFrame;
   for (;;) {
     if (IsPopup(f))
--- a/layout/generic/crashtests/crashtests.list
+++ b/layout/generic/crashtests/crashtests.list
@@ -1,25 +1,25 @@
 load 25888-1.html
 load 25888-2.html
 load 37757-1.html
 load 225868-1.html
 load 264937-1.html
-asserts(9) load 265867-1.html # Bug 575011
+asserts(13) load 265867-1.html # Bug 575011
 load 265867-2.html
 load 289864-1.html
 load 295292-1.html
 load 295292-2.html
 load 302260-1.html
 load 307979-1.html
 load 310556-1.xhtml
 load 322780-1.xul
 load 323381-1.html
 load 323381-2.html
-asserts(2) asserts-if(gtk2Widget,8) load 323386-1.html # Bug 575011
+asserts(2) asserts-if(gtk2Widget,25) load 323386-1.html # Bug 575011
 load 323389-1.html
 load 323389-2.html
 load 323493-1.html
 load 323495-1.html
 load 324318-1.html
 load 328946-1.html
 load 331284-1.xhtml
 load 334105-1.xhtml
@@ -212,17 +212,17 @@ load 430332-1.html
 load 430344-1.html
 load 430352-1.html
 load 430744-1.html
 load 431260-1.html
 load 431260-2.html
 load 435529.html
 load 436194-1.html
 load 436602-1.html
-load 436822-1.html
+asserts(1-2) load 436822-1.html
 load 436823.html
 load 436969-1.html
 load 437156-1.html
 load 437565-1.xhtml
 load 437565-2.xhtml
 load 437565-3.xhtml
 load 438259-1.html
 load 438266-1.html
@@ -254,18 +254,18 @@ load 461294-1.html
 load 463350-1.html
 load 463350-2.html
 load 463350-3.html
 load 463741-1.html
 load 465651-1.html
 load 467137-1.html
 load 467213-1.html
 load 467487-1.html
-load 467493-1.html
-load 467493-2.html
+asserts(11-12) load 467493-1.html
+asserts(10-11) load 467493-2.html
 load 467875-1.xhtml
 load 467914-1.html
 load 468207-1.html
 load 468771-1.xhtml
 load 468771-2.xhtml
 load 469859-1.xhtml
 load 472587-1.xhtml
 load 472617-1.xhtml
@@ -273,17 +273,17 @@ load 472774-1.html
 load 472776-1.html
 load 472950-1.html
 load 473278-1.xhtml
 load 473894-1.html
 load 476241-1.html
 load 477731-1.html
 load 477928.html
 load 478131-1.html
-load 478170-1.html
+asserts(4) load 478170-1.html
 load 478185-1.html
 asserts-if(!Android,1) load 479938-1.html # Bug 575011
 load 480345-1.html
 skip-if(Android) load 481921.html
 load 489462-1.html
 load 489480-1.xhtml
 load 493111-1.html
 load 493118-1.html
@@ -304,40 +304,40 @@ load 505912-1.html
 load 509749-1.html
 load 511482.html
 load 512724-1.html
 load 512725-1.html
 load 512749-1.html
 load 513394-1.html
 load 514098-1.xhtml
 load 514800-1.html
-load 515811-1.html
+asserts(1) load 515811-1.html
 load 517968.html
 load 519031.xhtml
 load 520340.html
 load 533379-1.html
 load 533379-2.html
 load 534082-1.html
 load 534366-1.html
 load 534366-2.html
 load 536692-1.xhtml
 load 541277-1.html
 load 541277-2.html
-load 541714-1.html
-load 541714-2.html
+asserts(4) load 541714-1.html
+asserts(5-6) load 541714-2.html
 load 542136-1.html
 load 545571-1.html
 load 547338.xul
 load 547843-1.xhtml
 load 551635-1.html
 asserts(5) load 553504-1.xhtml # nscoord_MAX assertions (bug 575011)
 load 564368-1.xhtml
 load 564968.xhtml
 load 570160.html
-load 570289-1.html
+asserts(2) load 570289-1.html
 load 571618-1.svg
 asserts(1) load 571975-1.html # bug 574889
 load 574958.xhtml
 asserts(0-4) load 578977.html # bug 610331
 load 580504-1.xhtml
 load 585598-1.xhtml
 asserts(0-11) load 586806-1.html # Bug 439258
 load 586806-2.html
@@ -367,17 +367,17 @@ load 656130-1.html
 load 656130-2.html
 load 660416.html
 load 660451-1.html
 load 665853.html
 load text-overflow-form-elements.html
 load text-overflow-iframe.html
 load text-overflow-bug666751-1.html
 load text-overflow-bug666751-2.html
-asserts(2) load text-overflow-bug670564.xhtml # asserts(2) for bug 436470
+asserts(0-1) load text-overflow-bug670564.xhtml
 load text-overflow-bug671796.xhtml
 load 667025.html
 asserts-if(Android,8) load 673770.html
 load 679933-1.html
 load 682649-1.html
 load 683702-1.xhtml
 load 688996-1.html
 load 688996-2.html
--- a/layout/generic/nsBlockFrame.cpp
+++ b/layout/generic/nsBlockFrame.cpp
@@ -1473,34 +1473,25 @@ nsBlockFrame::ComputeOverflowAreas(const
     // the line-box's overflow areas. However, if the line is a block
     // line then it won't; if there are no lines, it won't. So just
     // factor it in anyway (it can't hurt if it was already done).
     // XXXldb Can we just fix GetOverflowArea instead?
     if (mBullet) {
       areas.UnionAllWith(mBullet->GetRect());
     }
 
-    // Factor in the bottom edge of the children. Child frames
-    // will be added to the overflow area as we iterate through the lines,
-    // but their margins won't, so we need to account for bottom margins
-    // here. If we're a scrolled block then we also need to account
-    // for the scrollframe's padding, which is logically below the
-    // bottom margins of the children.
-    nscoord bottomEdgeOfContents = aBottomEdgeOfChildren;
-    if (GetStyleContext()->GetPseudo() == nsCSSAnonBoxes::scrolledContent) {
-      // We're a scrolled frame; the scrollframe's padding should be added
-      // to the bottom edge of the children
-      bottomEdgeOfContents += aReflowState.mComputedPadding.bottom;
-    }
+    // Factor in the bottom edge of the children.  Child frames will be added
+    // to the overflow area as we iterate through the lines, but their margins
+    // won't, so we need to account for bottom margins here.
     // REVIEW: For now, we do this for both visual and scrollable area,
     // although when we make scrollable overflow area not be a subset of
     // visual, we can change this.
     NS_FOR_FRAME_OVERFLOW_TYPES(otype) {
       nsRect& o = areas.Overflow(otype);
-      o.height = NS_MAX(o.YMost(), bottomEdgeOfContents) - o.y;
+      o.height = NS_MAX(o.YMost(), aBottomEdgeOfChildren) - o.y;
     }
   }
 #ifdef NOISY_COMBINED_AREA
   ListTag(stdout);
   printf(": ca=%d,%d,%d,%d\n", area.x, area.y, area.width, area.height);
 #endif
 
   aMetrics.mOverflowAreas = areas;
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -6559,19 +6559,24 @@ nsIFrame::FinishAndStoreOverflow(nsOverf
     } else if (initial != &aOverflowAreas) {
       *initial = aOverflowAreas;
     }
   }
 
   // This is now called FinishAndStoreOverflow() instead of 
   // StoreOverflow() because frame-generic ways of adding overflow
   // can happen here, e.g. CSS2 outline and native theme.
+  // If the overflow area width or height is nscoord_MAX, then a
+  // saturating union may have encounted an overflow, so the overflow may not
+  // contain the frame border-box. Don't warn in that case.
   NS_FOR_FRAME_OVERFLOW_TYPES(otype) {
+    DebugOnly<nsRect*> r = &aOverflowAreas.Overflow(otype);
     NS_ASSERTION(aNewSize.width == 0 || aNewSize.height == 0 ||
-                 aOverflowAreas.Overflow(otype).Contains(nsRect(nsPoint(0,0), aNewSize)),
+                 r->width == nscoord_MAX || r->height == nscoord_MAX ||
+                 r->Contains(nsRect(nsPoint(0,0), aNewSize)),
                  "Computed overflow area must contain frame bounds");
   }
 
   // If we clip our children, clear accumulated overflow area. The
   // children are actually clipped to the padding-box, but since the
   // overflow area should include the entire border-box, just set it to
   // the border-box here.
   const nsStyleDisplay *disp = GetStyleDisplay();
@@ -6588,16 +6593,27 @@ nsIFrame::FinishAndStoreOverflow(nsOverf
   // even if the frame rect is empty.
   // Pending a real fix for bug 426879, don't do this for inline frames
   // with zero width.
   if (aNewSize.width != 0 || !IsInlineFrame(this)) {
     NS_FOR_FRAME_OVERFLOW_TYPES(otype) {
       nsRect& o = aOverflowAreas.Overflow(otype);
       o.UnionRectEdges(o, bounds);
     }
+
+    if (!nsLayoutUtils::IsPopup(this)) {
+      // Include margin in scrollable overflow.
+      // XXX In theory this should consider margin collapsing
+      nsRect marginBounds(bounds);
+      nsMargin margin = GetUsedMargin();
+      ApplySkipSides(margin);
+      marginBounds.SaturatingInflate(margin);
+      nsRect& so = aOverflowAreas.ScrollableOverflow();
+      so.SaturatingUnionRectEdges(so, marginBounds);
+    }
   }
 
   // Note that NS_STYLE_OVERFLOW_CLIP doesn't clip the frame background,
   // so we add theme background overflow here so it's not clipped.
   if (!IsBoxWrapped() && IsThemed(disp)) {
     nsRect r(bounds);
     nsPresContext *presContext = PresContext();
     if (presContext->GetTheme()->
--- a/layout/reftests/box-properties/abspos-non-replaced-width-offset-margin-ref.html
+++ b/layout/reftests/box-properties/abspos-non-replaced-width-offset-margin-ref.html
@@ -1,16 +1,16 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html401/strict.dtd">
 <html>
 <head>
 <title>Test, CSS 2.1, section 10.3.7</title>
 <style type="text/css">
 
 html, body { margin: 0; padding: 0; border: none; }
-div { height: 1px; background: navy; }
+div { height: 1px; background: navy; margin-right: 19px; }
 
 </style>
 </head>
 <body>
 
 <!-- ***** NARROW WIDTH ***** -->
 
 <!-- nothing auto -->
--- a/layout/reftests/box-properties/abspos-replaced-width-offset-margin-ref.html
+++ b/layout/reftests/box-properties/abspos-replaced-width-offset-margin-ref.html
@@ -1,17 +1,17 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html401/strict.dtd">
 <html>
 <head>
 <title>Test, CSS 2.1, section 10.3.8</title>
 <style type="text/css">
 
 html, body { margin: 0; padding: 0; border: none; }
 div { height: 1px; background: blue;
-      border-left: 7px solid navy; border-right: 17px solid navy; }
+      border-left: 7px solid navy; border-right: 17px solid navy; margin-right: 19px; }
 
 </style>
 </head>
 <body>
 
 <!-- ***** WIDE WIDTH ***** -->
 
 <!-- nothing auto -->
--- a/layout/reftests/bugs/403519-2-ref.html
+++ b/layout/reftests/bugs/403519-2-ref.html
@@ -4,17 +4,17 @@
 <style>
 td {
   border: 1px solid black;
   background-color: lime;
 }
 table {
   border: 1px solid black;
   background-color: red;
-  width: 500px;
+  width: 200px;
   border-spacing: 0;
 }
 </style>
 </head>
 <body>
 <table>
   <tbody><tr>
     <td colspan="2" style="width: 100%;"><div>&nbsp;</div></td>
--- a/layout/reftests/bugs/403519-2.html
+++ b/layout/reftests/bugs/403519-2.html
@@ -4,17 +4,17 @@
 <style>
 td {
   border: 1px solid black;
   background-color: lime;
 }
 table {
   border: 1px solid black;
   background-color: red;
-  width: 500px;
+  width: 200px;
   border-spacing: 0;
 }
 </style>
 </head>
 <body>
 <table>
   <tbody><tr>
     <td colspan="2"><div style="margin: 0 100%;">&nbsp;</div></td>
--- a/layout/reftests/bugs/458296-1-ref.html
+++ b/layout/reftests/bugs/458296-1-ref.html
@@ -1,10 +1,10 @@
 <!DOCTYPE HTML>
 <html>
 <body>
 <div style="overflow:auto; width:300px; height:300px; background:green;">
   <div style="height:100px;"></div>
-  <div style="height:200px; margin-left:100px; width:100px; background:yellow;"></div>
+  <div style="height:200px; margin-left:100px; margin-right:100px; width:100px; background:yellow;"></div>
   <div style="height:100px;"></div>
 </div>
 </body>
 </html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/458296-1a-ref.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML>
+<html>
+<body>
+<div style="overflow:auto; width:300px; height:300px; background:green;">
+  <div style="height:100px;"></div>
+  <div style="height:200px; margin-left:100px; margin-right:100px; width:100px; background:yellow;"></div>
+</div>
+</body>
+</html>
--- a/layout/reftests/bugs/458296-1c.html
+++ b/layout/reftests/bugs/458296-1c.html
@@ -1,10 +1,10 @@
 <!DOCTYPE HTML>
 <html>
 <body>
 <div style="overflow:auto; width:300px; height:300px; background:green;">
   <div style="height:100px; margin-top:100px;">
-    <div style="height:200px; margin-left:100px; width:100px; margin-bottom:100px; background:yellow;"></div>
+    <div style="height:200px; margin-left:100px; width:100px; margin-bottom:100px; margin-right:100px; background:yellow;"></div>
   </div>
 </div>
 </body>
 </html>
--- a/layout/reftests/bugs/458296-1d.html
+++ b/layout/reftests/bugs/458296-1d.html
@@ -1,8 +1,8 @@
 <!DOCTYPE HTML>
 <html>
 <body>
 <div style="overflow:auto; width:300px; height:300px; background:green;">
-  <div style="height:200px; margin-left:100px; width:100px; margin-top:100px; float:left; margin-bottom:100px; background:yellow;"></div>
+  <div style="height:200px; margin:100px; width:100px; float:left; background:yellow;"></div>
 </div>
 </body>
 </html>
--- a/layout/reftests/bugs/665597-1-ref.html
+++ b/layout/reftests/bugs/665597-1-ref.html
@@ -8,16 +8,16 @@
 
 #content {
   height: 223px;
   margin-right: 5px;
   margin-left: 11px;
   background: aqua;
 }
 #gap {
-  height: 42px;
+  height: 35px;
 }
 
 </style>
 <div id="scroll"><div id="content"></div><div id="gap"></div></div>
 <script>
 document.getElementById("scroll").scrollTop = "1000";
 </script>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/665597-2-ref.html
@@ -0,0 +1,17 @@
+<!DOCTYPE HTML>
+<html><head>
+    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+    <title>Testcase for bug 665597</title>
+    <style type="text/css">
+
+.o { width:100px; height:100px; padding:100px; background:green; }	
+.i { width:100px; height:200px; background:yellow; }
+
+    </style>
+</head>
+<body>
+<div class="o" style="overflow:visible">
+  <div class="i"></div>
+</div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/665597-2.html
@@ -0,0 +1,17 @@
+<!DOCTYPE HTML>
+<html><head>
+    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+    <title>Testcase for bug 665597</title>
+    <style type="text/css">
+
+.o { width:100px; height:100px; padding:100px; background:green; }	
+.i { width:100px; height:200px; background:yellow; }
+
+    </style>
+</head>
+<body>
+<div class="o" style="overflow:auto">
+  <div class="i"></div>
+</div>
+</body>
+</html>
--- a/layout/reftests/bugs/reftest.list
+++ b/layout/reftests/bugs/reftest.list
@@ -1191,17 +1191,17 @@ fails-if(cocoaWidget) == 456147.xul 4561
 == 456219-1a.html 456219-1-ref.html
 == 456219-1b.html 456219-1-ref.html
 == 456219-1c.html 456219-1-ref.html
 == 456219-2.html 456219-2-ref.html
 == 456330-1.gif 456330-1-ref.png
 == 456484-1.html 456484-1-ref.html
 == 457398-1.html 457398-1-ref.html
 == 457398-2.html 457398-2-ref.html
-== 458296-1a.html 458296-1-ref.html
+== 458296-1a.html 458296-1a-ref.html
 == 458296-1b.html 458296-1-ref.html
 == 458296-1c.html 458296-1-ref.html
 == 458296-1d.html 458296-1-ref.html
 == 458487-1a.html 458487-1-ref.html
 == 458487-1b.html 458487-1-ref.html
 == 458487-1c.html 458487-1-ref.html
 == 458487-1d.html 458487-1-ref.html
 == 458487-1e.html 458487-1-ref.html
@@ -1562,17 +1562,17 @@ fails-if(Android) random-if(layersGPUAcc
 == 580160-1.html 580160-1-ref.html
 fails-if(/^Windows\x20NT\x205\.1/.test(http.oscpu)) HTTP(..) == 580863-1.html 580863-1-ref.html # bug 623454
 fails-if(Android) random-if(layersGPUAccelerated) fails-if(/^Windows\x20NT\x205\.1/.test(http.oscpu))  == 581317-1.html 581317-1-ref.html # bug 623456 for WinXP
 == 581579-1.html 581579-1-ref.html
 == 582037-1a.html 582037-1-ref.html
 == 582037-1b.html 582037-1-ref.html
 == 582037-2a.html 582037-2-ref.html
 == 582037-2b.html 582037-2-ref.html
-asserts(0-1) == 582146-1.html about:blank
+asserts(0-11) == 582146-1.html about:blank
 == 582476-1.svg 582476-1-ref.svg
 == 584400-dash-length.svg 584400-dash-length-ref.svg
 == 584699-1.html 584699-1-ref.html
 == 585598-2.xhtml 585598-2-ref.xhtml
 == 586400-1.html 586400-1-ref.html
 fails-if(Android) fails-if(cocoaWidget) == 586683-1.html 586683-1-ref.html
 == 589615-1a.xhtml 589615-1-ref.html
 == 589615-1b.html 589615-1-ref.html
@@ -1661,16 +1661,17 @@ fails-if(layersGPUAccelerated&&cocoaWidg
 == 652775-1.html 652775-1-ref.html
 == 655549-1.html 655549-1-ref.html
 == 655836-1.html 655836-1-ref.html
 != 656875.html about:blank
 == 658952.html 658952-ref.html
 == 664127-1.xul 664127-1-ref.xul
 == 660682-1.html 660682-1-ref.html
 == 665597-1.html 665597-1-ref.html
+== 665597-2.html 665597-2-ref.html
 != 669015-1.xul 669015-1-notref.xul
 == 668319-1.xul about:blank
 == 670442-1.html 670442-1-ref.html
 == 670467-1.html 670467-1-ref.html
 == 670467-2.html 670467-2-ref.html
 == 690164-1.html 690164-1-ref.html
 != 691087-1.html 691087-1-ref.html
 == 691571-1.html 691571-1-ref.html
--- a/layout/reftests/forms/progress/bar-pseudo-element-vertical-ref.html
+++ b/layout/reftests/forms/progress/bar-pseudo-element-vertical-ref.html
@@ -12,19 +12,19 @@
     body > div:nth-child(5) > .progress-bar { }
     body > div:nth-child(6) > .progress-bar { height: -moz-calc(100% - 10px); }
     body > div:nth-child(7) > .progress-bar { position: relative; left: 10px; }
     body > div:nth-child(8) > .progress-bar { }
     body > div:nth-child(9) > .progress-bar { }
     body > div:nth-child(10) > .progress-bar { }
     body > div:nth-child(11) > .progress-bar { }
     /* 12 - 15 should have 100% width, no need to specify. */
-    body > div:nth-child(16) > .progress-bar { position: relative; top: 64px; left: 64px;
-                                               height: -moz-calc(100% - 32px);
-                                               width: -moz-calc(100% + 128px - 1em); }
+    body > div:nth-of-type(16) > .progress-bar { position: relative; top: 64px; left: 64px;
+                                                 height: -moz-calc(100% - 32px);
+                                                 width: -moz-calc(100% + 128px - 1em); }
   </style>
   <body>
     <div class="progress-element vertical">
       <div class="progress-bar">
       </div>
     </div>
     <div class="progress-element vertical">
       <div class="progress-bar">
@@ -77,14 +77,14 @@
     <div class="progress-element vertical">
       <div class="progress-bar">
       </div>
     </div>
     <div class="progress-element vertical">
       <div class="progress-bar">
       </div>
     </div>
-    <div class="progress-element vertical">
+    <br><div class="progress-element vertical">
       <div class="progress-bar">
       </div>
     </div>
   </body>
 </html>
--- a/layout/reftests/forms/progress/bar-pseudo-element-vertical-rtl-ref.html
+++ b/layout/reftests/forms/progress/bar-pseudo-element-vertical-rtl-ref.html
@@ -12,20 +12,20 @@
     body > div:nth-child(5) > .progress-bar { }
     body > div:nth-child(6) > .progress-bar { height: -moz-calc(100% - 10px); }
     body > div:nth-child(7) > .progress-bar { position: relative; left: 10px; }
     body > div:nth-child(8) > .progress-bar { }
     body > div:nth-child(9) > .progress-bar { }
     body > div:nth-child(10) > .progress-bar {  }
     body > div:nth-child(11) > .progress-bar { }
     /* 12 - 15 should have 100% width, no need to specify. */
-    body > div:nth-child(16) > .progress-bar { position: relative; top: 64px;
-                                               left: -moz-calc(100% + 128px + 32px );
-                                               height: -moz-calc(100% - 32px);
-                                               width: -moz-calc(100% + 128px - 1em); }
+    body > div:nth-of-type(16) > .progress-bar { position: relative; top: 64px;
+                                                 left: -moz-calc(100% + 128px + 32px );
+                                                 height: -moz-calc(100% - 32px);
+                                                 width: -moz-calc(100% + 128px - 1em); }
   </style>
   <body dir='rtl'>
     <div class="progress-element vertical">
       <div class="progress-bar">
       </div>
     </div>
     <div class="progress-element vertical">
       <div class="progress-bar">
@@ -78,14 +78,14 @@
     <div class="progress-element vertical">
       <div class="progress-bar">
       </div>
     </div>
     <div class="progress-element vertical">
       <div class="progress-bar">
       </div>
     </div>
-    <div class="progress-element vertical">
+    <br><div class="progress-element vertical">
       <div class="progress-bar">
       </div>
     </div>
   </body>
 </html>
--- a/layout/reftests/forms/progress/bar-pseudo-element-vertical-rtl.html
+++ b/layout/reftests/forms/progress/bar-pseudo-element-vertical-rtl.html
@@ -16,17 +16,17 @@
     body > progress:nth-child(8)::-moz-progress-bar { margin: 0px; padding: 10px 0px 0px 0px; }
     body > progress:nth-child(9)::-moz-progress-bar { margin: 0px; padding: 0px 10px 0px 0px; }
     body > progress:nth-child(10)::-moz-progress-bar { margin: 0px; padding: 0px 0px 10px 0px; }
     body > progress:nth-child(11)::-moz-progress-bar { margin: 0px; padding: 0px 0px 0px 10px; }
     body > progress:nth-child(12)::-moz-progress-bar { height: 1000px; }
     body > progress:nth-child(13)::-moz-progress-bar { height: 10px; }
     body > progress:nth-child(14)::-moz-progress-bar { height: 10%; }
     body > progress:nth-child(15)::-moz-progress-bar { height: 200%; }
-    body > progress:nth-child(16)::-moz-progress-bar { margin: 64px; padding: 64px; }
+    body > progress:nth-of-type(16)::-moz-progress-bar { margin: 64px; padding: 64px; }
   </style>
   <body dir='rtl'>
     <!-- Those will be used to change padding/margin on ::-moz-progress-bar -->
     <progress value='1'></progress>
     <progress value='1'></progress>
     <progress value='1'></progress>
     <progress value='1'></progress>
     <progress value='1'></progress>
@@ -36,11 +36,11 @@
     <progress value='1'></progress>
     <progress value='1'></progress>
     <progress value='1'></progress>
     <progress value='1'></progress>
     <!-- Those will be used to change width. -->
     <progress value='1'></progress>
     <progress value='1'></progress>
     <progress value='1'></progress>
-    <progress value='1'></progress>
+    <br><progress value='1'></progress>
   </body>
 </html>
--- a/layout/reftests/forms/progress/bar-pseudo-element-vertical.html
+++ b/layout/reftests/forms/progress/bar-pseudo-element-vertical.html
@@ -16,17 +16,17 @@
     body > progress:nth-child(8)::-moz-progress-bar { margin: 0px; padding: 10px 0px 0px 0px; }
     body > progress:nth-child(9)::-moz-progress-bar { margin: 0px; padding: 0px 10px 0px 0px; }
     body > progress:nth-child(10)::-moz-progress-bar { margin: 0px; padding: 0px 0px 10px 0px; }
     body > progress:nth-child(11)::-moz-progress-bar { margin: 0px; padding: 0px 0px 0px 10px; }
     body > progress:nth-child(12)::-moz-progress-bar { height: 1000px; }
     body > progress:nth-child(13)::-moz-progress-bar { height: 10px; }
     body > progress:nth-child(14)::-moz-progress-bar { height: 10%; }
     body > progress:nth-child(15)::-moz-progress-bar { height: 200%; }
-    body > progress:nth-child(16)::-moz-progress-bar { margin: 64px; padding: 64px; }
+    body > progress:nth-of-type(16)::-moz-progress-bar { margin: 64px; padding: 64px; }
   </style>
   <body>
     <!-- Those will be used to change padding/margin on ::-moz-progress-bar -->
     <progress value='1'></progress>
     <progress value='1'></progress>
     <progress value='1'></progress>
     <progress value='1'></progress>
     <progress value='1'></progress>
@@ -36,11 +36,11 @@
     <progress value='1'></progress>
     <progress value='1'></progress>
     <progress value='1'></progress>
     <progress value='1'></progress>
     <!-- Those will be used to change width. -->
     <progress value='1'></progress>
     <progress value='1'></progress>
     <progress value='1'></progress>
-    <progress value='1'></progress>
+    <br><progress value='1'></progress>
   </body>
 </html>
--- a/layout/reftests/margin-collapsing/block-overflow-3-ref.html
+++ b/layout/reftests/margin-collapsing/block-overflow-3-ref.html
@@ -2,25 +2,26 @@
 <html>
 <head>
 <style type="text/css">
 .a {
  height: 20px;
  background-color: green;
 }
 #b {
- height: 120px;
+ height: 160px;
  margin-top: 20px;
  margin-bottom: 20px;
- padding: 40px 0;
+ padding-top: 40px;
  background-color: green;
  overflow-y: scroll;
 }
 #c {
  height: 160px;
+ margin-bottom: 40px;
  background-color: blue;
 }
 </style>
 </head>
 <body>
 <div class="a"></div>
 <div id="b">
  <div id="c"></div>
--- a/layout/reftests/margin-collapsing/block-overflow-4-ref.html
+++ b/layout/reftests/margin-collapsing/block-overflow-4-ref.html
@@ -2,25 +2,26 @@
 <html>
 <head>
 <style type="text/css">
 .a {
  height: 20px;
  background-color: green;
 }
 #b {
- height: 120px;
+ height: 160px;
  margin-top: 20px;
  margin-bottom: 20px;
- padding: 40px 0;
+ padding-top: 40px;
  background-color: green;
  overflow: auto;
 }
 #c {
  height: 160px;
+ margin-bottom: 40px;
  background-color: blue;
 }
 </style>
 </head>
 <body>
 <div class="a"></div>
 <div id="b">
  <div id="c"></div>
--- a/layout/tables/nsTableCellFrame.cpp
+++ b/layout/tables/nsTableCellFrame.cpp
@@ -231,30 +231,27 @@ nsTableCellFrame::AttributeChanged(PRInt
   // BasicTableLayoutStrategy
   if (aNameSpaceID == kNameSpaceID_None && aAttribute == nsGkAtoms::nowrap &&
       PresContext()->CompatibilityMode() == eCompatibility_NavQuirks) {
     PresContext()->PresShell()->
       FrameNeedsReflow(this, nsIPresShell::eTreeChange, NS_FRAME_IS_DIRTY);
   }
   // let the table frame decide what to do
   nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this);
-  if (tableFrame) {
-    tableFrame->AttributeChangedFor(this, mContent, aAttribute);
-  }
+  tableFrame->AttributeChangedFor(this, mContent, aAttribute);
   return NS_OK;
 }
 
 /* virtual */ void
 nsTableCellFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
 {
   if (!aOldStyleContext) //avoid this on init
     return;
 
   nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this);
-
   if (tableFrame->IsBorderCollapse() &&
       tableFrame->BCRecalcNeeded(aOldStyleContext, GetStyleContext())) {
     PRInt32 colIndex, rowIndex;
     GetColIndex(colIndex);
     GetRowIndex(rowIndex);
     // row span needs to be clamped as we do not create rows in the cellmap
     // which do not have cells originating in them
     nsRect damageArea(colIndex, rowIndex, GetColSpan(), NS_MIN(GetRowSpan(),
@@ -438,17 +435,16 @@ nsTableCellFrame::BuildDisplayList(nsDis
                                    const nsRect&           aDirtyRect,
                                    const nsDisplayListSet& aLists)
 {
   if (!IsVisibleInSelection(aBuilder))
     return NS_OK;
 
   DO_GLOBAL_REFLOW_COUNT_DSP("nsTableCellFrame");
   nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this);
-
   PRInt32 emptyCellStyle = GetContentEmpty() && !tableFrame->IsBorderCollapse() ?
                               GetStyleTableBorder()->mEmptyCells
                               : NS_STYLE_TABLE_EMPTY_CELLS_SHOW;
   // take account of 'empty-cells'
   if (GetStyleVisibility()->IsVisible() &&
       (NS_STYLE_TABLE_EMPTY_CELLS_HIDE != emptyCellStyle)) {
 
 
@@ -819,21 +815,16 @@ NS_METHOD nsTableCellFrame::Reflow(nsPre
   }
 
   // see if a special height reflow needs to occur due to having a pct height
   nsTableFrame::CheckRequestSpecialHeightReflow(aReflowState);
 
   aStatus = NS_FRAME_COMPLETE;
   nsSize availSize(aReflowState.availableWidth, aReflowState.availableHeight);
 
-  /* It's the 'border-collapse' on the table that matters */
-  nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this);
-  if (!tableFrame)
-    ABORT1(NS_ERROR_NULL_POINTER);
-
   nsMargin borderPadding = aReflowState.mComputedPadding;
   nsMargin border;
   GetBorderWidth(border);
   borderPadding += border;
 
   nscoord topInset    = borderPadding.top;
   nscoord rightInset  = borderPadding.right;
   nscoord bottomInset = borderPadding.bottom;
@@ -849,16 +840,17 @@ NS_METHOD nsTableCellFrame::Reflow(nsPre
   if (availSize.height < 0)
     availSize.height = 1;
 
   nsHTMLReflowMetrics kidSize(aDesiredSize.mFlags);
   kidSize.width = kidSize.height = 0;
   SetPriorAvailWidth(aReflowState.availableWidth);
   nsIFrame* firstKid = mFrames.FirstChild();
   NS_ASSERTION(firstKid, "Frame construction error, a table cell always has an inner cell frame");
+  nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this);
 
   if (aReflowState.mFlags.mSpecialHeightReflow) {
     const_cast<nsHTMLReflowState&>(aReflowState).SetComputedHeight(mRect.height - topInset - bottomInset);
     DISPLAY_REFLOW_CHANGE();
   }
   else if (aPresContext->IsPaginated()) {
     nscoord computedUnpaginatedHeight =
       CalcUnpaginagedHeight(aPresContext, (nsTableCellFrame&)*this,
--- a/layout/tables/nsTableColFrame.cpp
+++ b/layout/tables/nsTableColFrame.cpp
@@ -85,23 +85,21 @@ nsTableColFrame::SetColType(nsTableColTy
 
 /* virtual */ void
 nsTableColFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
 {
   if (!aOldStyleContext) //avoid this on init
     return;
      
   nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this);
-    
   if (tableFrame->IsBorderCollapse() &&
       tableFrame->BCRecalcNeeded(aOldStyleContext, GetStyleContext())) {
     nsRect damageArea = nsRect(GetColIndex(), 0, 1, tableFrame->GetRowCount());
     tableFrame->AddBCDamageArea(damageArea);
   }
-  return;
 }
 
 void nsTableColFrame::SetContinuousBCBorderWidth(PRUint8     aForSide,
                                                  BCPixelSize aPixelValue)
 {
   switch (aForSide) {
     case NS_SIDE_TOP:
       mTopContBorderWidth = aPixelValue;
@@ -125,19 +123,17 @@ NS_METHOD nsTableColFrame::Reflow(nsPres
   DO_GLOBAL_REFLOW_COUNT("nsTableColFrame");
   DISPLAY_REFLOW(aPresContext, this, aReflowState, aDesiredSize, aStatus);
   aDesiredSize.width=0;
   aDesiredSize.height=0;
   const nsStyleVisibility* colVis = GetStyleVisibility();
   bool collapseCol = (NS_STYLE_VISIBILITY_COLLAPSE == colVis->mVisible);
   if (collapseCol) {
     nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this);
-    if (tableFrame)  {
-      tableFrame->SetNeedToCollapse(true);
-    }    
+    tableFrame->SetNeedToCollapse(true);
   }
   aStatus = NS_FRAME_COMPLETE;
   NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
   return NS_OK;
 }
 
 PRInt32 nsTableColFrame::GetSpan()
 {
--- a/layout/tables/nsTableColGroupFrame.cpp
+++ b/layout/tables/nsTableColGroupFrame.cpp
@@ -97,20 +97,17 @@ void nsTableColGroupFrame::ResetColIndic
 }
 
 
 nsresult
 nsTableColGroupFrame::AddColsToTable(PRInt32                   aFirstColIndex,
                                      bool                      aResetSubsequentColIndices,
                                      const nsFrameList::Slice& aCols)
 {
-  nsresult rv = NS_OK;
   nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this);
-  if (!tableFrame)
-    return NS_ERROR_NULL_POINTER;
 
   // set the col indices of the col frames and and add col info to the table
   PRInt32 colIndex = aFirstColIndex;
   nsFrameList::Enumerator e(aCols);
   for (; !e.AtEnd(); e.Next()) {
     ((nsTableColFrame*)e.get())->SetColIndex(colIndex);
     mColCount++;
     tableFrame->InsertCol((nsTableColFrame &)*e.get(), colIndex);
@@ -127,17 +124,17 @@ nsTableColGroupFrame::AddColsToTable(PRI
   // We have already set the colindex for all the colframes in this
   // colgroup that come after the first inserted colframe, but there could
   // be other colgroups following this one and their colframes need
   // correct colindices too.
   if (aResetSubsequentColIndices && GetNextSibling()) {
     ResetColIndices(GetNextSibling(), colIndex);
   }
 
-  return rv;
+  return NS_OK;
 }
 
 
 nsTableColGroupFrame*
 nsTableColGroupFrame::GetLastRealColGroup(nsTableFrame* aTableFrame)
 {
   nsFrameList colGroups = aTableFrame->GetColGroups();
 
@@ -172,19 +169,16 @@ nsTableColGroupFrame::SetInitialChildLis
     return NS_ERROR_UNEXPECTED;
   }
   if (aListID != kPrincipalList) {
     // All we know about is the principal child list.
     NS_NOTREACHED("unknown frame list");
     return NS_ERROR_INVALID_ARG;
   } 
   nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this);
-  if (!tableFrame)
-    return NS_ERROR_NULL_POINTER;
-
   if (aChildList.IsEmpty()) {
     tableFrame->AppendAnonymousColFrames(this, GetSpan(), eColAnonymousColGroup, 
                                          false);
     return NS_OK; 
   }
 
   mFrames.AppendFrames(this, aChildList);
   return NS_OK;
@@ -192,27 +186,25 @@ nsTableColGroupFrame::SetInitialChildLis
 
 /* virtual */ void
 nsTableColGroupFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
 {
   if (!aOldStyleContext) //avoid this on init
     return;
      
   nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this);
-
   if (tableFrame->IsBorderCollapse() &&
       tableFrame->BCRecalcNeeded(aOldStyleContext, GetStyleContext())) {
     PRInt32 colCount = GetColCount();
     if (!colCount)
       return; // this is a degenerated colgroup 
     nsRect damageArea(GetFirstColumn()->GetColIndex(), 0, colCount,
                       tableFrame->GetRowCount());
     tableFrame->AddBCDamageArea(damageArea);
   }
-  return;
 }
 
 NS_IMETHODIMP
 nsTableColGroupFrame::AppendFrames(ChildListID     aListID,
                                    nsFrameList&    aFrameList)
 {
   NS_ASSERTION(aListID == kPrincipalList, "unexpected child list");
 
@@ -354,19 +346,16 @@ nsTableColGroupFrame::RemoveFrame(ChildL
       }
     }
     
     PRInt32 colIndex = colFrame->GetColIndex();
     // The RemoveChild call handles calling FrameNeedsReflow on us.
     RemoveChild(*colFrame, true);
     
     nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this);
-    if (!tableFrame)
-      return NS_ERROR_NULL_POINTER;
-
     tableFrame->RemoveCol(this, colIndex, true, true);
     if (mFrames.IsEmpty() && contentRemoval && 
         GetColType() == eColGroupContent) {
       tableFrame->AppendAnonymousColFrames(this, GetSpan(),
                                            eColAnonymousColGroup, true);
     }
   }
   else {
@@ -398,19 +387,17 @@ NS_METHOD nsTableColGroupFrame::Reflow(n
   DISPLAY_REFLOW(aPresContext, this, aReflowState, aDesiredSize, aStatus);
   NS_ASSERTION(nsnull!=mContent, "bad state -- null content for frame");
   nsresult rv=NS_OK;
   
   const nsStyleVisibility* groupVis = GetStyleVisibility();
   bool collapseGroup = (NS_STYLE_VISIBILITY_COLLAPSE == groupVis->mVisible);
   if (collapseGroup) {
     nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this);
-    if (tableFrame)  {
-      tableFrame->SetNeedToCollapse(true);;
-    }
+    tableFrame->SetNeedToCollapse(true);
   }
   // for every content child that (is a column thingy and does not already have a frame)
   // create a frame and adjust it's style
   
   for (nsIFrame *kidFrame = mFrames.FirstChild(); kidFrame;
        kidFrame = kidFrame->GetNextSibling()) {
     // Give the child frame a chance to reflow, even though we know it'll have 0 size
     nsHTMLReflowMetrics kidSize;
@@ -482,17 +469,16 @@ void nsTableColGroupFrame::GetContinuous
   PRInt32 aPixelsToTwips = nsPresContext::AppUnitsPerCSSPixel();
   nsTableFrame* table = nsTableFrame::GetTableFrame(this);
   nsTableColFrame* col = table->GetColFrame(mStartColIndex + mColCount - 1);
   col->GetContinuousBCBorderWidth(aBorder);
   aBorder.top = BC_BORDER_BOTTOM_HALF_COORD(aPixelsToTwips,
                                             mTopContBorderWidth);
   aBorder.bottom = BC_BORDER_TOP_HALF_COORD(aPixelsToTwips,
                                             mBottomContBorderWidth);
-  return;
 }
 
 /* ----- global methods ----- */
 
 nsIFrame*
 NS_NewTableColGroupFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) nsTableColGroupFrame(aContext);
--- a/layout/tables/nsTableFrame.cpp
+++ b/layout/tables/nsTableFrame.cpp
@@ -183,49 +183,45 @@ nsTableFrame::GetType() const
 }
 
 
 nsTableFrame::nsTableFrame(nsStyleContext* aContext)
   : nsContainerFrame(aContext),
     mCellMap(nsnull),
     mTableLayoutStrategy(nsnull)
 {
-  mBits.mHaveReflowedColGroups  = false;
-  mBits.mCellSpansPctCol        = false;
-  mBits.mNeedToCalcBCBorders    = false;
-  mBits.mIsBorderCollapse       = false;
-  mBits.mResizedColumns         = false; // only really matters if splitting
-  mBits.mGeometryDirty          = false;
+  memset(&mBits, 0, sizeof(mBits));
 }
 
 NS_QUERYFRAME_HEAD(nsTableFrame)
   NS_QUERYFRAME_ENTRY(nsITableLayout)
 NS_QUERYFRAME_TAIL_INHERITING(nsContainerFrame)
 
 NS_IMETHODIMP
 nsTableFrame::Init(nsIContent*      aContent,
                    nsIFrame*        aParent,
                    nsIFrame*        aPrevInFlow)
 {
-  nsresult  rv;
+  NS_PRECONDITION(!mCellMap, "Init called twice");
+  NS_PRECONDITION(!aPrevInFlow ||
+                  aPrevInFlow->GetType() == nsGkAtoms::tableFrame,
+                  "prev-in-flow must be of same type");
 
   // Let the base class do its processing
-  rv = nsContainerFrame::Init(aContent, aParent, aPrevInFlow);
+  nsresult rv = nsContainerFrame::Init(aContent, aParent, aPrevInFlow);
 
   // see if border collapse is on, if so set it
   const nsStyleTableBorder* tableStyle = GetStyleTableBorder();
   bool borderCollapse = (NS_STYLE_BORDER_COLLAPSE == tableStyle->mBorderCollapse);
   SetBorderCollapse(borderCollapse);
-  // Create the cell map
+  // Create the cell map if this frame is the first-in-flow.
   if (!aPrevInFlow) {
     mCellMap = new nsTableCellMap(*this, borderCollapse);
     if (!mCellMap)
       return NS_ERROR_OUT_OF_MEMORY;
-  } else {
-    mCellMap = nsnull;
   }
 
   if (aPrevInFlow) {
     // set my width, because all frames in a table flow are the same width and
     // code in nsTableOuterFrame depends on this being set
     mRect.width = aPrevInFlow->GetSize().width;
   }
   else {
@@ -237,28 +233,20 @@ nsTableFrame::Init(nsIContent*      aCon
       mTableLayoutStrategy = new FixedTableLayoutStrategy(this);
     if (!mTableLayoutStrategy)
       return NS_ERROR_OUT_OF_MEMORY;
   }
 
   return rv;
 }
 
-
 nsTableFrame::~nsTableFrame()
 {
-  if (nsnull!=mCellMap) {
-    delete mCellMap;
-    mCellMap = nsnull;
-  }
-
-  if (nsnull!=mTableLayoutStrategy) {
-    delete mTableLayoutStrategy;
-    mTableLayoutStrategy = nsnull;
-  }
+  delete mCellMap;
+  delete mTableLayoutStrategy;
 }
 
 void
 nsTableFrame::DestroyFrom(nsIFrame* aDestructRoot)
 {
   mColGroups.DestroyFramesFrom(aDestructRoot);
   nsContainerFrame::DestroyFrom(aDestructRoot);
 }
@@ -2036,40 +2024,40 @@ nsTableFrame::GetCollapsedWidth(nsMargin
     }
   }
   return width;
 }
 
 /* virtual */ void
 nsTableFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
 {
-   if (!aOldStyleContext) //avoid this on init
-     return;
-
-   if (IsBorderCollapse() &&
-       BCRecalcNeeded(aOldStyleContext, GetStyleContext())) {
-     SetFullBCDamageArea();
-   }
-
-   //avoid this on init or nextinflow
-   if (!mTableLayoutStrategy || GetPrevInFlow())
-     return;
-
-   bool isAuto = IsAutoLayout();
-   if (isAuto != (LayoutStrategy()->GetType() == nsITableLayoutStrategy::Auto)) {
-     nsITableLayoutStrategy* temp;
-     if (isAuto)
-       temp = new BasicTableLayoutStrategy(this);
-     else
-       temp = new FixedTableLayoutStrategy(this);
-
-     if (temp) {
-       delete mTableLayoutStrategy;
-       mTableLayoutStrategy = temp;
-     }
+  if (!aOldStyleContext) //avoid this on init
+    return;
+
+  if (IsBorderCollapse() &&
+      BCRecalcNeeded(aOldStyleContext, GetStyleContext())) {
+    SetFullBCDamageArea();
+  }
+
+  //avoid this on init or nextinflow
+  if (!mTableLayoutStrategy || GetPrevInFlow())
+    return;
+
+  bool isAuto = IsAutoLayout();
+  if (isAuto != (LayoutStrategy()->GetType() == nsITableLayoutStrategy::Auto)) {
+    nsITableLayoutStrategy* temp;
+    if (isAuto)
+      temp = new BasicTableLayoutStrategy(this);
+    else
+      temp = new FixedTableLayoutStrategy(this);
+
+    if (temp) {
+      delete mTableLayoutStrategy;
+      mTableLayoutStrategy = temp;
+    }
   }
 }
 
 
 
 NS_IMETHODIMP
 nsTableFrame::AppendFrames(ChildListID     aListID,
                            nsFrameList&    aFrameList)
@@ -3302,30 +3290,22 @@ nsTableFrame::DistributeHeightToRows(con
     yOriginRG = yEndRG;
   }
 
   ResizeCells(*this);
 }
 
 PRInt32 nsTableFrame::GetColumnWidth(PRInt32 aColIndex)
 {
-  nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow();
-  NS_ASSERTION(firstInFlow, "illegal state -- no first in flow");
-  PRInt32 result = 0;
+  nsTableFrame* firstInFlow = static_cast<nsTableFrame*>(GetFirstInFlow());
   if (this == firstInFlow) {
     nsTableColFrame* colFrame = GetColFrame(aColIndex);
-    if (colFrame) {
-      result = colFrame->GetFinalWidth();
-    }
-  }
-  else {
-    result = firstInFlow->GetColumnWidth(aColIndex);
-  }
-
-  return result;
+    return colFrame ? colFrame->GetFinalWidth() : 0;
+  }
+  return firstInFlow->GetColumnWidth(aColIndex);
 }
 
 // XXX: could cache this.  But be sure to check style changes if you do!
 nscoord nsTableFrame::GetCellSpacingX()
 {
   if (IsBorderCollapse())
     return 0;
 
@@ -3367,28 +3347,25 @@ nsIFrame*
 NS_NewTableFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) nsTableFrame(aContext);
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsTableFrame)
 
 nsTableFrame*
-nsTableFrame::GetTableFrame(nsIFrame* aSourceFrame)
-{
-  if (aSourceFrame) {
-    // "result" is the result of intermediate calls, not the result we return from this method
-    for (nsIFrame* parentFrame = aSourceFrame->GetParent(); parentFrame;
-         parentFrame = parentFrame->GetParent()) {
-      if (nsGkAtoms::tableFrame == parentFrame->GetType()) {
-        return (nsTableFrame*)parentFrame;
-      }
-    }
-  }
-  NS_NOTREACHED("unable to find table parent");
+nsTableFrame::GetTableFrame(nsIFrame* aFrame)
+{
+  for (nsIFrame* ancestor = aFrame->GetParent(); ancestor;
+       ancestor = ancestor->GetParent()) {
+    if (nsGkAtoms::tableFrame == ancestor->GetType()) {
+      return static_cast<nsTableFrame*>(ancestor);
+    }
+  }
+  NS_RUNTIMEABORT("unable to find table parent");
   return nsnull;
 }
 
 bool
 nsTableFrame::IsAutoHeight()
 {
   const nsStyleCoord &height = GetStylePosition()->mHeight;
   // Don't consider calc() here like this quirk for percent.
@@ -3584,24 +3561,18 @@ void nsTableIterator::Init(nsIFrame* aFi
   mLeftToRight    = true;
   mCount          = -1;
 
   if (!mFirstChild) {
     return;
   }
 
   nsTableFrame* table = nsTableFrame::GetTableFrame(mFirstChild);
-  if (table) {
-    mLeftToRight = (NS_STYLE_DIRECTION_LTR ==
-                    table->GetStyleVisibility()->mDirection);
-  }
-  else {
-    NS_NOTREACHED("source of table iterator is not part of a table");
-    return;
-  }
+  mLeftToRight = (NS_STYLE_DIRECTION_LTR ==
+                  table->GetStyleVisibility()->mDirection);
 
   if (!mLeftToRight) {
     mCount = 0;
     nsIFrame* nextChild = mFirstChild->GetNextSibling();
     while (nsnull != nextChild) {
       mCount++;
       mFirstChild = nextChild;
       nextChild = nextChild->GetNextSibling();
@@ -6228,29 +6199,27 @@ BCPaintBorderIterator::SetDamageArea(nsR
        nsPresContext::CSSPixelsToAppUnits(rowFrame->GetTopBCBorderWidth() + 1);
       nscoord bottomBorderHalf = (mTable->GetNextInFlow()) ? 0 :
         nsPresContext::CSSPixelsToAppUnits(rowFrame->GetBottomBCBorderWidth() + 1);
       // get the row rect relative to the table rather than the row group
       nsSize rowSize = rowFrame->GetSize();
       if (haveIntersect) {
         if (aDirtyRect.YMost() >= (rowY - topBorderHalf)) {
           nsTableRowFrame* fifRow =
-            (nsTableRowFrame*)rowFrame->GetFirstInFlow();
-          if (!fifRow) ABORT1(false);
+            static_cast<nsTableRowFrame*>(rowFrame->GetFirstInFlow());
           endRowIndex = fifRow->GetRowIndex();
         }
         else done = true;
       }
       else {
         if ((rowY + rowSize.height + bottomBorderHalf) >= aDirtyRect.y) {
           mStartRg  = rgFrame;
           mStartRow = rowFrame;
           nsTableRowFrame* fifRow =
-            (nsTableRowFrame*)rowFrame->GetFirstInFlow();
-          if (!fifRow) ABORT1(false);
+            static_cast<nsTableRowFrame*>(rowFrame->GetFirstInFlow());
           startRowIndex = endRowIndex = fifRow->GetRowIndex();
           haveIntersect = true;
         }
         else {
           mInitialOffsetY += rowSize.height;
         }
       }
       rowY += rowSize.height;
--- a/layout/tables/nsTableRowFrame.cpp
+++ b/layout/tables/nsTableRowFrame.cpp
@@ -186,35 +186,33 @@ nsTableRowFrame::Init(nsIContent*      a
 
 /* virtual */ void
 nsTableRowFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
 {
   if (!aOldStyleContext) //avoid this on init
     return;
      
   nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this);
-    
   if (tableFrame->IsBorderCollapse() &&
       tableFrame->BCRecalcNeeded(aOldStyleContext, GetStyleContext())) {
     nsRect damageArea(0, GetRowIndex(), tableFrame->GetColCount(), 1);
     tableFrame->AddBCDamageArea(damageArea);
   }
-  return;
 }
 
 NS_IMETHODIMP
 nsTableRowFrame::AppendFrames(ChildListID     aListID,
                               nsFrameList&    aFrameList)
 {
   NS_ASSERTION(aListID == kPrincipalList, "unexpected child list");
 
   const nsFrameList::Slice& newCells = mFrames.AppendFrames(nsnull, aFrameList);
 
   // Add the new cell frames to the table
-  nsTableFrame *tableFrame =  nsTableFrame::GetTableFrame(this);
+  nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this);
   for (nsFrameList::Enumerator e(newCells) ; !e.AtEnd(); e.Next()) {
     nsIFrame *childFrame = e.get();
     NS_ASSERTION(IS_TABLE_CELL(childFrame->GetType()),"Not a table cell frame/pseudo frame construction failure");
     tableFrame->AppendCell(static_cast<nsTableCellFrame&>(*childFrame), GetRowIndex());
   }
 
   PresContext()->PresShell()->FrameNeedsReflow(this, nsIPresShell::eTreeChange,
                                                NS_FRAME_HAS_DIRTY_CHILDREN);
@@ -232,18 +230,17 @@ nsTableRowFrame::InsertFrames(ChildListI
   NS_ASSERTION(aListID == kPrincipalList, "unexpected child list");
   NS_ASSERTION(!aPrevFrame || aPrevFrame->GetParent() == this,
                "inserting after sibling frame with different parent");
   //Insert Frames in the frame list
   const nsFrameList::Slice& newCells = mFrames.InsertFrames(nsnull, aPrevFrame, aFrameList);
 
   // Get the table frame
   nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this);
-  
-  nsIAtom* cellFrameType = (tableFrame->IsBorderCollapse()) ? nsGkAtoms::bcTableCellFrame : nsGkAtoms::tableCellFrame;
+  nsIAtom* cellFrameType = tableFrame->IsBorderCollapse() ? nsGkAtoms::bcTableCellFrame : nsGkAtoms::tableCellFrame;
   nsTableCellFrame* prevCellFrame = (nsTableCellFrame *)nsTableFrame::GetFrameAtOrBefore(this, aPrevFrame, cellFrameType);
   nsTArray<nsTableCellFrame*> cellChildren;
   for (nsFrameList::Enumerator e(newCells); !e.AtEnd(); e.Next()) {
     nsIFrame *childFrame = e.get();
     NS_ASSERTION(IS_TABLE_CELL(childFrame->GetType()),"Not a table cell frame/pseudo frame construction failure");
     cellChildren.AppendElement(static_cast<nsTableCellFrame*>(childFrame));
   }
   // insert the cells into the cell map
@@ -262,36 +259,34 @@ nsTableRowFrame::InsertFrames(ChildListI
 
 NS_IMETHODIMP
 nsTableRowFrame::RemoveFrame(ChildListID     aListID,
                              nsIFrame*       aOldFrame)
 {
   NS_ASSERTION(aListID == kPrincipalList, "unexpected child list");
 
   nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this);
-  if (tableFrame) {
-    nsTableCellFrame *cellFrame = do_QueryFrame(aOldFrame);
-    if (cellFrame) {
-      PRInt32 colIndex;
-      cellFrame->GetColIndex(colIndex);
-      // remove the cell from the cell map
-      tableFrame->RemoveCell(cellFrame, GetRowIndex());
+  nsTableCellFrame *cellFrame = do_QueryFrame(aOldFrame);
+  if (cellFrame) {
+    PRInt32 colIndex;
+    cellFrame->GetColIndex(colIndex);
+    // remove the cell from the cell map
+    tableFrame->RemoveCell(cellFrame, GetRowIndex());
 
-      // Remove the frame and destroy it
-      mFrames.DestroyFrame(aOldFrame);
+    // Remove the frame and destroy it
+    mFrames.DestroyFrame(aOldFrame);
 
-      PresContext()->PresShell()->
-        FrameNeedsReflow(this, nsIPresShell::eTreeChange,
-                         NS_FRAME_HAS_DIRTY_CHILDREN);
-      tableFrame->SetGeometryDirty();
-    }
-    else {
-      NS_ERROR("unexpected frame type");
-      return NS_ERROR_INVALID_ARG;
-    }
+    PresContext()->PresShell()->
+      FrameNeedsReflow(this, nsIPresShell::eTreeChange,
+                       NS_FRAME_HAS_DIRTY_CHILDREN);
+    tableFrame->SetGeometryDirty();
+  }
+  else {
+    NS_ERROR("unexpected frame type");
+    return NS_ERROR_INVALID_ARG;
   }
 
   return NS_OK;
 }
 
 /* virtual */ nsMargin
 nsTableRowFrame::GetUsedMargin() const
 {
@@ -347,19 +342,16 @@ nsTableRowFrame::GetFirstCell()
 /**
  * Post-reflow hook. This is where the table row does its post-processing
  */
 void
 nsTableRowFrame::DidResize()
 {
   // Resize and re-align the cell frames based on our row height
   nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this);
-  if (!tableFrame)
-    return;
-  
   nsTableIterator iter(*this);
   nsIFrame* childFrame = iter.First();
   
   nsHTMLReflowMetrics desiredSize;
   desiredSize.width = mRect.width;
   desiredSize.height = mRect.height;
   desiredSize.SetOverflowAreasToDesiredBounds();
 
@@ -516,19 +508,16 @@ nsTableRowFrame::UpdateHeight(nscoord   
     }
   }
 }
 
 nscoord
 nsTableRowFrame::CalcHeight(const nsHTMLReflowState& aReflowState)
 {
   nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this);
-  if (!tableFrame)
-    return 0;
-
   nscoord computedHeight = (NS_UNCONSTRAINEDSIZE == aReflowState.ComputedHeight())
                             ? 0 : aReflowState.ComputedHeight();
   ResetHeight(computedHeight);
 
   const nsStylePosition* position = GetStylePosition();
   if (eStyleUnit_Coord == position->mHeight.GetUnit()) {
     SetFixedHeight(position->mHeight.GetCoordValue());
   }
@@ -579,19 +568,19 @@ public:
 
   virtual void Paint(nsDisplayListBuilder* aBuilder,
                      nsRenderingContext* aCtx);
   NS_DISPLAY_DECL_NAME("TableRowBackground", TYPE_TABLE_ROW_BACKGROUND)
 };
 
 void
 nsDisplayTableRowBackground::Paint(nsDisplayListBuilder* aBuilder,
-                                   nsRenderingContext* aCtx) {
+                                   nsRenderingContext* aCtx)
+{
   nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(mFrame);
-
   TableBackgroundPainter painter(tableFrame,
                                  TableBackgroundPainter::eOrigin_TableRow,
                                  mFrame->PresContext(), *aCtx,
                                  mVisibleRect, ToReferenceFrame(),
                                  aBuilder->GetBackgroundPaintFlags());
   painter.PaintRow(static_cast<nsTableRowFrame*>(mFrame));
 }
 
@@ -641,19 +630,16 @@ nsTableRowFrame::CalculateCellActualHeig
                                            nscoord&          aDesiredHeight)
 {
   nscoord specifiedHeight = 0;
   
   // Get the height specified in the style information
   const nsStylePosition* position = aCellFrame->GetStylePosition();
 
   nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this);
-  if (!tableFrame)
-    return NS_ERROR_NULL_POINTER;
-  
   PRInt32 rowSpan = tableFrame->GetEffectiveRowSpan(*aCellFrame);
   
   switch (position->mHeight.GetUnit()) {
     case eStyleUnit_Coord:
       specifiedHeight = position->mHeight.GetCoordValue();
       if (1 == rowSpan) 
         SetFixedHeight(specifiedHeight);
       break;
@@ -760,18 +746,18 @@ GetSpaceBetween(PRInt32       aPrevColIn
 }
 
 // subtract the heights of aRow's prev in flows from the unpaginated height
 static
 nscoord CalcHeightFromUnpaginatedHeight(nsPresContext*   aPresContext,
                                         nsTableRowFrame& aRow)
 {
   nscoord height = 0;
-  nsTableRowFrame* firstInFlow = (nsTableRowFrame*)aRow.GetFirstInFlow();
-  if (!firstInFlow) ABORT1(0);
+  nsTableRowFrame* firstInFlow =
+    static_cast<nsTableRowFrame*>(aRow.GetFirstInFlow());
   if (firstInFlow->HasUnpaginatedHeight()) {
     height = firstInFlow->GetUnpaginatedHeight(aPresContext);
     for (nsIFrame* prevInFlow = aRow.GetPrevInFlow(); prevInFlow;
          prevInFlow = prevInFlow->GetPrevInFlow()) {
       height -= prevInFlow->GetSize().height;
     }
   }
   return NS_MAX(height, 0);
@@ -781,23 +767,20 @@ nsresult
 nsTableRowFrame::ReflowChildren(nsPresContext*          aPresContext,
                                 nsHTMLReflowMetrics&     aDesiredSize,
                                 const nsHTMLReflowState& aReflowState,
                                 nsTableFrame&            aTableFrame,
                                 nsReflowStatus&          aStatus)
 {
   aStatus = NS_FRAME_COMPLETE;
 
-  bool borderCollapse = (((nsTableFrame*)aTableFrame.GetFirstInFlow())->IsBorderCollapse());
-
   // XXXldb Should we be checking constrained height instead?
-  bool isPaginated = aPresContext->IsPaginated();
-
+  const bool isPaginated = aPresContext->IsPaginated();
+  const bool borderCollapse = aTableFrame.IsBorderCollapse();
   nsresult rv = NS_OK;
-
   nscoord cellSpacingX = aTableFrame.GetCellSpacingX();
   PRInt32 cellColSpan = 1;  // must be defined here so it's set properly for non-cell kids
   
   nsTableIterator iter(*this);
   // remember the col index of the previous cell to handle rowspans into this row
   PRInt32 firstPrevColIndex = (iter.IsLeftToRight()) ? -1 : aTableFrame.GetColCount();
   PRInt32 prevColIndex  = firstPrevColIndex;
   nscoord x = 0; // running total of children x offset
@@ -1027,19 +1010,16 @@ nsTableRowFrame::Reflow(nsPresContext*  
                         const nsHTMLReflowState& aReflowState,
                         nsReflowStatus&          aStatus)
 {
   DO_GLOBAL_REFLOW_COUNT("nsTableRowFrame");
   DISPLAY_REFLOW(aPresContext, this, aReflowState, aDesiredSize, aStatus);
   nsresult rv = NS_OK;
 
   nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this);
-  if (!tableFrame)
-    return NS_ERROR_NULL_POINTER;
-
   const nsStyleVisibility* rowVis = GetStyleVisibility();
   bool collapseRow = (NS_STYLE_VISIBILITY_COLLAPSE == rowVis->mVisible);
   if (collapseRow) {
     tableFrame->SetNeedToCollapse(true);
   }
 
   // see if a special height reflow needs to occur due to having a pct height
   nsTableFrame::CheckRequestSpecialHeightReflow(aReflowState);
@@ -1071,26 +1051,23 @@ nsTableRowFrame::Reflow(nsPresContext*  
 nscoord 
 nsTableRowFrame::ReflowCellFrame(nsPresContext*          aPresContext,
                                  const nsHTMLReflowState& aReflowState,
                                  bool                     aIsTopOfPage,
                                  nsTableCellFrame*        aCellFrame,
                                  nscoord                  aAvailableHeight,
                                  nsReflowStatus&          aStatus)
 {
-  nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this);
-  if (!tableFrame)
-    ABORT1(NS_ERROR_NULL_POINTER);
-
   // Reflow the cell frame with the specified height. Use the existing width
   nsRect cellRect = aCellFrame->GetRect();
   nsRect cellVisualOverflow = aCellFrame->GetVisualOverflowRect();
   
-  nsSize  availSize(cellRect.width, aAvailableHeight);
-  bool borderCollapse = ((nsTableFrame*)tableFrame->GetFirstInFlow())->IsBorderCollapse();
+  nsSize availSize(cellRect.width, aAvailableHeight);
+  nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this);
+  bool borderCollapse = tableFrame->IsBorderCollapse();
   nsTableCellReflowState cellReflowState(aPresContext, aReflowState,
                                          aCellFrame, availSize, false);
   InitChildReflowState(*aPresContext, availSize, borderCollapse, cellReflowState);
   cellReflowState.mFlags.mIsTopOfPage = aIsTopOfPage;
 
   nsHTMLReflowMetrics desiredSize;
 
   ReflowChild(aCellFrame, aPresContext, desiredSize, cellReflowState,
@@ -1121,19 +1098,18 @@ nsTableRowFrame::ReflowCellFrame(nsPresC
 nscoord
 nsTableRowFrame::CollapseRowIfNecessary(nscoord aRowOffset,
                                         nscoord aWidth,
                                         bool    aCollapseGroup,
                                         bool& aDidCollapse)
 {
   const nsStyleVisibility* rowVis = GetStyleVisibility();
   bool collapseRow = (NS_STYLE_VISIBILITY_COLLAPSE == rowVis->mVisible);
-  nsTableFrame* tableFrame = static_cast<nsTableFrame*>(nsTableFrame::GetTableFrame(this)->GetFirstInFlow());
-  if (!tableFrame)
-      return 0;
+  nsTableFrame* tableFrame = static_cast<nsTableFrame*>(
+    nsTableFrame::GetTableFrame(this)->GetFirstInFlow());
   if (collapseRow) {
     tableFrame->SetNeedToCollapse(true);
   }
 
   if (aRowOffset != 0) {
     // We're moving, so invalidate our old position
     InvalidateFrameSubtree();
   }
--- a/layout/tables/nsTableRowGroupFrame.cpp
+++ b/layout/tables/nsTableRowGroupFrame.cpp
@@ -91,19 +91,17 @@ PRInt32 nsTableRowGroupFrame::GetStartRo
   if (mFrames.NotEmpty()) {
     NS_ASSERTION(mFrames.FirstChild()->GetType() == nsGkAtoms::tableRowFrame,
                  "Unexpected frame type");
     result = static_cast<nsTableRowFrame*>(mFrames.FirstChild())->GetRowIndex();
   }
   // if the row group doesn't have any children, get it the hard way
   if (-1 == result) {
     nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this);
-    if (tableFrame) {
-      return tableFrame->GetStartRowIndex(this);
-    }
+    return tableFrame->GetStartRowIndex(this);
   }
       
   return result;
 }
 
 void  nsTableRowGroupFrame::AdjustRowIndices(PRInt32 aRowIndex,
                                              PRInt32 anAdjustment)
 {
@@ -173,19 +171,19 @@ public:
   virtual void Paint(nsDisplayListBuilder* aBuilder,
                      nsRenderingContext* aCtx);
 
   NS_DISPLAY_DECL_NAME("TableRowGroupBackground", TYPE_TABLE_ROW_GROUP_BACKGROUND)
 };
 
 void
 nsDisplayTableRowGroupBackground::Paint(nsDisplayListBuilder* aBuilder,
-                                        nsRenderingContext* aCtx) {
+                                        nsRenderingContext* aCtx)
+{
   nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(mFrame);
-
   TableBackgroundPainter painter(tableFrame,
                                  TableBackgroundPainter::eOrigin_TableRowGroup,
                                  mFrame->PresContext(), *aCtx,
                                  mVisibleRect, ToReferenceFrame(),
                                  aBuilder->GetBackgroundPaintFlags());
   painter.PaintRowGroup(static_cast<nsTableRowGroupFrame*>(mFrame));
 }
 
@@ -345,23 +343,18 @@ nsTableRowGroupFrame::ReflowChildren(nsP
                                      nsRowGroupReflowState& aReflowState,
                                      nsReflowStatus&        aStatus,
                                      bool*                aPageBreakBeforeEnd)
 {
   if (aPageBreakBeforeEnd) 
     *aPageBreakBeforeEnd = false;
 
   nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this);
-  if (!tableFrame)
-    ABORT1(NS_ERROR_NULL_POINTER);
-
   nsresult rv = NS_OK;
-
-  bool borderCollapse = tableFrame->IsBorderCollapse();
-
+  const bool borderCollapse = tableFrame->IsBorderCollapse();
   nscoord cellSpacingY = tableFrame->GetCellSpacingY();
 
   // XXXldb Should we really be checking this rather than available height?
   // (Think about multi-column layout!)
   bool isPaginated = aPresContext->IsPaginated() && 
                        NS_UNCONSTRAINEDSIZE != aReflowState.availSize.height;
 
   bool haveRow = false;
@@ -559,19 +552,17 @@ nsTableRowGroupFrame::DidResizeRows(nsHT
 // Even if rows don't change height, this method must be called to set the heights of each
 // cell in the row to the height of its row.
 void 
 nsTableRowGroupFrame::CalculateRowHeights(nsPresContext*           aPresContext, 
                                           nsHTMLReflowMetrics&     aDesiredSize,
                                           const nsHTMLReflowState& aReflowState)
 {
   nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this);
-  if (!tableFrame) return;
-
-  bool isPaginated = aPresContext->IsPaginated();
+  const bool isPaginated = aPresContext->IsPaginated();
 
   // all table cells have the same top and bottom margins, namely cellSpacingY
   nscoord cellSpacingY = tableFrame->GetCellSpacingY();
 
   PRInt32 numEffCols = tableFrame->GetEffectiveColCount();
 
   PRInt32 startRowIndex = GetStartRowIndex();
   // find the row corresponding to the row index we just found
@@ -839,17 +830,16 @@ nsTableRowGroupFrame::CalculateRowHeight
   aDesiredSize.height = rowGroupHeight; // Adjust our desired size
 }
 
 nscoord
 nsTableRowGroupFrame::CollapseRowGroupIfNecessary(nscoord aYTotalOffset,
                                                   nscoord aWidth)
 {
   nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this);
-
   const nsStyleVisibility* groupVis = GetStyleVisibility();
   bool collapseGroup = (NS_STYLE_VISIBILITY_COLLAPSE == groupVis->mVisible);
   if (collapseGroup) {
     tableFrame->SetNeedToCollapse(true);
   }
 
   nsOverflowAreas overflow;
 
@@ -946,18 +936,17 @@ nsTableRowGroupFrame::SplitSpanningCells
                                          nsTableRowFrame*&        aContRow,
                                          nsTableRowFrame*&        aFirstTruncatedRow,
                                          nscoord&                 aDesiredHeight)
 {
   NS_ASSERTION(aSpanningRowBottom >= 0, "Can't split negative heights");
   aFirstTruncatedRow = nsnull;
   aDesiredHeight     = 0;
 
-  bool borderCollapse =
-    static_cast<nsTableFrame*>(aTable.GetFirstInFlow())->IsBorderCollapse();
+  const bool borderCollapse = aTable.IsBorderCollapse();
   PRInt32 lastRowIndex = aLastRow.GetRowIndex();
   bool wasLast = false;
   bool haveRowSpan = false;
   // Iterate the rows between aFirstRow and aLastRow
   for (nsTableRowFrame* row = &aFirstRow; !wasLast; row = row->GetNextRow()) {
     wasLast = (row == &aLastRow);
     PRInt32 rowIndex = row->GetRowIndex();
     nsPoint rowPos = row->GetPosition();
@@ -1081,18 +1070,18 @@ nsTableRowGroupFrame::SplitRowGroup(nsPr
 
   nsresult rv = NS_OK;
   nsTableRowFrame* prevRowFrame = nsnull;
   aDesiredSize.height = 0;
 
   nscoord availWidth  = aReflowState.availableWidth;
   nscoord availHeight = aReflowState.availableHeight;
   
-  bool    borderCollapse = ((nsTableFrame*)aTableFrame->GetFirstInFlow())->IsBorderCollapse();
-  nscoord cellSpacingY   = aTableFrame->GetCellSpacingY();
+  const bool borderCollapse = aTableFrame->IsBorderCollapse();
+  nscoord cellSpacingY = aTableFrame->GetCellSpacingY();
   
   // get the page height
   nscoord pageHeight = aPresContext->GetPageSize().height;
   NS_ASSERTION(pageHeight != NS_UNCONSTRAINEDSIZE, 
                "The table shouldn't be split when there should be space");
 
   bool isTopOfPage = aReflowState.mFlags.mIsTopOfPage;
   nsTableRowFrame* firstRowThisPage = GetFirstRow();
@@ -1312,26 +1301,24 @@ nsTableRowGroupFrame::Reflow(nsPresConte
                              const nsHTMLReflowState& aReflowState,
                              nsReflowStatus&          aStatus)
 {
   DO_GLOBAL_REFLOW_COUNT("nsTableRowGroupFrame");
   DISPLAY_REFLOW(aPresContext, this, aReflowState, aDesiredSize, aStatus);
 
   nsresult rv = NS_OK;
   aStatus     = NS_FRAME_COMPLETE;
-        
-  nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this);
-  if (!tableFrame) return NS_ERROR_NULL_POINTER;
 
   // Row geometry may be going to change so we need to invalidate any row cursor.
   ClearRowCursor();
 
   // see if a special height reflow needs to occur due to having a pct height
   nsTableFrame::CheckRequestSpecialHeightReflow(aReflowState);
 
+  nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this);
   nsRowGroupReflowState state(aReflowState, tableFrame);
   const nsStyleVisibility* groupVis = GetStyleVisibility();
   bool collapseGroup = (NS_STYLE_VISIBILITY_COLLAPSE == groupVis->mVisible);
   if (collapseGroup) {
     tableFrame->SetNeedToCollapse(true);
   }
 
   // Check for an overflow list
@@ -1384,24 +1371,22 @@ nsTableRowGroupFrame::Reflow(nsPresConte
 
 /* virtual */ void
 nsTableRowGroupFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
 {
   if (!aOldStyleContext) //avoid this on init
     return;
      
   nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this);
-    
   if (tableFrame->IsBorderCollapse() &&
       tableFrame->BCRecalcNeeded(aOldStyleContext, GetStyleContext())) {
     nsRect damageArea(0, GetStartRowIndex(), tableFrame->GetColCount(),
                       GetRowCount());
     tableFrame->AddBCDamageArea(damageArea);
   }
-  return;
 }
 
 NS_IMETHODIMP
 nsTableRowGroupFrame::AppendFrames(ChildListID     aListID,
                                    nsFrameList&    aFrameList)
 {
   NS_ASSERTION(aListID == kPrincipalList, "unexpected child list");
 
@@ -1422,45 +1407,40 @@ nsTableRowGroupFrame::AppendFrames(Child
   }
 
   PRInt32 rowIndex = GetRowCount();
   // Append the frames to the sibling chain
   mFrames.AppendFrames(nsnull, aFrameList);
 
   if (rows.Length() > 0) {
     nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this);
-    if (tableFrame) {
-      tableFrame->AppendRows(this, rowIndex, rows);
-      PresContext()->PresShell()->
-        FrameNeedsReflow(this, nsIPresShell::eTreeChange,
-                         NS_FRAME_HAS_DIRTY_CHILDREN);
-      tableFrame->SetGeometryDirty();
-    }
+    tableFrame->AppendRows(this, rowIndex, rows);
+    PresContext()->PresShell()->
+      FrameNeedsReflow(this, nsIPresShell::eTreeChange,
+                       NS_FRAME_HAS_DIRTY_CHILDREN);
+    tableFrame->SetGeometryDirty();
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsTableRowGroupFrame::InsertFrames(ChildListID     aListID,
                                    nsIFrame*       aPrevFrame,
                                    nsFrameList&    aFrameList)
 {
   NS_ASSERTION(aListID == kPrincipalList, "unexpected child list");
   NS_ASSERTION(!aPrevFrame || aPrevFrame->GetParent() == this,
                "inserting after sibling frame with different parent");
 
   ClearRowCursor();
 
-  nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this);
-  if (!tableFrame)
-    return NS_ERROR_NULL_POINTER;
-
   // collect the new row frames in an array
   // XXXbz why are we doing the QI stuff?  There shouldn't be any non-rows here.
+  nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this);
   nsTArray<nsTableRowFrame*> rows;
   bool gotFirstRow = false;
   for (nsFrameList::Enumerator e(aFrameList); !e.AtEnd(); e.Next()) {
     nsTableRowFrame *rowFrame = do_QueryFrame(e.get());
     NS_ASSERTION(rowFrame, "Unexpected frame; frame constructor screwed up");
     if (rowFrame) {
       NS_ASSERTION(NS_STYLE_DISPLAY_TABLE_ROW ==
                      e.get()->GetStyleDisplay()->mDisplay,
@@ -1496,27 +1476,26 @@ NS_IMETHODIMP
 nsTableRowGroupFrame::RemoveFrame(ChildListID     aListID,
                                   nsIFrame*       aOldFrame)
 {
   NS_ASSERTION(aListID == kPrincipalList, "unexpected child list");
 
   ClearRowCursor();
 
   nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this);
-  if (tableFrame) {
-    nsTableRowFrame *rowFrame = do_QueryFrame(aOldFrame);
-    if (rowFrame) {
-      // remove the rows from the table (and flag a rebalance)
-      tableFrame->RemoveRows(*rowFrame, 1, true);
+  // XXX why are we doing the QI stuff?  There shouldn't be any non-rows here.
+  nsTableRowFrame* rowFrame = do_QueryFrame(aOldFrame);
+  if (rowFrame) {
+    // remove the rows from the table (and flag a rebalance)
+    tableFrame->RemoveRows(*rowFrame, 1, true);
 
-      PresContext()->PresShell()->
-        FrameNeedsReflow(this, nsIPresShell::eTreeChange,
-                         NS_FRAME_HAS_DIRTY_CHILDREN);
-      tableFrame->SetGeometryDirty();
-    }
+    PresContext()->PresShell()->
+      FrameNeedsReflow(this, nsIPresShell::eTreeChange,
+                       NS_FRAME_HAS_DIRTY_CHILDREN);
+    tableFrame->SetGeometryDirty();
   }
   mFrames.DestroyFrame(aOldFrame);
 
   return NS_OK;
 }
 
 /* virtual */ nsMargin
 nsTableRowGroupFrame::GetUsedMargin() const
@@ -1536,31 +1515,29 @@ nsTableRowGroupFrame::GetUsedPadding() c
   return nsMargin(0,0,0,0);
 }
 
 nscoord 
 nsTableRowGroupFrame::GetHeightBasis(const nsHTMLReflowState& aReflowState)
 {
   nscoord result = 0;
   nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this);
-  if (tableFrame) {
-    if ((aReflowState.ComputedHeight() > 0) && (aReflowState.ComputedHeight() < NS_UNCONSTRAINEDSIZE)) {
-      nscoord cellSpacing = NS_MAX(0, GetRowCount() - 1) * tableFrame->GetCellSpacingY();
-      result = aReflowState.ComputedHeight() - cellSpacing;
+  if ((aReflowState.ComputedHeight() > 0) && (aReflowState.ComputedHeight() < NS_UNCONSTRAINEDSIZE)) {
+    nscoord cellSpacing = NS_MAX(0, GetRowCount() - 1) * tableFrame->GetCellSpacingY();
+    result = aReflowState.ComputedHeight() - cellSpacing;
+  }
+  else {
+    const nsHTMLReflowState* parentRS = aReflowState.parentReflowState;
+    if (parentRS && (tableFrame != parentRS->frame)) {
+      parentRS = parentRS->parentReflowState;
     }
-    else {
-      const nsHTMLReflowState* parentRS = aReflowState.parentReflowState;
-      if (parentRS && (tableFrame != parentRS->frame)) {
-        parentRS = parentRS->parentReflowState;
-      }
-      if (parentRS && (tableFrame == parentRS->frame) && 
-          (parentRS->ComputedHeight() > 0) && (parentRS->ComputedHeight() < NS_UNCONSTRAINEDSIZE)) {
-        nscoord cellSpacing = NS_MAX(0, tableFrame->GetRowCount() + 1) * tableFrame->GetCellSpacingY();
-        result = parentRS->ComputedHeight() - cellSpacing;
-      }
+    if (parentRS && (tableFrame == parentRS->frame) && 
+        (parentRS->ComputedHeight() > 0) && (parentRS->ComputedHeight() < NS_UNCONSTRAINEDSIZE)) {
+      nscoord cellSpacing = NS_MAX(0, tableFrame->GetRowCount() + 1) * tableFrame->GetCellSpacingY();
+      result = parentRS->ComputedHeight() - cellSpacing;
     }
   }
 
   return result;
 }
 
 bool
 nsTableRowGroupFrame::IsSimpleRowFrame(nsTableFrame* aTableFrame,
--- a/mobile/android/base/GeckoApp.java
+++ b/mobile/android/base/GeckoApp.java
@@ -951,17 +951,19 @@ abstract public class GeckoApp
                         }
                     });
                 } else {
                     final JSONArray rect = message.getJSONArray("rect");
                     final double zoom = message.getDouble("zoom");
                     mMainHandler.post(new Runnable() {
                         public void run() {
                             // Don't show autocomplete popup when using fullscreen VKB
-                            if (!GeckoInputConnection.mIMELandscapeFS)
+                            InputMethodManager imm =
+                                (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
+                            if (!imm.isFullscreenMode())
                                 mAutoCompletePopup.show(suggestions, rect, zoom);
                         }
                     });
                 }
             } else if (event.equals("Permissions:Data")) {
                 String host = message.getString("host");
                 JSONArray permissions = message.getJSONArray("permissions");
                 showSiteSettingsDialog(host, permissions);
--- a/toolkit/content/tests/browser/browser_bug295977_autoscroll_overflow.js
+++ b/toolkit/content/tests/browser/browser_bug295977_autoscroll_overflow.js
@@ -75,17 +75,17 @@ function test()
     <div id="c" style="width: 100px; height: 100px; overflow-x: auto; overflow-y: hidden;"><div style="width: 200px; height: 200px;"></div></div>\
     <div id="d" style="width: 100px; height: 100px; overflow-y: auto; overflow-x: hidden;"><div style="width: 200px; height: 200px;"></div></div>\
     <select id="e" style="width: 100px; height: 100px;" multiple="multiple"><option>aaaaaaaaaaaaaaaaaaaaaaaa</option><option>a</option><option>a</option>\
     <option>a</option><option>a</option><option>a</option><option>a</option><option>a</option><option>a</option><option>a</option>\
     <option>a</option><option>a</option><option>a</option><option>a</option><option>a</option><option>a</option><option>a</option></select>\
     <select id="f" style="width: 100px; height: 100px;"><option>a</option><option>aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</option><option>a</option>\
     <option>a</option><option>a</option><option>a</option><option>a</option><option>a</option><option>a</option><option>a</option>\
     <option>a</option><option>a</option><option>a</option><option>a</option><option>a</option><option>a</option><option>a</option></select>\
-    <div id="g" style="width: 99px; height: 99px; padding: 10px; border: 10px solid black; margin: 10px; overflow: auto;"><div style="width: 100px; height: 100px;"></div></div>\
+    <div id="g" style="width: 99px; height: 99px; padding: 10px; border: 10px solid black; margin: 10px; overflow: auto;"><div style="width: 100px; height: 100px; margin: 10px;"></div></div>\
     <div id="h" style="width: 100px; height: 100px; overflow: -moz-hidden-unscrollable;"><div style="width: 200px; height: 200px;"></div></div>\
     <iframe id="iframe" style="display: none;"></iframe>\
     </body>';
   gBrowser.selectedBrowser.addEventListener("pageshow", onLoad, false);
   gBrowser.loadURI(dataUri);
 
   function onLoad() {
     gBrowser.selectedBrowser.removeEventListener("pageshow", onLoad, false);