Merge last PGO-green changeset of mozilla-inbound to mozilla-central
authorEd Morley <emorley@mozilla.com>
Tue, 08 May 2012 19:13:19 +0100
changeset 95757 75d817e6bf4d504d12e4ee4f626c762114dff69c
parent 95742 40b7177ea13a1cb9cff71adf2f4b24e763c1f434 (current diff)
parent 95756 3bc06857dcd2b2d18774cf662323e6c1f8cb3cbf (diff)
child 95758 5593fb2667192606d0d228cfc4f5223c081e736b
child 109758 e3b632e26dc04c0cf0226c8b2681a0d3243464ea
push id1439
push userlsblakk@mozilla.com
push dateMon, 04 Jun 2012 20:19:22 +0000
treeherdermozilla-aurora@ea74834dccd3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone15.0a1
Merge last PGO-green changeset of mozilla-inbound to mozilla-central
--- a/accessible/src/base/nsAccessNode.cpp
+++ b/accessible/src/base/nsAccessNode.cpp
@@ -44,35 +44,31 @@
 #include "nsCoreUtils.h"
 #include "RootAccessible.h"
 
 #include "nsIDocShell.h"
 #include "nsIDocShellTreeItem.h"
 #include "nsIDOMWindow.h"
 #include "nsIFrame.h"
 #include "nsIInterfaceRequestorUtils.h"
-#include "nsIPrefBranch.h"
-#include "nsIPrefService.h"
 #include "nsIPresShell.h"
 #include "nsIServiceManager.h"
 #include "nsIStringBundle.h"
 #include "nsFocusManager.h"
 #include "nsPresContext.h"
 #include "mozilla/Services.h"
 
 using namespace mozilla::a11y;
 
 /* For documentation of the accessibility architecture, 
  * see http://lxr.mozilla.org/seamonkey/source/accessible/accessible-docs.html
  */
 
 nsIStringBundle *nsAccessNode::gStringBundle = 0;
 
-bool nsAccessNode::gIsFormFillEnabled = false;
-
 ApplicationAccessible* nsAccessNode::gApplicationAccessible = nsnull;
 
 /*
  * Class nsAccessNode
  */
  
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccessible. nsISupports
@@ -157,21 +153,16 @@ void nsAccessNode::InitXPAccessibility()
 {
   nsCOMPtr<nsIStringBundleService> stringBundleService =
     mozilla::services::GetStringBundleService();
   if (stringBundleService) {
     // Static variables are released in ShutdownAllXPAccessibility();
     stringBundleService->CreateBundle(ACCESSIBLE_BUNDLE_URL, 
                                       &gStringBundle);
   }
-
-  nsCOMPtr<nsIPrefBranch> prefBranch(do_GetService(NS_PREFSERVICE_CONTRACTID));
-  if (prefBranch) {
-    prefBranch->GetBoolPref("browser.formfill.enable", &gIsFormFillEnabled);
-  }
 }
 
 void nsAccessNode::ShutdownXPAccessibility()
 {
   // Called by nsAccessibilityService::Shutdown()
   // which happens when xpcom is shutting down
   // at exit of program
 
--- a/accessible/src/base/nsAccessNode.h
+++ b/accessible/src/base/nsAccessNode.h
@@ -162,18 +162,16 @@ protected:
   void LastRelease();
 
   nsCOMPtr<nsIContent> mContent;
   nsDocAccessible* mDoc;
 
   // Static data, we do our own refcounting for our static data.
   static nsIStringBundle* gStringBundle;
 
-  static bool gIsFormFillEnabled;
-
 private:
   nsAccessNode() MOZ_DELETE;
   nsAccessNode(const nsAccessNode&) MOZ_DELETE;
   nsAccessNode& operator =(const nsAccessNode&) MOZ_DELETE;
   
   static ApplicationAccessible* gApplicationAccessible;
 };
 
--- a/accessible/src/base/nsAccessibilityService.cpp
+++ b/accessible/src/base/nsAccessibilityService.cpp
@@ -41,16 +41,17 @@
 // NOTE: alphabetically ordered
 #include "Accessible-inl.h"
 #include "ApplicationAccessibleWrap.h"
 #include "ARIAGridAccessibleWrap.h"
 #ifdef MOZ_ACCESSIBILITY_ATK
 #include "AtkSocketAccessible.h"
 #endif
 #include "FocusManager.h"
+#include "HTMLListAccessible.h"
 #include "nsAccessiblePivot.h"
 #include "nsAccUtils.h"
 #include "nsARIAMap.h"
 #include "nsIAccessibleProvider.h"
 #include "nsHTMLCanvasAccessible.h"
 #include "nsHTMLImageMapAccessible.h"
 #include "nsHTMLLinkAccessible.h"
 #include "nsHTMLSelectAccessible.h"
@@ -217,17 +218,17 @@ nsAccessibilityService::CreateHTMLButton
   return accessible;
 }
 
 already_AddRefed<nsAccessible>
 nsAccessibilityService::CreateHTMLLIAccessible(nsIContent* aContent,
                                                nsIPresShell* aPresShell)
 {
   nsAccessible* accessible = 
-    new nsHTMLLIAccessible(aContent, GetDocAccessible(aPresShell));
+    new HTMLLIAccessible(aContent, GetDocAccessible(aPresShell));
   NS_ADDREF(accessible);
   return accessible;
 }
 
 already_AddRefed<nsAccessible>
 nsAccessibilityService::CreateHyperTextAccessible(nsIContent* aContent,
                                                   nsIPresShell* aPresShell)
 {
@@ -594,17 +595,17 @@ void
 nsAccessibilityService::UpdateListBullet(nsIPresShell* aPresShell,
                                          nsIContent* aHTMLListItemContent,
                                          bool aHasBullet)
 {
   nsDocAccessible* document = GetDocAccessible(aPresShell);
   if (document) {
     nsAccessible* accessible = document->GetAccessible(aHTMLListItemContent);
     if (accessible) {
-      nsHTMLLIAccessible* listItem = accessible->AsHTMLListItem();
+      HTMLLIAccessible* listItem = accessible->AsHTMLListItem();
       if (listItem)
         listItem->UpdateBullet(aHasBullet);
     }
   }
 }
 
 void
 nsAccessibilityService::UpdateImageMap(nsImageFrame* aImageFrame)
@@ -1653,17 +1654,17 @@ nsAccessibilityService::CreateHTMLAccess
     nsAccessible* accessible = new nsHTMLSelectOptGroupAccessible(aContent,
                                                                   aDoc);
     NS_IF_ADDREF(accessible);
     return accessible;
   }
 
   if (tag == nsGkAtoms::ul || tag == nsGkAtoms::ol ||
       tag == nsGkAtoms::dl) {
-    nsAccessible* accessible = new nsHTMLListAccessible(aContent, aDoc);
+    nsAccessible* accessible = new HTMLListAccessible(aContent, aDoc);
     NS_IF_ADDREF(accessible);
     return accessible;
   }
 
   if (tag == nsGkAtoms::a) {
     // Only some roles truly enjoy life as nsHTMLLinkAccessibles, for details
     // see closed bug 494807.
     nsRoleMapEntry* roleMapEntry = aria::GetRoleMap(aContent);
@@ -1680,17 +1681,17 @@ nsAccessibilityService::CreateHTMLAccess
   }
 
   if (tag == nsGkAtoms::dt ||
       (tag == nsGkAtoms::li &&
        aFrame->GetType() != nsGkAtoms::blockFrame)) {
     // Normally for li, it is created by the list item frame (in nsBlockFrame)
     // which knows about the bullet frame; however, in this case the list item
     // must have been styled using display: foo
-    nsAccessible* accessible = new nsHTMLLIAccessible(aContent, aDoc);
+    nsAccessible* accessible = new HTMLLIAccessible(aContent, aDoc);
     NS_IF_ADDREF(accessible);
     return accessible;
   }
 
   if (tag == nsGkAtoms::abbr ||
       tag == nsGkAtoms::acronym ||
       tag == nsGkAtoms::blockquote ||
       tag == nsGkAtoms::dd ||
--- a/accessible/src/base/nsAccessible.h
+++ b/accessible/src/base/nsAccessible.h
@@ -57,22 +57,23 @@
 class AccEvent;
 class AccGroupInfo;
 class EmbeddedObjCollector;
 class KeyBinding;
 class nsAccessible;
 class nsHyperTextAccessible;
 class nsHTMLImageAccessible;
 class nsHTMLImageMapAccessible;
-class nsHTMLLIAccessible;
 struct nsRoleMapEntry;
 class Relation;
 
 namespace mozilla {
 namespace a11y {
+
+class HTMLLIAccessible;
 class TableAccessible;
 
 /**
  * Name type flags.
  */
 enum ENameValueFlag {
   /**
    * Name either
@@ -471,17 +472,17 @@ public:
   nsDocAccessible* AsDoc();
 
   inline bool IsHyperText() const { return mFlags & eHyperTextAccessible; }
   nsHyperTextAccessible* AsHyperText();
 
   inline bool IsHTMLFileInput() const { return mFlags & eHTMLFileInputAccessible; }
 
   inline bool IsHTMLListItem() const { return mFlags & eHTMLListItemAccessible; }
-  nsHTMLLIAccessible* AsHTMLListItem();
+  mozilla::a11y::HTMLLIAccessible* AsHTMLListItem();
 
   inline bool IsImageAccessible() const { return mFlags & eImageAccessible; }
   nsHTMLImageAccessible* AsImage();
 
   bool IsImageMapAccessible() const { return mFlags & eImageMapAccessible; }
   nsHTMLImageMapAccessible* AsImageMap();
 
   inline bool IsXULTree() const { return mFlags & eXULTreeAccessible; }
--- a/accessible/src/html/HTMLFormControlAccessible.cpp
+++ b/accessible/src/html/HTMLFormControlAccessible.cpp
@@ -58,16 +58,19 @@
 #include "nsIFrame.h"
 #include "nsINameSpaceManager.h"
 #include "nsISelectionController.h"
 #include "jsapi.h"
 #include "nsIJSContextStack.h"
 #include "nsIServiceManager.h"
 #include "nsITextControlFrame.h"
 
+#include "mozilla/Preferences.h"
+
+using namespace mozilla;
 using namespace mozilla::a11y;
 
 ////////////////////////////////////////////////////////////////////////////////
 // HTMLCheckboxAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
 HTMLCheckboxAccessible::
   HTMLCheckboxAccessible(nsIContent* aContent, nsDocAccessible* aDoc) :
@@ -491,17 +494,17 @@ HTMLTextFieldAccessible::NativeState()
   }
 
   // Expose autocomplete state if it has associated autocomplete list.
   if (mContent->HasAttr(kNameSpaceID_None, nsGkAtoms::list))
     return state | states::SUPPORTS_AUTOCOMPLETION;
 
   // No parent can mean a fake widget created for XUL textbox. If accessible
   // is unattached from tree then we don't care.
-  if (mParent && gIsFormFillEnabled) {
+  if (mParent && Preferences::GetBool("browser.formfill.enable")) {
     // Check to see if autocompletion is allowed on this input. We don't expose
     // it for password fields even though the entire password can be remembered
     // for a page if the user asks it to be. However, the kind of autocomplete
     // we're talking here is based on what the user types, where a popup of
     // possible choices comes up.
     nsAutoString autocomplete;
     mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::autocomplete,
                       autocomplete);
copy from accessible/src/html/nsHTMLTextAccessible.cpp
copy to accessible/src/html/HTMLListAccessible.cpp
--- a/accessible/src/html/nsHTMLTextAccessible.cpp
+++ b/accessible/src/html/HTMLListAccessible.cpp
@@ -1,360 +1,165 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is mozilla.org code.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   Aaron Leventhal (aaronl@netscape.com)
- *   Kyle Yuan (kyle.yuan@sun.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 ***** */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include "nsHTMLTextAccessible.h"
+#include "HTMLListAccessible.h"
 
 #include "nsDocAccessible.h"
-#include "nsAccUtils.h"
-#include "nsTextEquivUtils.h"
-#include "Relation.h"
 #include "Role.h"
 #include "States.h"
 
-#include "nsIAccessibleRelation.h"
-#include "nsIFrame.h"
-#include "nsPresContext.h"
 #include "nsBlockFrame.h"
-#include "nsISelection.h"
-#include "nsISelectionController.h"
-#include "nsComponentManagerUtils.h"
 
+using namespace mozilla;
 using namespace mozilla::a11y;
 
 ////////////////////////////////////////////////////////////////////////////////
-// nsHTMLTextAccessible
+// HTMLListAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
-nsHTMLTextAccessible::
-  nsHTMLTextAccessible(nsIContent* aContent, nsDocAccessible* aDoc) :
-  nsTextAccessibleWrap(aContent, aDoc)
-{
-}
-
-NS_IMPL_ISUPPORTS_INHERITED0(nsHTMLTextAccessible, nsTextAccessible)
-
-ENameValueFlag
-nsHTMLTextAccessible::Name(nsString& aName)
-{
-  // Text node, ARIA can't be used.
-  aName = mText;
-  return eNameOK;
-}
+NS_IMPL_ISUPPORTS_INHERITED0(HTMLListAccessible, nsHyperTextAccessible)
 
 role
-nsHTMLTextAccessible::NativeRole()
+HTMLListAccessible::NativeRole()
 {
-  nsIFrame *frame = GetFrame();
-  // Don't return on null frame -- we still return a role
-  // after accessible is shutdown/DEFUNCT
-  if (frame && frame->IsGeneratedContentFrame()) 
-    return roles::STATICTEXT;
+  if (mContent->Tag() == nsGkAtoms::dl)
+    return roles::DEFINITION_LIST;
 
-  return nsTextAccessible::NativeRole();
+  return roles::LIST;
 }
 
 PRUint64
-nsHTMLTextAccessible::NativeState()
+HTMLListAccessible::NativeState()
 {
-  PRUint64 state = nsTextAccessible::NativeState();
-
-  nsDocAccessible* docAccessible = Document();
-  if (docAccessible) {
-     PRUint64 docState = docAccessible->State();
-     if (0 == (docState & states::EDITABLE)) {
-       state |= states::READONLY; // Links not focusable in editor
-     }
-  }
-
-  return state;
-}
-
-nsresult
-nsHTMLTextAccessible::GetAttributesInternal(nsIPersistentProperties *aAttributes)
-{
-  if (NativeRole() == roles::STATICTEXT) {
-    nsAutoString oldValueUnused;
-    aAttributes->SetStringProperty(NS_LITERAL_CSTRING("auto-generated"),
-                                  NS_LITERAL_STRING("true"), oldValueUnused);
-  }
-
-  return NS_OK;
+  return nsHyperTextAccessibleWrap::NativeState() | states::READONLY;
 }
 
 
 ////////////////////////////////////////////////////////////////////////////////
-// nsHTMLHRAccessible
-////////////////////////////////////////////////////////////////////////////////
-
-nsHTMLHRAccessible::
-  nsHTMLHRAccessible(nsIContent* aContent, nsDocAccessible* aDoc) :
-  nsLeafAccessible(aContent, aDoc)
-{
-}
-
-role
-nsHTMLHRAccessible::NativeRole()
-{
-  return roles::SEPARATOR;
-}
-
-
-////////////////////////////////////////////////////////////////////////////////
-// nsHTMLBRAccessible
-////////////////////////////////////////////////////////////////////////////////
-
-nsHTMLBRAccessible::
-  nsHTMLBRAccessible(nsIContent* aContent, nsDocAccessible* aDoc) :
-  nsLeafAccessible(aContent, aDoc)
-{
-}
-
-role
-nsHTMLBRAccessible::NativeRole()
-{
-  return roles::WHITESPACE;
-}
-
-PRUint64
-nsHTMLBRAccessible::NativeState()
-{
-  return states::READONLY;
-}
-
-nsresult
-nsHTMLBRAccessible::GetNameInternal(nsAString& aName)
-{
-  aName = static_cast<PRUnichar>('\n');    // Newline char
-  return NS_OK;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// nsHTMLLabelAccessible
+// HTMLLIAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
-nsHTMLLabelAccessible::
-  nsHTMLLabelAccessible(nsIContent* aContent, nsDocAccessible* aDoc) :
-  nsHyperTextAccessibleWrap(aContent, aDoc)
-{
-}
-
-NS_IMPL_ISUPPORTS_INHERITED0(nsHTMLLabelAccessible, nsHyperTextAccessible)
-
-nsresult
-nsHTMLLabelAccessible::GetNameInternal(nsAString& aName)
-{
-  return nsTextEquivUtils::GetNameFromSubtree(this, aName);
-}
-
-role
-nsHTMLLabelAccessible::NativeRole()
-{
-  return roles::LABEL;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// nsHTMLOuputAccessible
-////////////////////////////////////////////////////////////////////////////////
-
-nsHTMLOutputAccessible::
-  nsHTMLOutputAccessible(nsIContent* aContent, nsDocAccessible* aDoc) :
-  nsHyperTextAccessibleWrap(aContent, aDoc)
-{
-}
-
-NS_IMPL_ISUPPORTS_INHERITED0(nsHTMLOutputAccessible, nsHyperTextAccessible)
-
-Relation
-nsHTMLOutputAccessible::RelationByType(PRUint32 aType)
-{
-  Relation rel = nsAccessibleWrap::RelationByType(aType);
-  if (aType == nsIAccessibleRelation::RELATION_CONTROLLED_BY)
-    rel.AppendIter(new IDRefsIterator(mDoc, mContent, nsGkAtoms::_for));
-
-  return rel;
-}
-
-role
-nsHTMLOutputAccessible::NativeRole()
-{
-  return roles::SECTION;
-}
-
-nsresult
-nsHTMLOutputAccessible::GetAttributesInternal(nsIPersistentProperties* aAttributes)
-{
-  nsresult rv = nsAccessibleWrap::GetAttributesInternal(aAttributes);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::live,
-                         NS_LITERAL_STRING("polite"));
-  
-  return NS_OK;
-}
-
-
-////////////////////////////////////////////////////////////////////////////////
-// nsHTMLLIAccessible
-////////////////////////////////////////////////////////////////////////////////
-
-nsHTMLLIAccessible::
-  nsHTMLLIAccessible(nsIContent* aContent, nsDocAccessible* aDoc) :
+HTMLLIAccessible::
+  HTMLLIAccessible(nsIContent* aContent, nsDocAccessible* aDoc) :
   nsHyperTextAccessibleWrap(aContent, aDoc), mBullet(nsnull)
 {
   mFlags |= eHTMLListItemAccessible;
 
   nsBlockFrame* blockFrame = do_QueryFrame(GetFrame());
   if (blockFrame && blockFrame->HasBullet()) {
-    mBullet = new nsHTMLListBulletAccessible(mContent, mDoc);
+    mBullet = new HTMLListBulletAccessible(mContent, mDoc);
     if (!Document()->BindToDocument(mBullet, nsnull))
       mBullet = nsnull;
   }
 }
 
-NS_IMPL_ISUPPORTS_INHERITED0(nsHTMLLIAccessible, nsHyperTextAccessible)
+NS_IMPL_ISUPPORTS_INHERITED0(HTMLLIAccessible, nsHyperTextAccessible)
 
 void
-nsHTMLLIAccessible::Shutdown()
+HTMLLIAccessible::Shutdown()
 {
   mBullet = nsnull;
 
   nsHyperTextAccessibleWrap::Shutdown();
 }
 
 role
-nsHTMLLIAccessible::NativeRole()
+HTMLLIAccessible::NativeRole()
 {
   if (mContent->Tag() == nsGkAtoms::dt)
     return roles::TERM;
 
   return roles::LISTITEM;
 }
 
 PRUint64
-nsHTMLLIAccessible::NativeState()
+HTMLLIAccessible::NativeState()
 {
   return nsHyperTextAccessibleWrap::NativeState() | states::READONLY;
 }
 
-NS_IMETHODIMP nsHTMLLIAccessible::GetBounds(PRInt32 *x, PRInt32 *y, PRInt32 *width, PRInt32 *height)
+NS_IMETHODIMP
+HTMLLIAccessible::GetBounds(PRInt32* aX, PRInt32* aY,
+                            PRInt32* aWidth, PRInt32* aHeight)
 {
-  nsresult rv = nsAccessibleWrap::GetBounds(x, y, width, height);
+  nsresult rv = nsAccessibleWrap::GetBounds(aX, aY, aWidth, aHeight);
   if (NS_FAILED(rv) || !mBullet)
     return rv;
 
-  PRInt32 bulletX, bulletY, bulletWidth, bulletHeight;
+  PRInt32 bulletX = 0, bulletY = 0, bulletWidth = 0, bulletHeight = 0;
   rv = mBullet->GetBounds(&bulletX, &bulletY, &bulletWidth, &bulletHeight);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  *x = bulletX; // Move x coordinate of list item over to cover bullet as well
-  *width += bulletWidth;
+  *aX = bulletX; // Move x coordinate of list item over to cover bullet as well
+  *aWidth += bulletWidth;
   return NS_OK;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-// nsHTMLLIAccessible: public
+// HTMLLIAccessible: public
 
 void
-nsHTMLLIAccessible::UpdateBullet(bool aHasBullet)
+HTMLLIAccessible::UpdateBullet(bool aHasBullet)
 {
   if (aHasBullet == !!mBullet) {
     NS_NOTREACHED("Bullet and accessible are in sync already!");
     return;
   }
 
   nsDocAccessible* document = Document();
   if (aHasBullet) {
-    mBullet = new nsHTMLListBulletAccessible(mContent, mDoc);
+    mBullet = new HTMLListBulletAccessible(mContent, mDoc);
     if (document->BindToDocument(mBullet, nsnull)) {
       InsertChildAt(0, mBullet);
     }
   } else {
     RemoveChild(mBullet);
     document->UnbindFromDocument(mBullet);
     mBullet = nsnull;
   }
 
   // XXXtodo: fire show/hide and reorder events. That's hard to make it
   // right now because coalescence happens by DOM node.
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-// nsHTMLLIAccessible: nsAccessible protected
+// HTMLLIAccessible: nsAccessible protected
 
 void
-nsHTMLLIAccessible::CacheChildren()
+HTMLLIAccessible::CacheChildren()
 {
   if (mBullet)
     AppendChild(mBullet);
 
   // Cache children from subtree.
   nsAccessibleWrap::CacheChildren();
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-// nsHTMLListBulletAccessible
+// HTMLListBulletAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
-nsHTMLListBulletAccessible::
-  nsHTMLListBulletAccessible(nsIContent* aContent, nsDocAccessible* aDoc) :
-    nsLeafAccessible(aContent, aDoc)
-{
-}
-
 ////////////////////////////////////////////////////////////////////////////////
-// nsHTMLListBulletAccessible: nsAccessNode
+// HTMLListBulletAccessible: nsAccessNode
 
 bool
-nsHTMLListBulletAccessible::IsPrimaryForNode() const
+HTMLListBulletAccessible::IsPrimaryForNode() const
 {
   return false;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-// nsHTMLListBulletAccessible: nsAccessible
+// HTMLListBulletAccessible: nsAccessible
 
 ENameValueFlag
-nsHTMLListBulletAccessible::Name(nsString &aName)
+HTMLListBulletAccessible::Name(nsString &aName)
 {
   aName.Truncate();
 
   // Native anonymous content, ARIA can't be used. Get list bullet text.
   nsBlockFrame* blockFrame = do_QueryFrame(mContent->GetPrimaryFrame());
   NS_ASSERTION(blockFrame, "No frame for list item!");
   if (blockFrame) {
     blockFrame->GetBulletText(aName);
@@ -362,63 +167,35 @@ nsHTMLListBulletAccessible::Name(nsStrin
     // Append space otherwise bullets are jammed up against list text.
     aName.Append(' ');
   }
 
   return eNameOK;
 }
 
 role
-nsHTMLListBulletAccessible::NativeRole()
+HTMLListBulletAccessible::NativeRole()
 {
   return roles::STATICTEXT;
 }
 
 PRUint64
-nsHTMLListBulletAccessible::NativeState()
+HTMLListBulletAccessible::NativeState()
 {
   PRUint64 state = nsLeafAccessible::NativeState();
 
   state &= ~states::FOCUSABLE;
   state |= states::READONLY;
   return state;
 }
 
 void
-nsHTMLListBulletAccessible::AppendTextTo(nsAString& aText, PRUint32 aStartOffset,
-                                         PRUint32 aLength)
+HTMLListBulletAccessible::AppendTextTo(nsAString& aText, PRUint32 aStartOffset,
+                                       PRUint32 aLength)
 {
   nsAutoString bulletText;
   nsBlockFrame* blockFrame = do_QueryFrame(mContent->GetPrimaryFrame());
   NS_ASSERTION(blockFrame, "No frame for list item!");
   if (blockFrame)
     blockFrame->GetBulletText(bulletText);
 
   aText.Append(Substring(bulletText, aStartOffset, aLength));
 }
-
-////////////////////////////////////////////////////////////////////////////////
-// nsHTMLListAccessible
-////////////////////////////////////////////////////////////////////////////////
-
-nsHTMLListAccessible::
-  nsHTMLListAccessible(nsIContent* aContent, nsDocAccessible* aDoc) :
-  nsHyperTextAccessibleWrap(aContent, aDoc)
-{
-}
-
-NS_IMPL_ISUPPORTS_INHERITED0(nsHTMLListAccessible, nsHyperTextAccessible)
-
-role
-nsHTMLListAccessible::NativeRole()
-{
-  if (mContent->Tag() == nsGkAtoms::dl)
-    return roles::DEFINITION_LIST;
-
-  return roles::LIST;
-}
-
-PRUint64
-nsHTMLListAccessible::NativeState()
-{
-  return nsHyperTextAccessibleWrap::NativeState() | states::READONLY;
-}
-
copy from accessible/src/html/nsHTMLTextAccessible.h
copy to accessible/src/html/HTMLListAccessible.h
--- a/accessible/src/html/nsHTMLTextAccessible.h
+++ b/accessible/src/html/HTMLListAccessible.h
@@ -1,196 +1,104 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is mozilla.org code.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   Aaron Leventhal (aaronl@netscape.com)
- *   Kyle Yuan (kyle.yuan@sun.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 ***** */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#ifndef _nsHTMLTextAccessible_H_
-#define _nsHTMLTextAccessible_H_
+#ifndef mozilla_a11y_HTMLListAccessible_h__
+#define mozilla_a11y_HTMLListAccessible_h__
 
-#include "nsTextAccessibleWrap.h"
-#include "nsAutoPtr.h"
+#include "nsHyperTextAccessibleWrap.h"
 #include "nsBaseWidgetAccessible.h"
 
+namespace mozilla {
+namespace a11y {
+
+class HTMLListBulletAccessible;
+
 /**
- * Used for text nodes within HTML document.
+ * Used for HTML list (like HTML ul).
  */
-class nsHTMLTextAccessible : public nsTextAccessibleWrap
+class HTMLListAccessible : public nsHyperTextAccessibleWrap
 {
 public:
-  nsHTMLTextAccessible(nsIContent* aContent, nsDocAccessible* aDoc);
+  HTMLListAccessible(nsIContent* aContent, nsDocAccessible* aDoc) :
+    nsHyperTextAccessibleWrap(aContent, aDoc) { }
+  virtual ~HTMLListAccessible() { }
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsAccessible
-  virtual mozilla::a11y::ENameValueFlag Name(nsString& aName);
-  virtual nsresult GetAttributesInternal(nsIPersistentProperties *aAttributes);
-  virtual mozilla::a11y::role NativeRole();
-  virtual PRUint64 NativeState();
-};
-
-/**
- * Used for HTML hr element.
- */
-class nsHTMLHRAccessible : public nsLeafAccessible
-{
-public:
-  nsHTMLHRAccessible(nsIContent* aContent, nsDocAccessible* aDoc);
-
-  // nsAccessible
-  virtual mozilla::a11y::role NativeRole();
-};
-
-/**
- * Used for HTML br element.
- */
-class nsHTMLBRAccessible : public nsLeafAccessible
-{
-public:
-  nsHTMLBRAccessible(nsIContent* aContent, nsDocAccessible* aDoc);
-
-  // nsAccessible
-  virtual nsresult GetNameInternal(nsAString& aName);
-  virtual mozilla::a11y::role NativeRole();
+  virtual a11y::role NativeRole();
   virtual PRUint64 NativeState();
 };
 
-/**
- * Used for HTML label element.
- */
-class nsHTMLLabelAccessible : public nsHyperTextAccessibleWrap
-{
-public:
-  nsHTMLLabelAccessible(nsIContent* aContent, nsDocAccessible* aDoc);
-
-  NS_DECL_ISUPPORTS_INHERITED
-
-  // nsAccessible
-  virtual nsresult GetNameInternal(nsAString& aName);
-  virtual mozilla::a11y::role NativeRole();
-};
-
-/**
- * Used for HTML output element.
- */
-class nsHTMLOutputAccessible : public nsHyperTextAccessibleWrap
-{
-public:
-  nsHTMLOutputAccessible(nsIContent* aContent, nsDocAccessible* aDoc);
-
-  NS_DECL_ISUPPORTS_INHERITED
-
-  // nsAccessible
-  virtual mozilla::a11y::role NativeRole();
-  virtual nsresult GetAttributesInternal(nsIPersistentProperties* aAttributes);
-  virtual Relation RelationByType(PRUint32 aType);
-};
-
-/**
- * Used for bullet of HTML list item element (for example, HTML li).
- */
-class nsHTMLListBulletAccessible : public nsLeafAccessible
-{
-public:
-  nsHTMLListBulletAccessible(nsIContent* aContent, nsDocAccessible* aDoc);
-
-  // nsAccessNode
-  virtual bool IsPrimaryForNode() const;
-
-  // nsAccessible
-  virtual mozilla::a11y::ENameValueFlag Name(nsString& aName);
-  virtual mozilla::a11y::role NativeRole();
-  virtual PRUint64 NativeState();
-  virtual void AppendTextTo(nsAString& aText, PRUint32 aStartOffset = 0,
-                            PRUint32 aLength = PR_UINT32_MAX);
-};
-
-/**
- * Used for HTML list (like HTML ul).
- */
-class nsHTMLListAccessible : public nsHyperTextAccessibleWrap
-{
-public:
-  nsHTMLListAccessible(nsIContent* aContent, nsDocAccessible* aDoc);
-
-  // nsISupports
-  NS_DECL_ISUPPORTS_INHERITED
-
-  // nsAccessible
-  virtual mozilla::a11y::role NativeRole();
-  virtual PRUint64 NativeState();
-};
 
 /**
  * Used for HTML list item (e.g. HTML li).
  */
-class nsHTMLLIAccessible : public nsHyperTextAccessibleWrap
+class HTMLLIAccessible : public nsHyperTextAccessibleWrap
 {
 public:
-  nsHTMLLIAccessible(nsIContent* aContent, nsDocAccessible* aDoc);
+  HTMLLIAccessible(nsIContent* aContent, nsDocAccessible* aDoc);
+  virtual ~HTMLLIAccessible() { }
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsAccessNode
   virtual void Shutdown();
 
   // nsIAccessible
-  NS_IMETHOD GetBounds(PRInt32 *x, PRInt32 *y, PRInt32 *width, PRInt32 *height);
+  NS_IMETHOD GetBounds(PRInt32* aX, PRInt32* aY,
+                       PRInt32* aWidth, PRInt32* aHeight);
 
   // nsAccessible
-  virtual mozilla::a11y::role NativeRole();
+  virtual a11y::role NativeRole();
   virtual PRUint64 NativeState();
 
   // nsHTMLLIAccessible
   void UpdateBullet(bool aHasBullet);
 
 protected:
   // nsAccessible
   virtual void CacheChildren();
 
 private:
-  nsRefPtr<nsHTMLListBulletAccessible> mBullet;
+  nsRefPtr<HTMLListBulletAccessible> mBullet;
 };
 
-inline nsHTMLLIAccessible*
+
+/**
+ * Used for bullet of HTML list item element (for example, HTML li).
+ */
+class HTMLListBulletAccessible : public nsLeafAccessible
+{
+public:
+  HTMLListBulletAccessible(nsIContent* aContent, nsDocAccessible* aDoc) :
+    nsLeafAccessible(aContent, aDoc) { }
+  virtual ~HTMLListBulletAccessible() { }
+
+  // nsAccessNode
+  virtual bool IsPrimaryForNode() const;
+
+  // nsAccessible
+  virtual ENameValueFlag Name(nsString& aName);
+  virtual a11y::role NativeRole();
+  virtual PRUint64 NativeState();
+  virtual void AppendTextTo(nsAString& aText, PRUint32 aStartOffset = 0,
+                            PRUint32 aLength = PR_UINT32_MAX);
+};
+
+} // namespace a11y
+} // namespace mozilla
+
+
+inline mozilla::a11y::HTMLLIAccessible*
 nsAccessible::AsHTMLListItem()
 {
   return mFlags & eHTMLListItemAccessible ?
-    static_cast<nsHTMLLIAccessible*>(this) : nsnull;
+    static_cast<mozilla::a11y::HTMLLIAccessible*>(this) : nsnull;
 }
 
 #endif
--- a/accessible/src/html/Makefile.in
+++ b/accessible/src/html/Makefile.in
@@ -47,16 +47,17 @@ MODULE = accessibility
 LIBRARY_NAME = accessibility_html_s
 LIBXUL_LIBRARY = 1
 
 
 
 CPPSRCS = \
   nsHTMLCanvasAccessible.cpp \
   HTMLFormControlAccessible.cpp \
+  HTMLListAccessible.cpp \
   nsHTMLImageAccessible.cpp \
   nsHTMLImageMapAccessible.cpp \
   nsHTMLLinkAccessible.cpp \
   nsHTMLSelectAccessible.cpp \
   nsHTMLTableAccessible.cpp \
   nsHTMLTextAccessible.cpp \
   nsHyperTextAccessible.cpp \
   $(NULL)
--- a/accessible/src/html/nsHTMLTextAccessible.cpp
+++ b/accessible/src/html/nsHTMLTextAccessible.cpp
@@ -36,29 +36,22 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsHTMLTextAccessible.h"
 
 #include "nsDocAccessible.h"
 #include "nsAccUtils.h"
+#include "nsIAccessibleRelation.h"
 #include "nsTextEquivUtils.h"
 #include "Relation.h"
 #include "Role.h"
 #include "States.h"
 
-#include "nsIAccessibleRelation.h"
-#include "nsIFrame.h"
-#include "nsPresContext.h"
-#include "nsBlockFrame.h"
-#include "nsISelection.h"
-#include "nsISelectionController.h"
-#include "nsComponentManagerUtils.h"
-
 using namespace mozilla::a11y;
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsHTMLTextAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
 nsHTMLTextAccessible::
   nsHTMLTextAccessible(nsIContent* aContent, nsDocAccessible* aDoc) :
@@ -222,203 +215,8 @@ nsHTMLOutputAccessible::GetAttributesInt
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::live,
                          NS_LITERAL_STRING("polite"));
   
   return NS_OK;
 }
 
-
-////////////////////////////////////////////////////////////////////////////////
-// nsHTMLLIAccessible
-////////////////////////////////////////////////////////////////////////////////
-
-nsHTMLLIAccessible::
-  nsHTMLLIAccessible(nsIContent* aContent, nsDocAccessible* aDoc) :
-  nsHyperTextAccessibleWrap(aContent, aDoc), mBullet(nsnull)
-{
-  mFlags |= eHTMLListItemAccessible;
-
-  nsBlockFrame* blockFrame = do_QueryFrame(GetFrame());
-  if (blockFrame && blockFrame->HasBullet()) {
-    mBullet = new nsHTMLListBulletAccessible(mContent, mDoc);
-    if (!Document()->BindToDocument(mBullet, nsnull))
-      mBullet = nsnull;
-  }
-}
-
-NS_IMPL_ISUPPORTS_INHERITED0(nsHTMLLIAccessible, nsHyperTextAccessible)
-
-void
-nsHTMLLIAccessible::Shutdown()
-{
-  mBullet = nsnull;
-
-  nsHyperTextAccessibleWrap::Shutdown();
-}
-
-role
-nsHTMLLIAccessible::NativeRole()
-{
-  if (mContent->Tag() == nsGkAtoms::dt)
-    return roles::TERM;
-
-  return roles::LISTITEM;
-}
-
-PRUint64
-nsHTMLLIAccessible::NativeState()
-{
-  return nsHyperTextAccessibleWrap::NativeState() | states::READONLY;
-}
-
-NS_IMETHODIMP nsHTMLLIAccessible::GetBounds(PRInt32 *x, PRInt32 *y, PRInt32 *width, PRInt32 *height)
-{
-  nsresult rv = nsAccessibleWrap::GetBounds(x, y, width, height);
-  if (NS_FAILED(rv) || !mBullet)
-    return rv;
-
-  PRInt32 bulletX, bulletY, bulletWidth, bulletHeight;
-  rv = mBullet->GetBounds(&bulletX, &bulletY, &bulletWidth, &bulletHeight);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  *x = bulletX; // Move x coordinate of list item over to cover bullet as well
-  *width += bulletWidth;
-  return NS_OK;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// nsHTMLLIAccessible: public
-
-void
-nsHTMLLIAccessible::UpdateBullet(bool aHasBullet)
-{
-  if (aHasBullet == !!mBullet) {
-    NS_NOTREACHED("Bullet and accessible are in sync already!");
-    return;
-  }
-
-  nsDocAccessible* document = Document();
-  if (aHasBullet) {
-    mBullet = new nsHTMLListBulletAccessible(mContent, mDoc);
-    if (document->BindToDocument(mBullet, nsnull)) {
-      InsertChildAt(0, mBullet);
-    }
-  } else {
-    RemoveChild(mBullet);
-    document->UnbindFromDocument(mBullet);
-    mBullet = nsnull;
-  }
-
-  // XXXtodo: fire show/hide and reorder events. That's hard to make it
-  // right now because coalescence happens by DOM node.
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// nsHTMLLIAccessible: nsAccessible protected
-
-void
-nsHTMLLIAccessible::CacheChildren()
-{
-  if (mBullet)
-    AppendChild(mBullet);
-
-  // Cache children from subtree.
-  nsAccessibleWrap::CacheChildren();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// nsHTMLListBulletAccessible
-////////////////////////////////////////////////////////////////////////////////
-
-nsHTMLListBulletAccessible::
-  nsHTMLListBulletAccessible(nsIContent* aContent, nsDocAccessible* aDoc) :
-    nsLeafAccessible(aContent, aDoc)
-{
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// nsHTMLListBulletAccessible: nsAccessNode
-
-bool
-nsHTMLListBulletAccessible::IsPrimaryForNode() const
-{
-  return false;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// nsHTMLListBulletAccessible: nsAccessible
-
-ENameValueFlag
-nsHTMLListBulletAccessible::Name(nsString &aName)
-{
-  aName.Truncate();
-
-  // Native anonymous content, ARIA can't be used. Get list bullet text.
-  nsBlockFrame* blockFrame = do_QueryFrame(mContent->GetPrimaryFrame());
-  NS_ASSERTION(blockFrame, "No frame for list item!");
-  if (blockFrame) {
-    blockFrame->GetBulletText(aName);
-
-    // Append space otherwise bullets are jammed up against list text.
-    aName.Append(' ');
-  }
-
-  return eNameOK;
-}
-
-role
-nsHTMLListBulletAccessible::NativeRole()
-{
-  return roles::STATICTEXT;
-}
-
-PRUint64
-nsHTMLListBulletAccessible::NativeState()
-{
-  PRUint64 state = nsLeafAccessible::NativeState();
-
-  state &= ~states::FOCUSABLE;
-  state |= states::READONLY;
-  return state;
-}
-
-void
-nsHTMLListBulletAccessible::AppendTextTo(nsAString& aText, PRUint32 aStartOffset,
-                                         PRUint32 aLength)
-{
-  nsAutoString bulletText;
-  nsBlockFrame* blockFrame = do_QueryFrame(mContent->GetPrimaryFrame());
-  NS_ASSERTION(blockFrame, "No frame for list item!");
-  if (blockFrame)
-    blockFrame->GetBulletText(bulletText);
-
-  aText.Append(Substring(bulletText, aStartOffset, aLength));
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// nsHTMLListAccessible
-////////////////////////////////////////////////////////////////////////////////
-
-nsHTMLListAccessible::
-  nsHTMLListAccessible(nsIContent* aContent, nsDocAccessible* aDoc) :
-  nsHyperTextAccessibleWrap(aContent, aDoc)
-{
-}
-
-NS_IMPL_ISUPPORTS_INHERITED0(nsHTMLListAccessible, nsHyperTextAccessible)
-
-role
-nsHTMLListAccessible::NativeRole()
-{
-  if (mContent->Tag() == nsGkAtoms::dl)
-    return roles::DEFINITION_LIST;
-
-  return roles::LIST;
-}
-
-PRUint64
-nsHTMLListAccessible::NativeState()
-{
-  return nsHyperTextAccessibleWrap::NativeState() | states::READONLY;
-}
-
--- a/accessible/src/html/nsHTMLTextAccessible.h
+++ b/accessible/src/html/nsHTMLTextAccessible.h
@@ -114,83 +114,9 @@ public:
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsAccessible
   virtual mozilla::a11y::role NativeRole();
   virtual nsresult GetAttributesInternal(nsIPersistentProperties* aAttributes);
   virtual Relation RelationByType(PRUint32 aType);
 };
 
-/**
- * Used for bullet of HTML list item element (for example, HTML li).
- */
-class nsHTMLListBulletAccessible : public nsLeafAccessible
-{
-public:
-  nsHTMLListBulletAccessible(nsIContent* aContent, nsDocAccessible* aDoc);
-
-  // nsAccessNode
-  virtual bool IsPrimaryForNode() const;
-
-  // nsAccessible
-  virtual mozilla::a11y::ENameValueFlag Name(nsString& aName);
-  virtual mozilla::a11y::role NativeRole();
-  virtual PRUint64 NativeState();
-  virtual void AppendTextTo(nsAString& aText, PRUint32 aStartOffset = 0,
-                            PRUint32 aLength = PR_UINT32_MAX);
-};
-
-/**
- * Used for HTML list (like HTML ul).
- */
-class nsHTMLListAccessible : public nsHyperTextAccessibleWrap
-{
-public:
-  nsHTMLListAccessible(nsIContent* aContent, nsDocAccessible* aDoc);
-
-  // nsISupports
-  NS_DECL_ISUPPORTS_INHERITED
-
-  // nsAccessible
-  virtual mozilla::a11y::role NativeRole();
-  virtual PRUint64 NativeState();
-};
-
-/**
- * Used for HTML list item (e.g. HTML li).
- */
-class nsHTMLLIAccessible : public nsHyperTextAccessibleWrap
-{
-public:
-  nsHTMLLIAccessible(nsIContent* aContent, nsDocAccessible* aDoc);
-
-  // nsISupports
-  NS_DECL_ISUPPORTS_INHERITED
-
-  // nsAccessNode
-  virtual void Shutdown();
-
-  // nsIAccessible
-  NS_IMETHOD GetBounds(PRInt32 *x, PRInt32 *y, PRInt32 *width, PRInt32 *height);
-
-  // nsAccessible
-  virtual mozilla::a11y::role NativeRole();
-  virtual PRUint64 NativeState();
-
-  // nsHTMLLIAccessible
-  void UpdateBullet(bool aHasBullet);
-
-protected:
-  // nsAccessible
-  virtual void CacheChildren();
-
-private:
-  nsRefPtr<nsHTMLListBulletAccessible> mBullet;
-};
-
-inline nsHTMLLIAccessible*
-nsAccessible::AsHTMLListItem()
-{
-  return mFlags & eHTMLListItemAccessible ?
-    static_cast<nsHTMLLIAccessible*>(this) : nsnull;
-}
-
 #endif
--- a/content/base/public/nsIContent.h
+++ b/content/base/public/nsIContent.h
@@ -868,17 +868,17 @@ public:
    */
   bool HasIndependentSelection();
 
   /**
    * If the content is a part of HTML editor, this returns editing
    * host content.  When the content is in designMode, this returns its body
    * element.  Also, when the content isn't editable, this returns null.
    */
-  nsIContent* GetEditingHost();
+  mozilla::dom::Element* GetEditingHost();
 
   /**
    * Determing language. Look at the nearest ancestor element that has a lang
    * attribute in the XML namespace or is an HTML/SVG element and has a lang in
    * no namespace attribute.
    */
   void GetLang(nsAString& aResult) const {
     for (const nsIContent* content = this; content; content = content->GetParent()) {
--- a/content/base/src/nsContentAreaDragDrop.cpp
+++ b/content/base/src/nsContentAreaDragDrop.cpp
@@ -80,16 +80,17 @@
 #include "nsIDocShellTreeItem.h"
 #include "nsIWebBrowserPersist.h"
 #include "nsEscape.h"
 #include "nsContentUtils.h"
 #include "nsIMIMEService.h"
 #include "imgIContainer.h"
 #include "imgIRequest.h"
 #include "nsDOMDataTransfer.h"
+#include "mozilla/dom/Element.h"
 
 class NS_STACK_CLASS DragDataProducer
 {
 public:
   DragDataProducer(nsIDOMWindow* aWindow,
                    nsIContent* aTarget,
                    nsIContent* aSelectionTargetNode,
                    bool aIsAltKeyPressed);
--- a/content/base/src/nsGenericElement.cpp
+++ b/content/base/src/nsGenericElement.cpp
@@ -1547,36 +1547,36 @@ nsIContent::GetDesiredIMEState()
 
 bool
 nsIContent::HasIndependentSelection()
 {
   nsIFrame* frame = GetPrimaryFrame();
   return (frame && frame->GetStateBits() & NS_FRAME_INDEPENDENT_SELECTION);
 }
 
-nsIContent*
+dom::Element*
 nsIContent::GetEditingHost()
 {
   // If this isn't editable, return NULL.
   NS_ENSURE_TRUE(IsEditableInternal(), nsnull);
 
   nsIDocument* doc = GetCurrentDoc();
   NS_ENSURE_TRUE(doc, nsnull);
   // If this is in designMode, we should return <body>
   if (doc->HasFlag(NODE_IS_EDITABLE)) {
     return doc->GetBodyElement();
   }
 
   nsIContent* content = this;
-  for (nsIContent* parent = GetParent();
+  for (dom::Element* parent = GetElementParent();
        parent && parent->HasFlag(NODE_IS_EDITABLE);
-       parent = content->GetParent()) {
+       parent = content->GetElementParent()) {
     content = parent;
   }
-  return content;
+  return content->AsElement();
 }
 
 nsresult
 nsIContent::LookupNamespaceURIInternal(const nsAString& aNamespacePrefix,
                                        nsAString& aNamespaceURI) const
 {
   if (aNamespacePrefix.EqualsLiteral("xml")) {
     // Special-case for xml prefix
--- a/dom/plugins/base/android/ANPAudio.cpp
+++ b/dom/plugins/base/android/ANPAudio.cpp
@@ -1,10 +1,10 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* ***** BEGIN LICENSE BLOCK *****
+/* -*- Mode: c++; c-basic-offset: 2; tab-width: 20; indent-tabs-mode: nil; -*-
+ * ***** 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,
@@ -57,16 +57,18 @@ struct AudioTrack {
   jmethodID constructor;
   jmethodID flush;
   jmethodID pause;
   jmethodID play;
   jmethodID setvol;
   jmethodID stop;
   jmethodID write;
   jmethodID getpos;
+  jmethodID getstate;
+  jmethodID release;
 };
 
 enum AudioTrackMode {
   MODE_STATIC = 0,
   MODE_STREAM = 1
 };
 
 /* android.media.AudioManager */
@@ -86,30 +88,39 @@ enum AudioFormatChannel {
   CHANNEL_OUT_STEREO = 12
 };
 
 enum AudioFormatEncoding {
   ENCODING_PCM_16BIT = 2,
   ENCODING_PCM_8BIT = 3
 };
 
+enum AudioFormatState {
+  STATE_UNINITIALIZED = 0,
+  STATE_INITIALIZED = 1,
+  STATE_NO_STATIC_DATA = 2
+};
+
 static struct AudioTrack at;
 
 static jclass
 init_jni_bindings(JNIEnv *jenv) {
-  jclass jc = jenv->FindClass("android/media/AudioTrack");
+  jclass jc =
+    (jclass)jenv->NewGlobalRef(jenv->FindClass("android/media/AudioTrack"));
 
   at.constructor = jenv->GetMethodID(jc, "<init>", "(IIIIII)V");
   at.flush       = jenv->GetMethodID(jc, "flush", "()V");
   at.pause       = jenv->GetMethodID(jc, "pause", "()V");
   at.play        = jenv->GetMethodID(jc, "play",  "()V");
   at.setvol      = jenv->GetMethodID(jc, "setStereoVolume",  "(FF)I");
   at.stop        = jenv->GetMethodID(jc, "stop",  "()V");
   at.write       = jenv->GetMethodID(jc, "write", "([BII)I");
   at.getpos      = jenv->GetMethodID(jc, "getPlaybackHeadPosition", "()I");
+  at.getstate    = jenv->GetMethodID(jc, "getState", "()I");
+  at.release     = jenv->GetMethodID(jc, "release", "()V");
 
   return jc;
 }
 
 struct ANPAudioTrack {
   jobject output_unit;
   jclass at_class;
 
@@ -138,17 +149,17 @@ public:
 
 NS_IMETHODIMP
 AudioRunnable::Run()
 {
   JNIEnv* jenv = GetJNIForThread();
   if (!jenv)
     return NS_ERROR_FAILURE;
 
-  mozilla::AutoLocalJNIFrame autoFrame(jenv);
+  mozilla::AutoLocalJNIFrame autoFrame(jenv, 2);
 
   jbyteArray bytearray = jenv->NewByteArray(mTrack->bufferSize);
   if (!bytearray) {
     LOG("AudioRunnable:: Run.  Could not create bytearray");
     return NS_ERROR_FAILURE;
   }
 
   jbyte *byte = jenv->GetByteArrayElements(bytearray, NULL);
@@ -188,16 +199,18 @@ AudioRunnable::Run()
         break;
       }
 
       wroteSoFar += retval;
 
     } while(wroteSoFar < buffer.size);
   }
 
+  jenv->CallVoidMethod(mTrack->output_unit, at.release);
+
   jenv->DeleteGlobalRef(mTrack->output_unit);
   jenv->DeleteGlobalRef(mTrack->at_class);
 
   free(mTrack);
 
   jenv->ReleaseByteArrayElements(bytearray, byte, 0);
 
   return NS_OK;
@@ -252,30 +265,36 @@ anp_audio_newTrack(uint32_t sampleRate, 
     jChannels = CHANNEL_OUT_STEREO;
     break;
   default:
     LOG("Unknown channel count.  defaulting to mono.");
     jChannels = CHANNEL_OUT_MONO;
     break;
   }
 
+  mozilla::AutoLocalJNIFrame autoFrame(jenv);
+
   jobject obj = jenv->NewObject(s->at_class,
                                 at.constructor,
                                 STREAM_MUSIC,
                                 s->rate,
                                 jChannels,
                                 jformat,
                                 s->bufferSize,
                                 MODE_STREAM);
 
-  jthrowable exception = jenv->ExceptionOccurred();
-  if (exception) {
-    LOG("%s fAILED  ", __PRETTY_FUNCTION__);
-    jenv->ExceptionDescribe();
-    jenv->ExceptionClear();
+  if (autoFrame.CheckForException() || obj == NULL) {
+    jenv->DeleteGlobalRef(s->at_class);
+    free(s);
+    return NULL;
+  }
+
+  jint state = jenv->CallIntMethod(obj, at.getstate);
+
+  if (autoFrame.CheckForException() || state == STATE_UNINITIALIZED) {
     jenv->DeleteGlobalRef(s->at_class);
     free(s);
     return NULL;
   }
 
   s->output_unit = jenv->NewGlobalRef(obj);
   return s;
 }
@@ -295,28 +314,35 @@ anp_audio_deleteTrack(ANPAudioTrack* s)
 }
 
 void
 anp_audio_start(ANPAudioTrack* s)
 {
   if (s == NULL || s->output_unit == NULL) {
     return;
   }
-  
+
   if (s->keepGoing) {
     // we are already playing.  Ignore.
     return;
   }
 
   JNIEnv *jenv = GetJNIForThread();
   if (!jenv)
     return;
 
+  mozilla::AutoLocalJNIFrame autoFrame(jenv, 0);
   jenv->CallVoidMethod(s->output_unit, at.play);
 
+  if (autoFrame.CheckForException()) {
+    jenv->DeleteGlobalRef(s->at_class);
+    free(s);
+    return;
+  }
+
   s->isStopped = false;
   s->keepGoing = true;
 
   // AudioRunnable now owns the ANPAudioTrack
   nsRefPtr<AudioRunnable> runnable = new AudioRunnable(s);
 
   nsCOMPtr<nsIThread> thread;
   NS_NewThread(getter_AddRefs(thread), runnable);
@@ -327,30 +353,34 @@ anp_audio_pause(ANPAudioTrack* s)
 {
   if (s == NULL || s->output_unit == NULL) {
     return;
   }
 
   JNIEnv *jenv = GetJNIForThread();
   if (!jenv)
     return;
+
+  mozilla::AutoLocalJNIFrame autoFrame(jenv, 0);
   jenv->CallVoidMethod(s->output_unit, at.pause);
 }
 
 void
 anp_audio_stop(ANPAudioTrack* s)
 {
   if (s == NULL || s->output_unit == NULL) {
     return;
   }
 
   s->isStopped = true;
   JNIEnv *jenv = GetJNIForThread();
   if (!jenv)
     return;
+
+  mozilla::AutoLocalJNIFrame autoFrame(jenv, 0);
   jenv->CallVoidMethod(s->output_unit, at.stop);
 }
 
 bool
 anp_audio_isStopped(ANPAudioTrack* s)
 {
   return s->isStopped;
 }
--- a/editor/composer/src/nsEditorSpellCheck.cpp
+++ b/editor/composer/src/nsEditorSpellCheck.cpp
@@ -57,16 +57,17 @@
 #include "nsServiceManagerUtils.h"
 #include "nsIChromeRegistry.h"
 #include "nsString.h"
 #include "nsReadableUtils.h"
 #include "nsITextServicesFilter.h"
 #include "nsUnicharUtils.h"
 #include "mozilla/Services.h"
 #include "mozilla/Preferences.h"
+#include "mozilla/dom/Element.h"
 
 using namespace mozilla;
 
 class UpdateDictionnaryHolder {
   private:
     nsEditorSpellCheck* mSpellCheck;
   public:
     UpdateDictionnaryHolder(nsEditorSpellCheck* esc): mSpellCheck(esc) {
--- a/editor/idl/nsIHTMLEditor.idl
+++ b/editor/idl/nsIHTMLEditor.idl
@@ -46,17 +46,25 @@ interface nsIContent;
 interface nsISupportsArray;
 interface nsISelection;
 interface nsIContentFilter;
 
 %{C++
 #define NS_EDITOR_ELEMENT_NOT_FOUND \
   NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_EDITOR, 1)
 
+namespace mozilla {
+namespace dom {
+class Element;
+}
+}
 %}
+
+[ptr] native Element (mozilla::dom::Element);
+
 [scriptable, uuid(833f30de-94c7-4630-a852-2300ef329d7b)]
 
 interface nsIHTMLEditor : nsISupports
 {
 %{C++
   typedef short EAlignment;
 %}
 
@@ -585,11 +593,11 @@ interface nsIHTMLEditor : nsISupports
    * Checks whether a BR node is visible to the user.
    */
   boolean breakIsVisible(in nsIDOMNode aNode);
 
   /**
    * Get an active editor's editing host in DOM window.  If this editor isn't
    * active in the DOM window, this returns NULL.
    */
-  [noscript, notxpcom] nsIContent GetActiveEditingHost();
+  [noscript, notxpcom] Element GetActiveEditingHost();
 };
 
--- a/editor/libeditor/base/nsEditor.cpp
+++ b/editor/libeditor/base/nsEditor.cpp
@@ -3143,95 +3143,89 @@ nsEditor::GetLengthOfDOMNode(nsIDOMNode 
 }
 
 
 nsresult 
 nsEditor::GetPriorNode(nsIDOMNode  *aParentNode, 
                        PRInt32      aOffset, 
                        bool         aEditableNode, 
                        nsCOMPtr<nsIDOMNode> *aResultNode,
-                       bool         bNoBlockCrossing,
-                       nsIContent  *aActiveEditorRoot)
+                       bool         bNoBlockCrossing)
 {
   NS_ENSURE_TRUE(aResultNode, NS_ERROR_NULL_POINTER);
   *aResultNode = nsnull;
 
   nsCOMPtr<nsINode> parentNode = do_QueryInterface(aParentNode);
   NS_ENSURE_TRUE(parentNode, NS_ERROR_NULL_POINTER);
 
   *aResultNode = do_QueryInterface(GetPriorNode(parentNode, aOffset,
-                                                aEditableNode, bNoBlockCrossing,
-                                                aActiveEditorRoot));
+                                                aEditableNode,
+                                                bNoBlockCrossing));
   return NS_OK;
 }
 
 nsIContent*
 nsEditor::GetPriorNode(nsINode* aParentNode,
                        PRInt32 aOffset,
                        bool aEditableNode,
-                       bool aNoBlockCrossing,
-                       nsIContent* aActiveEditorRoot)
+                       bool aNoBlockCrossing)
 {
   MOZ_ASSERT(aParentNode);
 
   // If we are at the beginning of the node, or it is a text node, then just
   // look before it.
   if (!aOffset || aParentNode->NodeType() == nsIDOMNode::TEXT_NODE) {
     if (aNoBlockCrossing && IsBlockNode(aParentNode)) {
       // If we aren't allowed to cross blocks, don't look before this block.
       return nsnull;
     }
-    return GetPriorNode(aParentNode, aEditableNode,
-                        aNoBlockCrossing, aActiveEditorRoot);
+    return GetPriorNode(aParentNode, aEditableNode, aNoBlockCrossing);
   }
 
   // else look before the child at 'aOffset'
   if (nsIContent* child = aParentNode->GetChildAt(aOffset)) {
-    return GetPriorNode(child, aEditableNode, aNoBlockCrossing,
-                        aActiveEditorRoot);
+    return GetPriorNode(child, aEditableNode, aNoBlockCrossing);
   }
 
   // unless there isn't one, in which case we are at the end of the node
   // and want the deep-right child.
   nsIContent* resultNode = GetRightmostChild(aParentNode, aNoBlockCrossing);
   if (!resultNode || !aEditableNode || IsEditable(resultNode)) {
     return resultNode;
   }
 
   // restart the search from the non-editable node we just found
-  return GetPriorNode(resultNode, aEditableNode, aNoBlockCrossing, aActiveEditorRoot);
+  return GetPriorNode(resultNode, aEditableNode, aNoBlockCrossing);
 }
 
 
 nsresult 
 nsEditor::GetNextNode(nsIDOMNode   *aParentNode, 
                       PRInt32      aOffset, 
                       bool         aEditableNode, 
                       nsCOMPtr<nsIDOMNode> *aResultNode,
-                      bool         bNoBlockCrossing,
-                      nsIContent  *aActiveEditorRoot)
+                      bool         bNoBlockCrossing)
 {
   NS_ENSURE_TRUE(aResultNode, NS_ERROR_NULL_POINTER);
   *aResultNode = nsnull;
 
   nsCOMPtr<nsINode> parentNode = do_QueryInterface(aParentNode);
   NS_ENSURE_TRUE(parentNode, NS_ERROR_NULL_POINTER);
 
   *aResultNode = do_QueryInterface(GetNextNode(parentNode, aOffset,
-                                               aEditableNode, bNoBlockCrossing,
-                                               aActiveEditorRoot));
+                                               aEditableNode,
+                                               bNoBlockCrossing));
   return NS_OK;
 }
 
 nsIContent*
 nsEditor::GetNextNode(nsINode* aParentNode,
                       PRInt32 aOffset,
                       bool aEditableNode,
-                      bool aNoBlockCrossing,
-                      nsIContent* aActiveEditorRoot)
+                      bool aNoBlockCrossing)
 {
   MOZ_ASSERT(aParentNode);
 
   // if aParentNode is a text node, use its location instead
   if (aParentNode->NodeType() == nsIDOMNode::TEXT_NODE) {
     nsINode* parent = aParentNode->GetNodeParent();
     NS_ENSURE_TRUE(parent, nsnull);
     aOffset = parent->IndexOf(aParentNode) + 1; // _after_ the text node
@@ -3245,88 +3239,76 @@ nsEditor::GetNextNode(nsINode* aParentNo
       return child;
     }
 
     nsIContent* resultNode = GetLeftmostChild(child, aNoBlockCrossing);
     if (!resultNode) {
       return child;
     }
 
-    if (!IsDescendantOfBody(resultNode)) {
+    if (!IsDescendantOfEditorRoot(resultNode)) {
       return nsnull;
     }
 
     if (!aEditableNode || IsEditable(resultNode)) {
       return resultNode;
     }
 
     // restart the search from the non-editable node we just found
-    return GetNextNode(resultNode, aEditableNode, aNoBlockCrossing,
-                       aActiveEditorRoot);
+    return GetNextNode(resultNode, aEditableNode, aNoBlockCrossing);
   }
     
   // unless there isn't one, in which case we are at the end of the node
   // and want the next one.
   if (aNoBlockCrossing && IsBlockNode(aParentNode)) {
     // don't cross out of parent block
     return NS_OK;
   }
 
-  return GetNextNode(aParentNode, aEditableNode, aNoBlockCrossing,
-                     aActiveEditorRoot);
+  return GetNextNode(aParentNode, aEditableNode, aNoBlockCrossing);
 }
 
 
 nsresult 
 nsEditor::GetPriorNode(nsIDOMNode  *aCurrentNode, 
                        bool         aEditableNode, 
                        nsCOMPtr<nsIDOMNode> *aResultNode,
-                       bool         bNoBlockCrossing,
-                       nsIContent  *aActiveEditorRoot)
+                       bool         bNoBlockCrossing)
 {
   NS_ENSURE_TRUE(aResultNode, NS_ERROR_NULL_POINTER);
 
   nsCOMPtr<nsINode> currentNode = do_QueryInterface(aCurrentNode);
   NS_ENSURE_TRUE(currentNode, NS_ERROR_NULL_POINTER);
 
   *aResultNode = do_QueryInterface(GetPriorNode(currentNode, aEditableNode,
-                                                bNoBlockCrossing,
-                                                aActiveEditorRoot));
+                                                bNoBlockCrossing));
   return NS_OK;
 }
 
 nsIContent*
 nsEditor::GetPriorNode(nsINode* aCurrentNode, bool aEditableNode,
-                       bool aNoBlockCrossing /* = false */,
-                       nsIContent* aActiveEditorRoot /* = null */)
+                       bool aNoBlockCrossing /* = false */)
 {
   MOZ_ASSERT(aCurrentNode);
 
-  if (!IsDescendantOfBody(aCurrentNode) ||
-      (aActiveEditorRoot &&
-       !nsContentUtils::ContentIsDescendantOf(aCurrentNode,
-                                              aActiveEditorRoot))) {
+  if (!IsDescendantOfEditorRoot(aCurrentNode)) {
     return nsnull;
   }
 
-  return FindNode(aCurrentNode, false, aEditableNode, aNoBlockCrossing,
-                  aActiveEditorRoot);
+  return FindNode(aCurrentNode, false, aEditableNode, aNoBlockCrossing);
 }
 
 nsIContent*
 nsEditor::FindNextLeafNode(nsINode  *aCurrentNode, 
                            bool      aGoForward,
-                           bool      bNoBlockCrossing,
-                           nsIContent *aActiveEditorRoot)
+                           bool      bNoBlockCrossing)
 {
   // called only by GetPriorNode so we don't need to check params.
-  NS_PRECONDITION(IsDescendantOfBody(aCurrentNode) && !IsRootNode(aCurrentNode) &&
-                  (!aActiveEditorRoot ||
-                   nsContentUtils::ContentIsDescendantOf(aCurrentNode,
-                                                         aActiveEditorRoot)),
+  NS_PRECONDITION(IsDescendantOfEditorRoot(aCurrentNode) &&
+                  !IsEditorRoot(aCurrentNode),
                   "Bogus arguments");
 
   nsINode* cur = aCurrentNode;
   for (;;) {
     // if aCurrentNode has a sibling in the right direction, return
     // that sibling's closest child (or itself if it has no children)
     nsIContent* sibling =
       aGoForward ? cur->GetNextSibling() : cur->GetPreviousSibling();
@@ -3345,100 +3327,88 @@ nsEditor::FindNextLeafNode(nsINode  *aCu
       return leaf;
     }
 
     nsINode *parent = cur->GetNodeParent();
     if (!parent) {
       return nsnull;
     }
 
-    NS_ASSERTION(IsDescendantOfBody(parent),
+    NS_ASSERTION(IsDescendantOfEditorRoot(parent),
                  "We started with a proper descendant of root, and should stop "
                  "if we ever hit the root, so we better have a descendant of "
                  "root now!");
-    if (IsRootNode(parent) ||
-        (bNoBlockCrossing && IsBlockNode(parent)) ||
-        parent == aActiveEditorRoot) {
+    if (IsEditorRoot(parent) ||
+        (bNoBlockCrossing && IsBlockNode(parent))) {
       return nsnull;
     }
 
     cur = parent;
   }
 
   NS_NOTREACHED("What part of for(;;) do you not understand?");
   return nsnull;
 }
 
 nsresult
 nsEditor::GetNextNode(nsIDOMNode* aCurrentNode,
                       bool aEditableNode,
                       nsCOMPtr<nsIDOMNode> *aResultNode,
-                      bool bNoBlockCrossing,
-                      nsIContent* aActiveEditorRoot)
+                      bool bNoBlockCrossing)
 {
   nsCOMPtr<nsINode> currentNode = do_QueryInterface(aCurrentNode);
   if (!currentNode || !aResultNode) {
     return NS_ERROR_NULL_POINTER;
   }
 
   *aResultNode = do_QueryInterface(GetNextNode(currentNode, aEditableNode,
-                                               bNoBlockCrossing,
-                                               aActiveEditorRoot));
+                                               bNoBlockCrossing));
   return NS_OK;
 }
 
 nsIContent*
 nsEditor::GetNextNode(nsINode* aCurrentNode,
                       bool aEditableNode,
-                      bool bNoBlockCrossing,
-                      nsIContent* aActiveEditorRoot)
+                      bool bNoBlockCrossing)
 {
   MOZ_ASSERT(aCurrentNode);
 
-  if (!IsDescendantOfBody(aCurrentNode) ||
-      (aActiveEditorRoot &&
-       !nsContentUtils::ContentIsDescendantOf(aCurrentNode,
-                                              aActiveEditorRoot))) {
+  if (!IsDescendantOfEditorRoot(aCurrentNode)) {
     return nsnull;
   }
 
-  return FindNode(aCurrentNode, true, aEditableNode, bNoBlockCrossing,
-                  aActiveEditorRoot);
+  return FindNode(aCurrentNode, true, aEditableNode, bNoBlockCrossing);
 }
 
 nsIContent*
 nsEditor::FindNode(nsINode *aCurrentNode,
                    bool     aGoForward,
                    bool     aEditableNode,
-                   bool     bNoBlockCrossing,
-                   nsIContent *aActiveEditorRoot)
-{
-  if (IsRootNode(aCurrentNode) || aCurrentNode == aActiveEditorRoot)
-  {
+                   bool     bNoBlockCrossing)
+{
+  if (IsEditorRoot(aCurrentNode)) {
     // Don't allow traversal above the root node! This helps
     // prevent us from accidentally editing browser content
     // when the editor is in a text widget.
 
     return nsnull;
   }
 
   nsIContent* candidate =
-    FindNextLeafNode(aCurrentNode, aGoForward, bNoBlockCrossing,
-                     aActiveEditorRoot);
+    FindNextLeafNode(aCurrentNode, aGoForward, bNoBlockCrossing);
   
   if (!candidate) {
     return nsnull;
   }
 
   if (!aEditableNode || IsEditable(candidate)) {
     return candidate;
   }
 
-  return FindNode(candidate, aGoForward, aEditableNode, bNoBlockCrossing,
-                  aActiveEditorRoot);
+  return FindNode(candidate, aGoForward, aEditableNode, bNoBlockCrossing);
 }
 
 already_AddRefed<nsIDOMNode>
 nsEditor::GetRightmostChild(nsIDOMNode *aCurrentNode, 
                             bool bNoBlockCrossing)
 {
   NS_ENSURE_TRUE(aCurrentNode, nsnull);
   nsCOMPtr<nsIDOMNode> resultNode, temp = aCurrentNode;
@@ -3584,52 +3554,77 @@ nsEditor::TagCanContain(nsIAtom* aParent
 
 bool 
 nsEditor::TagCanContainTag(nsIAtom* aParentTag, nsIAtom* aChildTag)
 {
   return true;
 }
 
 bool
-nsEditor::IsRootNode(nsIDOMNode *inNode)
+nsEditor::IsRoot(nsIDOMNode* inNode)
 {
   NS_ENSURE_TRUE(inNode, false);
 
   nsCOMPtr<nsIDOMNode> rootNode = do_QueryInterface(GetRoot());
 
   return inNode == rootNode;
 }
 
 bool 
-nsEditor::IsRootNode(nsINode *inNode) 
+nsEditor::IsRoot(nsINode* inNode)
 {
   NS_ENSURE_TRUE(inNode, false);
 
   nsCOMPtr<nsINode> rootNode = GetRoot();
 
   return inNode == rootNode;
 }
 
+bool
+nsEditor::IsEditorRoot(nsINode* aNode)
+{
+  NS_ENSURE_TRUE(aNode, false);
+  nsCOMPtr<nsINode> rootNode = GetEditorRoot();
+  return aNode == rootNode;
+}
+
 bool 
-nsEditor::IsDescendantOfBody(nsIDOMNode *inNode) 
+nsEditor::IsDescendantOfRoot(nsIDOMNode* inNode)
 {
   nsCOMPtr<nsINode> node = do_QueryInterface(inNode);
-  return IsDescendantOfBody(node);
+  return IsDescendantOfRoot(node);
 }
 
 bool
-nsEditor::IsDescendantOfBody(nsINode *inNode)
+nsEditor::IsDescendantOfRoot(nsINode* inNode)
 {
   NS_ENSURE_TRUE(inNode, false);
   nsCOMPtr<nsIContent> root = GetRoot();
   NS_ENSURE_TRUE(root, false);
 
   return nsContentUtils::ContentIsDescendantOf(inNode, root);
 }
 
+bool
+nsEditor::IsDescendantOfEditorRoot(nsIDOMNode* aNode)
+{
+  nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
+  return IsDescendantOfEditorRoot(node);
+}
+
+bool
+nsEditor::IsDescendantOfEditorRoot(nsINode* aNode)
+{
+  NS_ENSURE_TRUE(aNode, false);
+  nsCOMPtr<nsIContent> root = GetEditorRoot();
+  NS_ENSURE_TRUE(root, false);
+
+  return nsContentUtils::ContentIsDescendantOf(aNode, root);
+}
+
 bool 
 nsEditor::IsContainer(nsIDOMNode *aNode)
 {
   return aNode ? true : false;
 }
 
 bool
 nsEditor::IsTextInDirtyFrameVisible(nsIContent *aNode)
@@ -5228,16 +5223,22 @@ nsEditor::GetRoot()
 
     // Let GetRootElement() do the work
     GetRootElement(getter_AddRefs(root));
   }
 
   return mRootElement;
 }
 
+dom::Element*
+nsEditor::GetEditorRoot()
+{
+  return GetRoot();
+}
+
 nsresult
 nsEditor::DetermineCurrentDirection()
 {
   // Get the current root direction from its frame
   dom::Element *rootElement = GetRoot();
 
   // If we don't have an explicit direction, determine our direction
   // from the content's direction
--- a/editor/libeditor/base/nsEditor.h
+++ b/editor/libeditor/base/nsEditor.h
@@ -368,18 +368,17 @@ protected:
 
   // stub.  see comment in source.                     
   virtual bool IsBlockNode(nsIDOMNode *aNode);
   virtual bool IsBlockNode(nsINode *aNode);
   
   // helper for GetPriorNode and GetNextNode
   nsIContent* FindNextLeafNode(nsINode  *aCurrentNode,
                                bool      aGoForward,
-                               bool      bNoBlockCrossing,
-                               nsIContent *aActiveEditorRoot);
+                               bool      bNoBlockCrossing);
 
   // Get nsIWidget interface
   nsresult GetWidget(nsIWidget **aWidget);
 
 
   // install the event listeners for the editor 
   virtual nsresult InstallEventListeners();
 
@@ -472,77 +471,67 @@ public:
 
   /** get the node immediately prior to aCurrentNode
     * @param aCurrentNode   the node from which we start the search
     * @param aEditableNode  if true, only return an editable node
     * @param aResultNode    [OUT] the node that occurs before aCurrentNode in the tree,
     *                       skipping non-editable nodes if aEditableNode is true.
     *                       If there is no prior node, aResultNode will be nsnull.
     * @param bNoBlockCrossing If true, don't move across "block" nodes, whatever that means.
-    * @param aActiveEditorRoot If non-null, only return descendants of aActiveEditorRoot.
     */
   nsresult GetPriorNode(nsIDOMNode  *aCurrentNode, 
                         bool         aEditableNode,
                         nsCOMPtr<nsIDOMNode> *aResultNode,
-                        bool         bNoBlockCrossing = false,
-                        nsIContent  *aActiveEditorRoot = nsnull);
+                        bool         bNoBlockCrossing = false);
   nsIContent* GetPriorNode(nsINode* aCurrentNode, bool aEditableNode,
-                           bool aNoBlockCrossing = false,
-                           nsIContent* aActiveEditorRoot = nsnull);
+                           bool aNoBlockCrossing = false);
 
   // and another version that takes a {parent,offset} pair rather than a node
   nsresult GetPriorNode(nsIDOMNode  *aParentNode, 
                         PRInt32      aOffset, 
                         bool         aEditableNode, 
                         nsCOMPtr<nsIDOMNode> *aResultNode,
-                        bool         bNoBlockCrossing = false,
-                        nsIContent  *aActiveEditorRoot = nsnull);
+                        bool         bNoBlockCrossing = false);
   nsIContent* GetPriorNode(nsINode* aParentNode,
                            PRInt32 aOffset,
                            bool aEditableNode,
-                           bool aNoBlockCrossing = false,
-                           nsIContent* aActiveEditorRoot = nsnull);
+                           bool aNoBlockCrossing = false);
 
 
   /** get the node immediately after to aCurrentNode
     * @param aCurrentNode   the node from which we start the search
     * @param aEditableNode  if true, only return an editable node
     * @param aResultNode    [OUT] the node that occurs after aCurrentNode in the tree,
     *                       skipping non-editable nodes if aEditableNode is true.
     *                       If there is no prior node, aResultNode will be nsnull.
     */
   nsresult GetNextNode(nsIDOMNode  *aCurrentNode, 
                        bool         aEditableNode,
                        nsCOMPtr<nsIDOMNode> *aResultNode,
-                       bool         bNoBlockCrossing = false,
-                       nsIContent  *aActiveEditorRoot = nsnull);
+                       bool         bNoBlockCrossing = false);
   nsIContent* GetNextNode(nsINode* aCurrentNode,
                           bool aEditableNode,
-                          bool bNoBlockCrossing = false,
-                          nsIContent* aActiveEditorRoot = nsnull);
+                          bool bNoBlockCrossing = false);
 
   // and another version that takes a {parent,offset} pair rather than a node
   nsresult GetNextNode(nsIDOMNode  *aParentNode, 
                        PRInt32      aOffset, 
                        bool         aEditableNode, 
                        nsCOMPtr<nsIDOMNode> *aResultNode,
-                       bool         bNoBlockCrossing = false,
-                       nsIContent  *aActiveEditorRoot = nsnull);
+                       bool         bNoBlockCrossing = false);
   nsIContent* GetNextNode(nsINode* aParentNode,
                           PRInt32 aOffset,
                           bool aEditableNode,
-                          bool aNoBlockCrossing = false,
-                          nsIContent* aActiveEditorRoot = nsnull);
+                          bool aNoBlockCrossing = false);
 
   // Helper for GetNextNode and GetPriorNode
   nsIContent* FindNode(nsINode *aCurrentNode,
                        bool     aGoForward,
                        bool     aEditableNode,
-                       bool     bNoBlockCrossing,
-                       nsIContent *aActiveEditorRoot);
+                       bool     bNoBlockCrossing);
   /**
    * Get the rightmost child of aCurrentNode;
    * return nsnull if aCurrentNode has no children.
    */
   already_AddRefed<nsIDOMNode> GetRightmostChild(nsIDOMNode *aCurrentNode, 
                                                  bool        bNoBlockCrossing = false);
   nsIContent* GetRightmostChild(nsINode *aCurrentNode,
                                 bool     bNoBlockCrossing = false);
@@ -572,22 +561,25 @@ public:
 
   /** returns true if aParent can contain a child of type aTag */
   bool CanContain(nsIDOMNode* aParent, nsIDOMNode* aChild);
   bool CanContainTag(nsIDOMNode* aParent, nsIAtom* aTag);
   bool TagCanContain(nsIAtom* aParentTag, nsIDOMNode* aChild);
   virtual bool TagCanContainTag(nsIAtom* aParentTag, nsIAtom* aChildTag);
 
   /** returns true if aNode is our root node */
-  bool IsRootNode(nsIDOMNode *inNode);
-  bool IsRootNode(nsINode *inNode);
+  bool IsRoot(nsIDOMNode* inNode);
+  bool IsRoot(nsINode* inNode);
+  bool IsEditorRoot(nsINode* aNode);
 
   /** returns true if aNode is a descendant of our root node */
-  bool IsDescendantOfBody(nsIDOMNode *inNode);
-  bool IsDescendantOfBody(nsINode *inNode);
+  bool IsDescendantOfRoot(nsIDOMNode* inNode);
+  bool IsDescendantOfRoot(nsINode* inNode);
+  bool IsDescendantOfEditorRoot(nsIDOMNode* aNode);
+  bool IsDescendantOfEditorRoot(nsINode* aNode);
 
   /** returns true if aNode is a container */
   virtual bool IsContainer(nsIDOMNode *aNode);
 
   /** returns true if aNode is an editable node */
   bool IsEditable(nsIDOMNode *aNode);
   bool IsEditable(nsIContent *aNode);
 
@@ -667,16 +659,20 @@ public:
                                     nsIDOMNode *aEndNode,
                                     PRInt32 aEndOffset);
 
   virtual already_AddRefed<nsIDOMEventTarget> GetDOMEventTarget() = 0;
 
   // Fast non-refcounting editor root element accessor
   mozilla::dom::Element *GetRoot();
 
+  // Likewise, but gets the editor's root instead, which is different for HTML
+  // editors
+  virtual mozilla::dom::Element* GetEditorRoot();
+
   // Accessor methods to flags
   bool IsPlaintextEditor() const
   {
     return (mFlags & nsIPlaintextEditor::eEditorPlaintextMask) != 0;
   }
 
   bool IsSingleLineEditor() const
   {
--- a/editor/libeditor/html/nsHTMLEditRules.cpp
+++ b/editor/libeditor/html/nsHTMLEditRules.cpp
@@ -4080,17 +4080,17 @@ nsHTMLEditRules::WillOutdent(nsISelectio
       }
       
       // are we inside a blockquote?
       nsCOMPtr<nsIDOMNode> n = curNode;
       nsCOMPtr<nsIDOMNode> tmp;
       curBlockQuoteIsIndentedWithCSS = false;
       // keep looking up the hierarchy as long as we don't hit the body or the
       // active editing host or a table element (other than an entire table)
-      while (!nsTextEditUtils::IsBody(n) && mHTMLEditor->IsNodeInActiveEditor(n)
+      while (!nsTextEditUtils::IsBody(n) && mHTMLEditor->IsDescendantOfEditorRoot(n)
           && (nsHTMLEditUtils::IsTable(n) || !nsHTMLEditUtils::IsTableElement(n)))
       {
         n->GetParentNode(getter_AddRefs(tmp));
         if (!tmp) {
           break;
         }
         n = tmp;
         if (nsHTMLEditUtils::IsBlockquote(n))
@@ -5592,18 +5592,18 @@ nsHTMLEditRules::GetPromotedPoint(RulesE
       // Don't walk past the editable section. Note that we need to check
       // before walking up to a parent because we need to return the parent
       // object, so the parent itself might not be in the editable area, but
       // it's OK if we're not performing a block-level action.
       bool blockLevelAction = (actionID == nsHTMLEditor::kOpIndent)
                              || (actionID == nsHTMLEditor::kOpOutdent)
                              || (actionID == nsHTMLEditor::kOpAlign)
                              || (actionID == nsHTMLEditor::kOpMakeBasicBlock);
-      if (!mHTMLEditor->IsNodeInActiveEditor(parent) &&
-          (blockLevelAction || !mHTMLEditor->IsNodeInActiveEditor(node))) {
+      if (!mHTMLEditor->IsDescendantOfEditorRoot(parent) &&
+          (blockLevelAction || !mHTMLEditor->IsDescendantOfEditorRoot(node))) {
         break;
       }
 
       node = parent;
       offset = pOffset;
       res = mHTMLEditor->GetPriorHTMLNode(node, offset, address_of(nearNode), true);
       NS_ENSURE_SUCCESS(res, res);
     } 
@@ -5648,18 +5648,18 @@ nsHTMLEditRules::GetPromotedPoint(RulesE
     {
       res = nsEditor::GetNodeLocation(node, address_of(parent), &pOffset);
       NS_ENSURE_SUCCESS(res, res);
 
       // Don't walk past the editable section. Note that we need to check
       // before walking up to a parent because we need to return the parent
       // object, so the parent itself might not be in the editable area, but
       // it's OK.
-      if (!mHTMLEditor->IsNodeInActiveEditor(node) &&
-          !mHTMLEditor->IsNodeInActiveEditor(parent)) {
+      if (!mHTMLEditor->IsDescendantOfEditorRoot(node) &&
+          !mHTMLEditor->IsDescendantOfEditorRoot(parent)) {
         break;
       }
 
       node = parent;
       offset = pOffset+1;  // we want to be AFTER nearNode
       res = mHTMLEditor->GetNextHTMLNode(node, offset, address_of(nearNode), true);
       NS_ENSURE_SUCCESS(res, res);
     } 
@@ -5782,18 +5782,18 @@ nsHTMLEditRules::PromoteRange(nsIDOMRang
   nsCOMPtr<nsIDOMRange> opRange;
   
   res = GetPromotedPoint( kStart, startNode, startOffset, inOperationType, address_of(opStartNode), &opStartOffset);
   NS_ENSURE_SUCCESS(res, res);
   res = GetPromotedPoint( kEnd, endNode, endOffset, inOperationType, address_of(opEndNode), &opEndOffset);
   NS_ENSURE_SUCCESS(res, res);
 
   // Make sure that the new range ends up to be in the editable section.
-  if (!mHTMLEditor->IsNodeInActiveEditor(nsEditor::GetNodeAtRangeOffsetPoint(opStartNode, opStartOffset)) ||
-      !mHTMLEditor->IsNodeInActiveEditor(nsEditor::GetNodeAtRangeOffsetPoint(opEndNode, opEndOffset - 1))) {
+  if (!mHTMLEditor->IsDescendantOfEditorRoot(nsEditor::GetNodeAtRangeOffsetPoint(opStartNode, opStartOffset)) ||
+      !mHTMLEditor->IsDescendantOfEditorRoot(nsEditor::GetNodeAtRangeOffsetPoint(opEndNode, opEndOffset - 1))) {
     return NS_OK;
   }
 
   res = inRange->SetStart(opStartNode, opStartOffset);
   NS_ENSURE_SUCCESS(res, res);
   res = inRange->SetEnd(opEndNode, opEndOffset);
   return res;
 } 
@@ -6487,17 +6487,17 @@ nsINode*
 nsHTMLEditRules::IsInListItem(nsINode* aNode)
 {
   NS_ENSURE_TRUE(aNode, nsnull);
   if (aNode->IsElement() && nsHTMLEditUtils::IsListItem(aNode->AsElement())) {
     return aNode;
   }
 
   nsINode* parent = aNode->GetNodeParent();
-  while (parent && mHTMLEditor->IsNodeInActiveEditor(parent) &&
+  while (parent && mHTMLEditor->IsDescendantOfEditorRoot(parent) &&
          !(parent->IsElement() &&
            nsHTMLEditUtils::IsTableElement(parent->AsElement()))) {
     if (nsHTMLEditUtils::IsListItem(parent->AsElement())) {
       return parent;
     }
     parent = parent->GetNodeParent();
   }
   return nsnull;
@@ -7289,17 +7289,17 @@ nsHTMLEditRules::SplitAsNeeded(const nsA
    
   // check that we have a place that can legally contain the tag
   while (!tagParent)
   {
     // sniffing up the parent tree until we find 
     // a legal place for the block
     if (!parent) break;
     // Don't leave the active editing host
-    if (!mHTMLEditor->IsNodeInActiveEditor(parent)) {
+    if (!mHTMLEditor->IsDescendantOfEditorRoot(parent)) {
       nsCOMPtr<nsIContent> parentContent = do_QueryInterface(parent);
       if (parentContent != mHTMLEditor->GetActiveEditingHost()) {
         break;
       }
     }
     if (mHTMLEditor->CanContainTag(parent, tagAtom)) {
       tagParent = parent;
       break;
@@ -8351,18 +8351,17 @@ nsHTMLEditRules::UpdateDocChangeRange(ns
 
   // first make sure aRange is in the document.  It might not be if
   // portions of our editting action involved manipulating nodes
   // prior to placing them in the document (e.g., populating a list item
   // before placing it in its list)
   nsCOMPtr<nsIDOMNode> startNode;
   res = aRange->GetStartContainer(getter_AddRefs(startNode));
   NS_ENSURE_SUCCESS(res, res);
-  if (!mHTMLEditor->IsDescendantOfBody(startNode))
-  {
+  if (!mHTMLEditor->IsDescendantOfRoot(startNode)) {
     // just return - we don't need to adjust mDocChangeRange in this case
     return NS_OK;
   }
   
   if (!mDocChangeRange)
   {
     // clone aRange.
     nsCOMPtr<nsIDOMRange> range;
@@ -8888,17 +8887,17 @@ nsHTMLEditRules::RelativeChangeIndentati
   // remove unnecessary DIV blocks:
   // we could skip this section but that would cause a FAIL in
   // editor/libeditor/html/tests/browserscope/richtext.html, which expects
   // to unapply a CSS "indent" (<div style="margin-left: 40px;">) by
   // removing the DIV container instead of just removing the CSS property.
   nsCOMPtr<dom::Element> node = do_QueryInterface(aNode);
   if (!node || !node->IsHTML(nsGkAtoms::div) ||
       node == mHTMLEditor->GetActiveEditingHost() ||
-      !mHTMLEditor->IsNodeInActiveEditor(node) ||
+      !mHTMLEditor->IsDescendantOfEditorRoot(node) ||
       nsHTMLEditor::HasAttributes(node)) {
     return NS_OK;
   }
 
   return mHTMLEditor->RemoveContainer(element);
 }
 
 //
--- a/editor/libeditor/html/nsHTMLEditor.cpp
+++ b/editor/libeditor/html/nsHTMLEditor.cpp
@@ -1877,17 +1877,17 @@ nsHTMLEditor::InsertNodeAtPoint(nsIDOMNo
 }
 
 NS_IMETHODIMP
 nsHTMLEditor::SelectElement(nsIDOMElement* aElement)
 {
   nsresult res = NS_ERROR_NULL_POINTER;
 
   // Must be sure that element is contained in the document body
-  if (IsNodeInActiveEditor(aElement)) {
+  if (IsDescendantOfEditorRoot(aElement)) {
     nsCOMPtr<nsISelection> selection;
     res = GetSelection(getter_AddRefs(selection));
     NS_ENSURE_SUCCESS(res, res);
     NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER);
     nsCOMPtr<nsIDOMNode>parent;
     res = aElement->GetParentNode(getter_AddRefs(parent));
     if (NS_SUCCEEDED(res) && parent)
     {
@@ -1909,17 +1909,17 @@ nsHTMLEditor::SelectElement(nsIDOMElemen
 }
 
 NS_IMETHODIMP
 nsHTMLEditor::SetCaretAfterElement(nsIDOMElement* aElement)
 {
   nsresult res = NS_ERROR_NULL_POINTER;
 
   // Be sure the element is contained in the document body
-  if (aElement && IsNodeInActiveEditor(aElement)) {
+  if (aElement && IsDescendantOfEditorRoot(aElement)) {
     nsCOMPtr<nsISelection> selection;
     res = GetSelection(getter_AddRefs(selection));
     NS_ENSURE_SUCCESS(res, res);
     NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER);
     nsCOMPtr<nsIDOMNode>parent;
     res = aElement->GetParentNode(getter_AddRefs(parent));
     NS_ENSURE_SUCCESS(res, res);
     NS_ENSURE_TRUE(parent, NS_ERROR_NULL_POINTER);
@@ -3971,39 +3971,22 @@ void nsHTMLEditor::IsTextPropertySetByCo
 //================================================================
 // HTML Editor methods
 //
 // Note: Table Editing methods are implemented in nsTableEditor.cpp
 //
 
 
 bool
-nsHTMLEditor::IsNodeInActiveEditor(nsIDOMNode* aNode)
-{
-  nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
-  return node && IsNodeInActiveEditor(node);
-}
-
-bool
-nsHTMLEditor::IsNodeInActiveEditor(nsINode* aNode)
-{
-  nsIContent* activeEditingHost = GetActiveEditingHost();
-  if (!activeEditingHost) {
-    return false;
-  }
-  return nsContentUtils::ContentIsDescendantOf(aNode, activeEditingHost);
-}
-
-bool
 nsHTMLEditor::SetCaretInTableCell(nsIDOMElement* aElement)
 {
   nsCOMPtr<dom::Element> element = do_QueryInterface(aElement);
   if (!element || !element->IsHTML() ||
       !nsHTMLEditUtils::IsTableElement(element) ||
-      !IsNodeInActiveEditor(element)) {
+      !IsDescendantOfEditorRoot(element)) {
     return false;
   }
 
   nsIContent* node = element;
   while (node->HasChildren()) {
     node = node->GetFirstChild();
   }
 
@@ -4348,20 +4331,21 @@ nsHTMLEditor::GetPriorHTMLNode(nsIDOMNod
   NS_ENSURE_TRUE(outNode, NS_ERROR_NULL_POINTER);
 
   nsIContent* activeEditingHost = GetActiveEditingHost();
   if (!activeEditingHost) {
     *outNode = nsnull;
     return NS_OK;
   }
 
-  nsresult res = GetPriorNode(inNode, true, address_of(*outNode), bNoBlockCrossing, activeEditingHost);
+  nsresult res = GetPriorNode(inNode, true, address_of(*outNode),
+                              bNoBlockCrossing);
   NS_ENSURE_SUCCESS(res, res);
   
-  NS_ASSERTION(!*outNode || IsNodeInActiveEditor(*outNode),
+  NS_ASSERTION(!*outNode || IsDescendantOfEditorRoot(*outNode),
                "GetPriorNode screwed up");
   return res;
 }
 
 
 ///////////////////////////////////////////////////////////////////////////
 // GetPriorHTMLNode: same as above but takes {parent,offset} instead of node
 //                       
@@ -4371,20 +4355,21 @@ nsHTMLEditor::GetPriorHTMLNode(nsIDOMNod
   NS_ENSURE_TRUE(outNode, NS_ERROR_NULL_POINTER);
 
   nsIContent* activeEditingHost = GetActiveEditingHost();
   if (!activeEditingHost) {
     *outNode = nsnull;
     return NS_OK;
   }
 
-  nsresult res = GetPriorNode(inParent, inOffset, true, address_of(*outNode), bNoBlockCrossing, activeEditingHost);
+  nsresult res = GetPriorNode(inParent, inOffset, true, address_of(*outNode),
+                              bNoBlockCrossing);
   NS_ENSURE_SUCCESS(res, res);
   
-  NS_ASSERTION(!*outNode || IsNodeInActiveEditor(*outNode),
+  NS_ASSERTION(!*outNode || IsDescendantOfEditorRoot(*outNode),
                "GetPriorNode screwed up");
   return res;
 }
 
 
 ///////////////////////////////////////////////////////////////////////////
 // GetNextHTMLNode: returns the next editable leaf node, if there is
 //                   one within the <body>
@@ -4392,17 +4377,17 @@ nsHTMLEditor::GetPriorHTMLNode(nsIDOMNod
 nsresult
 nsHTMLEditor::GetNextHTMLNode(nsIDOMNode *inNode, nsCOMPtr<nsIDOMNode> *outNode, bool bNoBlockCrossing)
 {
   NS_ENSURE_TRUE(outNode, NS_ERROR_NULL_POINTER);
   nsresult res = GetNextNode(inNode, true, address_of(*outNode), bNoBlockCrossing);
   NS_ENSURE_SUCCESS(res, res);
   
   // if it's not in the body, then zero it out
-  if (*outNode && !IsNodeInActiveEditor(*outNode)) {
+  if (*outNode && !IsDescendantOfEditorRoot(*outNode)) {
     *outNode = nsnull;
   }
   return res;
 }
 
 
 ///////////////////////////////////////////////////////////////////////////
 // GetNHTMLextNode: same as above but takes {parent,offset} instead of node
@@ -4410,17 +4395,17 @@ nsHTMLEditor::GetNextHTMLNode(nsIDOMNode
 nsresult
 nsHTMLEditor::GetNextHTMLNode(nsIDOMNode *inParent, PRInt32 inOffset, nsCOMPtr<nsIDOMNode> *outNode, bool bNoBlockCrossing)
 {
   NS_ENSURE_TRUE(outNode, NS_ERROR_NULL_POINTER);
   nsresult res = GetNextNode(inParent, inOffset, true, address_of(*outNode), bNoBlockCrossing);
   NS_ENSURE_SUCCESS(res, res);
   
   // if it's not in the body, then zero it out
-  if (*outNode && !IsNodeInActiveEditor(*outNode)) {
+  if (*outNode && !IsDescendantOfEditorRoot(*outNode)) {
     *outNode = nsnull;
   }
   return res;
 }
 
 
 nsresult 
 nsHTMLEditor::IsFirstEditableChild( nsIDOMNode *aNode, bool *aOutIsFirst)
@@ -5469,17 +5454,17 @@ nsHTMLEditor::IsActiveInDOMWindow()
   // we're not active).
   if (!content->HasFlag(NODE_IS_EDITABLE) ||
       content->HasIndependentSelection()) {
     return false;
   }
   return true;
 }
 
-nsIContent*
+dom::Element*
 nsHTMLEditor::GetActiveEditingHost()
 {
   NS_ENSURE_TRUE(mDocWeak, nsnull);
 
   nsCOMPtr<nsIDocument> doc = do_QueryReferent(mDocWeak);
   NS_ENSURE_TRUE(doc, nsnull);
   if (doc->HasFlag(NODE_IS_EDITABLE)) {
     return doc->GetBodyElement();
@@ -5710,8 +5695,15 @@ nsHTMLEditor::GetPreferredIMEState(IMESt
 }
 
 already_AddRefed<nsIContent>
 nsHTMLEditor::GetInputEventTargetContent()
 {
   nsCOMPtr<nsIContent> target = GetActiveEditingHost();
   return target.forget();
 }
+
+// virtual MOZ_OVERRIDE
+dom::Element*
+nsHTMLEditor::GetEditorRoot()
+{
+  return GetActiveEditingHost();
+}
--- a/editor/libeditor/html/nsHTMLEditor.h
+++ b/editor/libeditor/html/nsHTMLEditor.h
@@ -131,16 +131,17 @@ public:
 
   /* ------------ nsPlaintextEditor overrides -------------- */
   NS_IMETHOD GetIsDocumentEditable(bool *aIsDocumentEditable);
   NS_IMETHOD BeginningOfDocument();
   virtual nsresult HandleKeyPressEvent(nsIDOMKeyEvent* aKeyEvent);
   virtual already_AddRefed<nsIContent> GetFocusedContent();
   virtual bool IsActiveInDOMWindow();
   virtual already_AddRefed<nsIDOMEventTarget> GetDOMEventTarget();
+  virtual mozilla::dom::Element* GetEditorRoot() MOZ_OVERRIDE;
   virtual already_AddRefed<nsIContent> FindSelectionRoot(nsINode *aNode);
   virtual bool IsAcceptableInputEvent(nsIDOMEvent* aEvent);
   virtual already_AddRefed<nsIContent> GetInputEventTargetContent();
 
   /* ------------ nsStubMutationObserver overrides --------- */
   NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED
   NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
   NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
@@ -436,18 +437,16 @@ protected:
   nsresult GetBodyElement(nsIDOMHTMLElement** aBody);
   // Get the focused node of this editor.
   // @return    If the editor has focus, this returns the focused node.
   //            Otherwise, returns null.
   already_AddRefed<nsINode> GetFocusedNode();
 
   // Return TRUE if aElement is a table-related elemet and caret was set
   bool SetCaretInTableCell(nsIDOMElement* aElement);
-  bool IsNodeInActiveEditor(nsIDOMNode* aNode);
-  bool IsNodeInActiveEditor(nsINode* aNode);
 
   // key event helpers
   NS_IMETHOD TabInTable(bool inIsShift, bool *outHandled);
   NS_IMETHOD CreateBR(nsIDOMNode *aNode, PRInt32 aOffset, 
                       nsCOMPtr<nsIDOMNode> *outBRNode, nsIEditor::EDirection aSelect = nsIEditor::eNone);
 
 // Table Editing (implemented in nsTableEditor.cpp)
 
--- a/editor/libeditor/html/nsHTMLEditorEventListener.cpp
+++ b/editor/libeditor/html/nsHTMLEditorEventListener.cpp
@@ -137,17 +137,17 @@ nsHTMLEditorEventListener::MouseDown(nsI
   nsCOMPtr<nsIDOMEventTarget> target;
   nsCOMPtr<nsIDOMNSEvent> internalEvent = do_QueryInterface(aMouseEvent);
   res = internalEvent->GetExplicitOriginalTarget(getter_AddRefs(target));
   NS_ENSURE_SUCCESS(res, res);
   NS_ENSURE_TRUE(target, NS_ERROR_NULL_POINTER);
   nsCOMPtr<nsIDOMElement> element = do_QueryInterface(target);
 
   // Contenteditable should disregard mousedowns outside it
-  if (element && !htmlEditor->IsNodeInActiveEditor(element)) {
+  if (element && !htmlEditor->IsDescendantOfEditorRoot(element)) {
     return NS_OK;
   }
 
   if (isContextClick || (buttonNumber == 0 && clickCount == 2))
   {
     nsCOMPtr<nsISelection> selection;
     mEditor->GetSelection(getter_AddRefs(selection));
     NS_ENSURE_TRUE(selection, NS_OK);
--- a/editor/libeditor/html/nsHTMLEditorStyle.cpp
+++ b/editor/libeditor/html/nsHTMLEditorStyle.cpp
@@ -452,17 +452,17 @@ nsHTMLEditor::SetInlinePropertyOnNodeImp
         IsOnlyAttribute(priorNode, *aAttribute)) {
       // previous sib is already right kind of inline node; slide this over into it
       return MoveNode(aNode->AsDOMNode(), priorNode->AsDOMNode(), -1);
     }
 
     nsIContent* nextNode = GetNextHTMLSibling(aNode);
     if (nextNode && nextNode->Tag() == aProperty &&
         HasAttrVal(nextNode, aAttribute, *aValue) &&
-        IsOnlyAttribute(priorNode, *aAttribute)) {
+        IsOnlyAttribute(nextNode, *aAttribute)) {
       // following sib is already right kind of inline node; slide this over into it
       return MoveNode(aNode->AsDOMNode(), nextNode->AsDOMNode(), 0);
     }
   }
 
   // ok, chuck it in its very own container
   nsCOMPtr<nsIDOMNode> tmp;
   return InsertContainerAbove(aNode->AsDOMNode(), address_of(tmp), tag,
--- a/gfx/harfbuzz/src/Makefile.in
+++ b/gfx/harfbuzz/src/Makefile.in
@@ -29,17 +29,19 @@ DEPTH     = ../../..
 topsrcdir = @top_srcdir@
 srcdir    = @srcdir@
 VPATH     = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE         = harfbuzz
 LIBRARY_NAME   = mozharfbuzz
+ifneq ($(OS_ARCH),WINNT)
 LIBXUL_LIBRARY = 1
+endif
 
 CPPSRCS	=                        \
   hb-blob.cc                     \
   hb-buffer.cc                   \
   hb-common.cc                   \
   hb-fallback-shape.cc           \
   hb-font.cc                     \
   hb-ot-layout.cc                \
--- a/image/build/nsImageModule.cpp
+++ b/image/build/nsImageModule.cpp
@@ -123,16 +123,17 @@ static const mozilla::Module::CategoryEn
   { "Gecko-Content-Viewers", "image/x-png", "@mozilla.org/content/document-loader-factory;1" },
   { "content-sniffing-services", "@mozilla.org/image/loader;1", "@mozilla.org/image/loader;1" },
   { NULL }
 };
 
 static nsresult
 imglib_Initialize()
 {
+  mozilla::image::DiscardTracker::Initialize();
   imgLoader::InitCache();
   return NS_OK;
 }
 
 static void
 imglib_Shutdown()
 {
   imgLoader::Shutdown();
--- a/image/decoders/nsICODecoder.cpp
+++ b/image/decoders/nsICODecoder.cpp
@@ -360,29 +360,25 @@ nsICODecoder::WriteInternal(const char* 
     aCount -= toCopy;
     aBuffer += toCopy;
 
     mIsPNG = !memcmp(mSignature, nsPNGDecoder::pngSignatureBytes, 
                      PNGSIGNATURESIZE);
     if (mIsPNG) {
       mContainedDecoder = new nsPNGDecoder(mImage, mObserver);
       mContainedDecoder->InitSharedDecoder();
-      mContainedDecoder->Write(mSignature, PNGSIGNATURESIZE);
-      mDataError = mContainedDecoder->HasDataError();
-      if (mContainedDecoder->HasDataError()) {
+      if (!WriteToContainedDecoder(mSignature, PNGSIGNATURESIZE)) {
         return;
       }
     }
   }
 
   // If we have a PNG, let the PNG decoder do all of the rest of the work
   if (mIsPNG && mContainedDecoder && mPos >= mImageOffset + PNGSIGNATURESIZE) {
-    mContainedDecoder->Write(aBuffer, aCount);
-    mDataError = mContainedDecoder->HasDataError();
-    if (mContainedDecoder->HasDataError()) {
+    if (!WriteToContainedDecoder(aBuffer, aCount)) {
       return;
     }
     mPos += aCount;
     aBuffer += aCount;
     aCount = 0;
 
     // Raymond Chen says that 32bpp only are valid PNG ICOs
     // http://blogs.msdn.com/b/oldnewthing/archive/2010/10/22/10079192.aspx
@@ -440,19 +436,17 @@ nsICODecoder::WriteInternal(const char* 
     // The ICO format when containing a BMP does not include the 14 byte
     // bitmap file header. To use the code of the BMP decoder we need to 
     // generate this header ourselves and feed it to the BMP decoder.
     PRInt8 bfhBuffer[BMPFILEHEADERSIZE];
     if (!FillBitmapFileHeaderBuffer(bfhBuffer)) {
       PostDataError();
       return;
     }
-    mContainedDecoder->Write((const char*)bfhBuffer, sizeof(bfhBuffer));
-    mDataError = mContainedDecoder->HasDataError();
-    if (mContainedDecoder->HasDataError()) {
+    if (!WriteToContainedDecoder((const char*)bfhBuffer, sizeof(bfhBuffer))) {
       return;
     }
 
     // Setup the cursor hot spot if one is present
     SetHotSpotIfCursor();
 
     // Fix the ICO height from the BIH.
     // Fix the height on the BIH to be /2 so our BMP decoder will understand.
@@ -463,19 +457,17 @@ nsICODecoder::WriteInternal(const char* 
 
     // Fix the ICO width from the BIH.
     if (!FixBitmapWidth(reinterpret_cast<PRInt8*>(mBIHraw))) {
       PostDataError();
       return;
     }
 
     // Write out the BMP's bitmap info header
-    mContainedDecoder->Write(mBIHraw, sizeof(mBIHraw));
-    mDataError = mContainedDecoder->HasDataError();
-    if (mContainedDecoder->HasDataError()) {
+    if (!WriteToContainedDecoder(mBIHraw, sizeof(mBIHraw))) {
       return;
     }
 
     // We have the size. If we're doing a size decode, we got what
     // we came for.
     if (IsSizeDecode())
       return;
 
@@ -510,19 +502,17 @@ nsICODecoder::WriteInternal(const char* 
     if (mPos >= bmpDataOffset && mPos < bmpDataEnd) {
 
       // Figure out how much data the BMP decoder wants
       PRUint32 toFeed = bmpDataEnd - mPos;
       if (toFeed > aCount) {
         toFeed = aCount;
       }
 
-      mContainedDecoder->Write(aBuffer, toFeed);
-      mDataError = mContainedDecoder->HasDataError();
-      if (mContainedDecoder->HasDataError()) {
+      if (!WriteToContainedDecoder(aBuffer, toFeed)) {
         return;
       }
 
       mPos += toFeed;
       aCount -= toFeed;
       aBuffer += toFeed;
     }
   
@@ -587,16 +577,29 @@ nsICODecoder::WriteInternal(const char* 
             }
           }
         }
       }
     }
   }
 }
 
+bool
+nsICODecoder::WriteToContainedDecoder(const char* aBuffer, PRUint32 aCount)
+{
+  mContainedDecoder->Write(aBuffer, aCount);
+  if (mContainedDecoder->HasDataError()) {
+    mDataError = mContainedDecoder->HasDataError();
+  }
+  if (mContainedDecoder->HasDecoderError()) {
+    PostDecoderError(mContainedDecoder->GetDecoderError());
+  }
+  return !HasError();
+}
+
 void
 nsICODecoder::ProcessDirEntry(IconDirEntry& aTarget)
 {
   memset(&aTarget, 0, sizeof(aTarget));
   memcpy(&aTarget.mWidth, mDirEntryArray, sizeof(aTarget.mWidth));
   memcpy(&aTarget.mHeight, mDirEntryArray + 1, sizeof(aTarget.mHeight));
   memcpy(&aTarget.mColorCount, mDirEntryArray + 2, sizeof(aTarget.mColorCount));
   memcpy(&aTarget.mReserved, mDirEntryArray + 3, sizeof(aTarget.mReserved));
--- a/image/decoders/nsICODecoder.h
+++ b/image/decoders/nsICODecoder.h
@@ -72,16 +72,20 @@ public:
   {
     return mDirEntry.mHeight == 0 ? 256 : mDirEntry.mHeight; 
   }
 
   virtual void WriteInternal(const char* aBuffer, PRUint32 aCount);
   virtual void FinishInternal();
 
 private:
+  // Writes to the contained decoder and sets the appropriate errors
+  // Returns true if there are no errors.
+  bool WriteToContainedDecoder(const char* aBuffer, PRUint32 aCount);
+
   // Processes a single dir entry of the icon resource
   void ProcessDirEntry(IconDirEntry& aTarget);
   // Sets the hotspot property of if we have a cursor
   void SetHotSpotIfCursor();
   // Creates a bitmap file header buffer, returns true if successful
   bool FillBitmapFileHeaderBuffer(PRInt8 *bfh);
   // Fixes the ICO height to match that of the BIH.
   // and also fixes the BIH height to be /2 of what it was.
--- a/image/src/DiscardTracker.cpp
+++ b/image/src/DiscardTracker.cpp
@@ -13,29 +13,31 @@ namespace mozilla {
 namespace image {
 
 static const char* sDiscardTimeoutPref = "image.mem.min_discard_timeout_ms";
 
 /* static */ LinkedList<DiscardTracker::Node> DiscardTracker::sDiscardableImages;
 /* static */ nsCOMPtr<nsITimer> DiscardTracker::sTimer;
 /* static */ bool DiscardTracker::sInitialized = false;
 /* static */ bool DiscardTracker::sTimerOn = false;
-/* static */ bool DiscardTracker::sDiscardRunnablePending = false;
+/* static */ PRInt32 DiscardTracker::sDiscardRunnablePending = 0;
 /* static */ PRInt64 DiscardTracker::sCurrentDecodedImageBytes = 0;
 /* static */ PRUint32 DiscardTracker::sMinDiscardTimeoutMs = 10000;
 /* static */ PRUint32 DiscardTracker::sMaxDecodedImageKB = 42 * 1024;
+/* static */ PRLock * DiscardTracker::sAllocationLock = NULL;
 
 /*
  * When we notice we're using too much memory for decoded images, we enqueue a
  * DiscardRunnable, which runs this code.
  */
 NS_IMETHODIMP
 DiscardTracker::DiscardRunnable::Run()
 {
-  sDiscardRunnablePending = false;
+  PR_ATOMIC_SET(&sDiscardRunnablePending, 0);
+
   DiscardTracker::DiscardNow();
   return NS_OK;
 }
 
 int
 DiscardTimeoutChangedCallback(const char* aPref, void *aClosure)
 {
   DiscardTracker::ReloadTimeout();
@@ -43,77 +45,78 @@ DiscardTimeoutChangedCallback(const char
 }
 
 nsresult
 DiscardTracker::Reset(Node *node)
 {
   // We shouldn't call Reset() with a null |img| pointer, on images which can't
   // be discarded, or on animated images (which should be marked as
   // non-discardable, anyway).
+  MOZ_ASSERT(NS_IsMainThread());
+  MOZ_ASSERT(sInitialized);
   MOZ_ASSERT(node->img);
   MOZ_ASSERT(node->img->CanDiscard());
   MOZ_ASSERT(!node->img->mAnim);
 
-  // Initialize the first time through.
-  nsresult rv;
-  if (NS_UNLIKELY(!sInitialized)) {
-    rv = Initialize();
-    NS_ENSURE_SUCCESS(rv, rv);
-  }
-
   // Insert the node at the front of the list and note when it was inserted.
   bool wasInList = node->isInList();
   if (wasInList) {
     node->remove();
   }
   node->timestamp = TimeStamp::Now();
   sDiscardableImages.insertFront(node);
 
   // If the node wasn't already in the list of discardable images, then we may
   // need to discard some images to stay under the sMaxDecodedImageKB limit.
   // Call MaybeDiscardSoon to do this check.
   if (!wasInList) {
     MaybeDiscardSoon();
   }
 
   // Make sure the timer is running.
-  rv = EnableTimer();
+  nsresult rv = EnableTimer();
   NS_ENSURE_SUCCESS(rv,rv);
 
   return NS_OK;
 }
 
 void
 DiscardTracker::Remove(Node *node)
 {
+  MOZ_ASSERT(NS_IsMainThread());
+
   if (node->isInList())
     node->remove();
 
   if (sDiscardableImages.isEmpty())
     DisableTimer();
 }
 
 /**
  * Shut down the tracker, deallocating the timer.
  */
 void
 DiscardTracker::Shutdown()
 {
+  MOZ_ASSERT(NS_IsMainThread());
+
   if (sTimer) {
     sTimer->Cancel();
     sTimer = NULL;
   }
 }
 
 /*
  * Discard all the images we're tracking.
  */
 void
 DiscardTracker::DiscardAll()
 {
+  MOZ_ASSERT(NS_IsMainThread());
+
   if (!sInitialized)
     return;
 
   // Be careful: Calling Discard() on an image might cause it to be removed
   // from the list!
   Node *n;
   while ((n = sDiscardableImages.popFirst())) {
     n->img->Discard();
@@ -123,41 +126,50 @@ DiscardTracker::DiscardAll()
   DisableTimer();
 }
 
 void
 DiscardTracker::InformAllocation(PRInt64 bytes)
 {
   // This function is called back e.g. from RasterImage::Discard(); be careful!
 
+  MOZ_ASSERT(sInitialized);
+
+  PR_Lock(sAllocationLock);
   sCurrentDecodedImageBytes += bytes;
   MOZ_ASSERT(sCurrentDecodedImageBytes >= 0);
+  PR_Unlock(sAllocationLock);
 
   // If we're using too much memory for decoded images, MaybeDiscardSoon will
   // enqueue a callback to discard some images.
   MaybeDiscardSoon();
 }
 
 /**
  * Initialize the tracker.
  */
 nsresult
 DiscardTracker::Initialize()
 {
+  MOZ_ASSERT(NS_IsMainThread());
+
   // Watch the timeout pref for changes.
   Preferences::RegisterCallback(DiscardTimeoutChangedCallback,
                                 sDiscardTimeoutPref);
 
   Preferences::AddUintVarCache(&sMaxDecodedImageKB,
                               "image.mem.max_decoded_image_kb",
                               50 * 1024);
 
   // Create the timer.
   sTimer = do_CreateInstance("@mozilla.org/timer;1");
 
+  // Create a lock for safegarding the 64-bit sCurrentDecodedImageBytes
+  sAllocationLock = PR_NewLock();
+
   // Mark us as initialized
   sInitialized = true;
 
   // Read the timeout pref and start the timer.
   ReloadTimeout();
 
   return NS_OK;
 }
@@ -270,17 +282,19 @@ DiscardTracker::DiscardNow()
 }
 
 void
 DiscardTracker::MaybeDiscardSoon()
 {
   // Are we carrying around too much decoded image data?  If so, enqueue an
   // event to try to get us down under our limit.
   if (sCurrentDecodedImageBytes > sMaxDecodedImageKB * 1024 &&
-      !sDiscardableImages.isEmpty() && !sDiscardRunnablePending) {
-    sDiscardRunnablePending = true;
-    nsRefPtr<DiscardRunnable> runnable = new DiscardRunnable();
-    NS_DispatchToCurrentThread(runnable);
+      !sDiscardableImages.isEmpty()) {
+    // Check if the value of sDiscardRunnablePending used to be false
+    if (!PR_ATOMIC_SET(&sDiscardRunnablePending, 1)) {
+      nsRefPtr<DiscardRunnable> runnable = new DiscardRunnable();
+      NS_DispatchToMainThread(runnable);
+    }
   }
 }
 
 } // namespace image
 } // namespace mozilla
--- a/image/src/DiscardTracker.h
+++ b/image/src/DiscardTracker.h
@@ -43,42 +43,49 @@ class DiscardTracker
     struct Node : public LinkedListElement<Node>
     {
       RasterImage *img;
       TimeStamp timestamp;
     };
 
     /**
      * Add an image to the front of the tracker's list, or move it to the front
-     * if it's already in the list.
+     * if it's already in the list.  This function is main thread only.
      */
     static nsresult Reset(struct Node* node);
 
     /**
      * Remove a node from the tracker; do nothing if the node is currently
-     * untracked.
+     * untracked.  This function is main thread only.
      */
     static void Remove(struct Node* node);
 
     /**
+     * Initializes the discard tracker.  This function is main thread only.
+     */
+    static nsresult Initialize();
+
+    /**
      * Shut the discard tracker down.  This should be called on XPCOM shutdown
-     * so we destroy the discard timer's nsITimer.
+     * so we destroy the discard timer's nsITimer.  This function is main thread
+     * only.
      */
     static void Shutdown();
 
     /**
      * Discard the decoded image data for all images tracked by the discard
-     * tracker.
+     * tracker.  This function is main thread only.
      */
     static void DiscardAll();
 
     /**
      * Inform the discard tracker that we've allocated or deallocated some
      * memory for a decoded image.  We use this to determine when we've
-     * allocated too much memory and should discard some images.
+     * allocated too much memory and should discard some images.  This function
+     * can be called from any thread and is thread-safe.
      */
     static void InformAllocation(PRInt64 bytes);
 
   private:
     /**
      * This is called when the discard timer fires; it calls into DiscardNow().
      */
     friend int DiscardTimeoutChangedCallback(const char* aPref, void *aClosure);
@@ -87,30 +94,31 @@ class DiscardTracker
      * When run, this runnable sets sDiscardRunnablePending to false and calls
      * DiscardNow().
      */
     class DiscardRunnable : public nsRunnable
     {
       NS_IMETHOD Run();
     };
 
-    static nsresult Initialize();
     static void ReloadTimeout();
     static nsresult EnableTimer();
     static void DisableTimer();
     static void MaybeDiscardSoon();
     static void TimerCallback(nsITimer *aTimer, void *aClosure);
     static void DiscardNow();
 
     static LinkedList<Node> sDiscardableImages;
     static nsCOMPtr<nsITimer> sTimer;
     static bool sInitialized;
     static bool sTimerOn;
-    static bool sDiscardRunnablePending;
+    static PRInt32 sDiscardRunnablePending;
     static PRInt64 sCurrentDecodedImageBytes;
     static PRUint32 sMinDiscardTimeoutMs;
     static PRUint32 sMaxDecodedImageKB;
+    // Lock for safegarding the 64-bit sCurrentDecodedImageBytes
+    static PRLock *sAllocationLock;
 };
 
 } // namespace image
 } // namespace mozilla
 
 #endif /* mozilla_imagelib_DiscardTracker_h_ */
--- a/image/src/RasterImage.cpp
+++ b/image/src/RasterImage.cpp
@@ -243,20 +243,19 @@ RasterImage::~RasterImage()
             ("CompressedImageAccounting: destroying RasterImage %p.  "
              "Total Containers: %d, Discardable containers: %d, "
              "Total source bytes: %lld, Source bytes for discardable containers %lld",
              this,
              num_containers,
              num_discardable_containers,
              total_source_bytes,
              discardable_source_bytes));
+    DiscardTracker::Remove(&mDiscardTrackerNode);
   }
 
-  DiscardTracker::Remove(&mDiscardTrackerNode);
-
   // If we have a decoder open, shut it down
   if (mDecoder) {
     nsresult rv = ShutdownDecoder(eShutdownIntent_Interrupted);
     if (NS_FAILED(rv))
       NS_WARNING("Failed to shut down decoder in destructor!");
   }
 
   // Total statistics
--- a/layout/media/Makefile.in
+++ b/layout/media/Makefile.in
@@ -44,17 +44,22 @@ include $(DEPTH)/config/autoconf.mk
 
 MODULE		= layout
 LIBRARY_NAME	= gkmedias
 EXPORT_LIBRARY	= $(DIST)/lib
 ifeq (WINNT,$(OS_TARGET))
 FORCE_SHARED_LIB = 1
 endif
 
-SHARED_LIBRARY_LIBS = $(MOZ_OTS_LIBS) $(QCMS_LIBS) $(MOZ_CAIRO_LIBS)
+SHARED_LIBRARY_LIBS = \
+    $(MOZ_OTS_LIBS) \
+    $(QCMS_LIBS) \
+    $(MOZ_CAIRO_LIBS) \
+    $(MOZ_HARFBUZZ_LIBS) \
+    $(NULL)
 
 ifdef MOZ_GRAPHITE
 SHARED_LIBRARY_LIBS += $(MOZ_GRAPHITE_LIBS)
 endif
 
 ifdef MOZ_VORBIS
 SHARED_LIBRARY_LIBS 	+= \
 	$(DEPTH)/media/libvorbis/lib/$(LIB_PREFIX)vorbis.$(LIB_SUFFIX) \
--- a/layout/media/symbols.def.in
+++ b/layout/media/symbols.def.in
@@ -438,8 +438,48 @@ cairo_null_surface_create
 cairo_release_device
 cairo_surface_attach_snapshot
 cairo_win32_get_dc_with_clip
 cairo_win32_get_system_text_quality
 cairo_win32_surface_create_with_alpha
 cairo_win32_surface_get_height
 cairo_win32_surface_get_width
 cairo_win32_surface_set_can_convert_to_dib
+hb_blob_create
+hb_blob_destroy
+hb_blob_get_data
+hb_blob_get_empty
+hb_blob_get_length
+hb_blob_reference
+hb_buffer_add_utf16
+hb_buffer_create
+hb_buffer_destroy
+hb_buffer_get_glyph_infos
+hb_buffer_get_glyph_positions
+hb_buffer_reverse
+hb_buffer_set_direction
+hb_buffer_set_language
+hb_buffer_set_script
+hb_buffer_set_unicode_funcs
+hb_face_create_for_tables
+hb_face_destroy
+hb_font_create
+hb_font_destroy
+hb_font_funcs_create
+hb_font_funcs_set_glyph_contour_point_func
+hb_font_funcs_set_glyph_func
+hb_font_funcs_set_glyph_h_advance_func
+hb_font_funcs_set_glyph_h_kerning_func
+hb_font_set_funcs
+hb_font_set_ppem
+hb_font_set_scale
+hb_language_from_string
+hb_ot_tag_to_language
+hb_shape
+hb_unicode_funcs_create
+hb_unicode_funcs_get_empty
+hb_unicode_funcs_set_combining_class_func
+hb_unicode_funcs_set_compose_func
+hb_unicode_funcs_set_decompose_func
+hb_unicode_funcs_set_eastasian_width_func
+hb_unicode_funcs_set_general_category_func
+hb_unicode_funcs_set_mirroring_func
+hb_unicode_funcs_set_script_func
--- a/mobile/android/base/AboutHomeContent.java
+++ b/mobile/android/base/AboutHomeContent.java
@@ -319,24 +319,16 @@ public class AboutHomeContent extends Sc
     private int getNumberOfTopSites() {
         Configuration config = getContext().getResources().getConfiguration();
         if (config.orientation == Configuration.ORIENTATION_LANDSCAPE)
             return NUMBER_OF_TOP_SITES_LANDSCAPE;
         else
             return NUMBER_OF_TOP_SITES_PORTRAIT;
     }
 
-    private int getNumberOfColumns() {
-        Configuration config = getContext().getResources().getConfiguration();
-        if (config.orientation == Configuration.ORIENTATION_LANDSCAPE)
-            return NUMBER_OF_COLS_LANDSCAPE;
-        else
-            return NUMBER_OF_COLS_PORTRAIT;
-    }
-
     private void loadTopSites(final Activity activity) {
         // Ensure we initialize GeckoApp's startup mode in
         // background thread before we use it when updating
         // the top sites section layout in main thread.
         final GeckoApp.StartupMode startupMode = GeckoApp.mAppContext.getStartupMode();
 
         // The isSyncSetup method should not be called on
         // UI thread as it touches disk to access a sqlite DB.
@@ -356,18 +348,16 @@ public class AboutHomeContent extends Sc
                                                                  new int[] { R.id.title, R.id.thumbnail });
 
                     mTopSitesAdapter.setViewBinder(new TopSitesViewBinder());
                     mTopSitesGrid.setAdapter(mTopSitesAdapter);
                 } else {
                     mTopSitesAdapter.changeCursor(mCursor);
                 }
 
-                mTopSitesGrid.setNumColumns(getNumberOfColumns());
-
                 updateLayout(startupMode, syncIsSetup);
             }
         });
     }
 
     void update(final Activity activity, final EnumSet<UpdateFlags> flags) {
         GeckoAppShell.getHandler().post(new Runnable() {
             public void run() {
@@ -391,18 +381,16 @@ public class AboutHomeContent extends Sc
     }
 
     public void onActivityContentChanged(Activity activity) {
         update(activity, EnumSet.of(UpdateFlags.TOP_SITES));
     }
 
     @Override
     public void onConfigurationChanged(Configuration newConfig) {
-        if (mTopSitesGrid != null) 
-            mTopSitesGrid.setNumColumns(getNumberOfColumns());
         if (mTopSitesAdapter != null)
             mTopSitesAdapter.notifyDataSetChanged();
 
         super.onConfigurationChanged(newConfig);
     }
 
     private String readFromZipFile(Activity activity, String filename) {
         ZipFile zip = null;
@@ -704,23 +692,26 @@ public class AboutHomeContent extends Sc
                 if (c != null)
                     nSites = c.getCount();
             }
 
             Configuration config = getContext().getResources().getConfiguration();
             if (config.orientation == Configuration.ORIENTATION_LANDSCAPE) {
                 nSites = Math.min(nSites, NUMBER_OF_TOP_SITES_LANDSCAPE);
                 numRows = (int) Math.round((double) nSites / NUMBER_OF_COLS_LANDSCAPE);
+                setNumColumns(NUMBER_OF_COLS_LANDSCAPE);
             } else {
                 nSites = Math.min(nSites, NUMBER_OF_TOP_SITES_PORTRAIT);
                 numRows = (int) Math.round((double) nSites / NUMBER_OF_COLS_PORTRAIT);
+                setNumColumns(NUMBER_OF_COLS_PORTRAIT);
             }
             int expandedHeightSpec = 
                 MeasureSpec.makeMeasureSpec((int)(mDisplayDensity * numRows * kTopSiteItemHeight),
                                             MeasureSpec.EXACTLY);
+
             super.onMeasure(widthMeasureSpec, expandedHeightSpec);
         }
     }
 
     public class TopSitesCursorAdapter extends SimpleCursorAdapter {
         public TopSitesCursorAdapter(Context context, int layout, Cursor c,
                                      String[] from, int[] to) {
             super(context, layout, c, from, to);
--- a/toolkit/library/Makefile.in
+++ b/toolkit/library/Makefile.in
@@ -334,17 +334,16 @@ ifeq ($(MOZ_WIDGET_TOOLKIT),cocoa)
 OS_LIBS += -framework OpenGL -lcups
 endif
 
 EXTRA_DSO_LDOPTS += \
   $(LIBS_DIR) \
   $(MOZ_JS_LIBS) \
   $(NSS_LIBS) \
   $(MOZ_CAIRO_OSLIBS) \
-  $(MOZ_HARFBUZZ_LIBS) \
   $(MOZ_APP_EXTRA_LIBS) \
   $(SQLITE_LIBS) \
   $(NULL)
 
 ifdef MOZ_NATIVE_JPEG
 EXTRA_DSO_LDOPTS += $(JPEG_LIBS)
 endif
 
--- a/widget/android/AndroidBridge.cpp
+++ b/widget/android/AndroidBridge.cpp
@@ -1149,17 +1149,17 @@ AndroidBridge::CallEglCreateWindowSurfac
      *    s = EGLContext.getEGL().eglCreateWindowSurface(new EGLDisplayImpl(dpy),
      *                                                   new EGLConfigImpl(config),
      *                                                   view.getHolder(), null);
      *    return s.mEGLSurface;
      *
      * We can't do it from java, because the EGLConfigImpl constructor is private.
      */
 
-    jobject surfaceHolder = sview.GetSurfaceHolder(env, &jniFrame);
+    jobject surfaceHolder = sview.GetSurfaceHolder(&jniFrame);
     if (!surfaceHolder)
         return nsnull;
 
     // grab some fields and methods we'll need
     jmethodID constructConfig = env->GetMethodID(jEGLConfigImplClass, "<init>", "(I)V");
     jmethodID constructDisplay = env->GetMethodID(jEGLDisplayImplClass, "<init>", "(I)V");
 
     jmethodID getEgl = env->GetStaticMethodID(jEGLContextClass, "getEGL", "()Ljavax/microedition/khronos/egl/EGL;");
--- a/widget/android/AndroidBridge.h
+++ b/widget/android/AndroidBridge.h
@@ -569,16 +569,20 @@ public:
     // any local refs that you need to keep around in global refs!
     void Purge() {
         if (mJNIEnv) {
             mJNIEnv->PopLocalFrame(NULL);
             Push();
         }
     }
 
+    JNIEnv* GetEnv() {
+        return mJNIEnv;
+    }
+
     bool CheckForException() {
         if (mJNIEnv->ExceptionCheck()) {
             mJNIEnv->ExceptionDescribe();
             mJNIEnv->ExceptionClear();
             return true;
         }
 
         return false;
--- a/widget/android/AndroidJavaWrappers.cpp
+++ b/widget/android/AndroidJavaWrappers.cpp
@@ -731,115 +731,158 @@ AndroidGeckoLayerClient::SyncViewportInf
     AndroidViewTransform viewTransform;
     viewTransform.Init(viewTransformJObj);
 
     aScrollOffset = nsIntPoint(viewTransform.GetX(env), viewTransform.GetY(env));
     aScaleX = aScaleY = viewTransform.GetScale(env);
 }
 
 jobject
-AndroidGeckoSurfaceView::GetSoftwareDrawBitmap(JNIEnv *env, AutoLocalJNIFrame *jniFrame)
+AndroidGeckoSurfaceView::GetSoftwareDrawBitmap(AutoLocalJNIFrame *jniFrame)
 {
-    if (!env || !jniFrame)
+    if (!jniFrame || !jniFrame->GetEnv())
         return nsnull;
 
-    jobject ret = env->CallObjectMethod(wrapped_obj, jGetSoftwareDrawBitmapMethod);
+    jobject ret = jniFrame->GetEnv()->CallObjectMethod(wrapped_obj, jGetSoftwareDrawBitmapMethod);
     if (jniFrame->CheckForException())
         return nsnull;
 
     return ret;
 }
 
 jobject
-AndroidGeckoSurfaceView::GetSoftwareDrawBuffer(JNIEnv *env, AutoLocalJNIFrame *jniFrame)
+AndroidGeckoSurfaceView::GetSoftwareDrawBuffer(AutoLocalJNIFrame *jniFrame)
 {
-    if (!env || !jniFrame)
+    if (!jniFrame || !jniFrame->GetEnv())
         return nsnull;
 
-    jobject ret = env->CallObjectMethod(wrapped_obj, jGetSoftwareDrawBufferMethod);
+    jobject ret = jniFrame->GetEnv()->CallObjectMethod(wrapped_obj, jGetSoftwareDrawBufferMethod);
     if (jniFrame->CheckForException())
         return nsnull;
 
     return ret;
 }
 
 jobject
-AndroidGeckoSurfaceView::GetSurface(JNIEnv *env, AutoLocalJNIFrame *jniFrame)
+AndroidGeckoSurfaceView::GetSurface(AutoLocalJNIFrame *jniFrame)
 {
-    if (!env || !jniFrame)
+    if (!jniFrame || !jniFrame->GetEnv())
         return nsnull;
 
-    jobject ret = env->CallObjectMethod(wrapped_obj, jGetSurfaceMethod);
+    jobject ret = jniFrame->GetEnv()->CallObjectMethod(wrapped_obj, jGetSurfaceMethod);
     if (jniFrame->CheckForException())
         return nsnull;
 
     return ret;
 }
 
 jobject
-AndroidGeckoSurfaceView::GetSurfaceHolder(JNIEnv *env, AutoLocalJNIFrame *jniFrame)
+AndroidGeckoSurfaceView::GetSurfaceHolder(AutoLocalJNIFrame *jniFrame)
 {
-    if (!env || !jniFrame)
+    if (!jniFrame || !jniFrame->GetEnv())
         return nsnull;
 
-    jobject ret = env->CallObjectMethod(wrapped_obj, jGetHolderMethod);
+    jobject ret = jniFrame->GetEnv()->CallObjectMethod(wrapped_obj, jGetHolderMethod);
     if (jniFrame->CheckForException())
         return nsnull;
 
     return ret;
 }
 
 bool
-AndroidGeckoLayerClient::CreateFrame(JNIEnv *env, AndroidLayerRendererFrame& aFrame)
+AndroidGeckoLayerClient::CreateFrame(AutoLocalJNIFrame *jniFrame, AndroidLayerRendererFrame& aFrame)
 {
-    AutoLocalJNIFrame jniFrame(env, 1);
+    if (!jniFrame || !jniFrame->GetEnv())
+        return false;
 
-    jobject frameJObj = env->CallObjectMethod(wrapped_obj, jCreateFrameMethod);
-    if (jniFrame.CheckForException())
+    jobject frameJObj = jniFrame->GetEnv()->CallObjectMethod(wrapped_obj, jCreateFrameMethod);
+    if (jniFrame->CheckForException())
         return false;
     NS_ABORT_IF_FALSE(frameJObj, "No frame object!");
 
-    aFrame.Init(env, frameJObj);
+    aFrame.Init(jniFrame->GetEnv(), frameJObj);
+    return true;
+}
+
+bool
+AndroidGeckoLayerClient::ActivateProgram(AutoLocalJNIFrame *jniFrame)
+{
+    if (!jniFrame || !jniFrame->GetEnv())
+        return false;
+
+    jniFrame->GetEnv()->CallVoidMethod(wrapped_obj, jActivateProgramMethod);
+    if (jniFrame->CheckForException())
+        return false;
+
+    return true;
+}
+
+bool
+AndroidGeckoLayerClient::DeactivateProgram(AutoLocalJNIFrame *jniFrame)
+{
+    if (!jniFrame || !jniFrame->GetEnv())
+        return false;
+
+    jniFrame->GetEnv()->CallVoidMethod(wrapped_obj, jDeactivateProgramMethod);
+    if (jniFrame->CheckForException())
+        return false;
+
     return true;
 }
 
-void
-AndroidGeckoLayerClient::ActivateProgram(JNIEnv *env)
+bool
+AndroidLayerRendererFrame::BeginDrawing(AutoLocalJNIFrame *jniFrame)
 {
-    env->CallVoidMethod(wrapped_obj, jActivateProgramMethod);
-}
+    if (!jniFrame || !jniFrame->GetEnv())
+        return false;
 
-void
-AndroidGeckoLayerClient::DeactivateProgram(JNIEnv *env)
-{
-    env->CallVoidMethod(wrapped_obj, jDeactivateProgramMethod);
+    jniFrame->GetEnv()->CallVoidMethod(wrapped_obj, jBeginDrawingMethod);
+    if (jniFrame->CheckForException())
+        return false;
+
+    return true;
 }
 
-void
-AndroidLayerRendererFrame::BeginDrawing(JNIEnv *env)
+bool
+AndroidLayerRendererFrame::DrawBackground(AutoLocalJNIFrame *jniFrame)
 {
-    env->CallVoidMethod(wrapped_obj, jBeginDrawingMethod);
+    if (!jniFrame || !jniFrame->GetEnv())
+        return false;
+
+    jniFrame->GetEnv()->CallVoidMethod(wrapped_obj, jDrawBackgroundMethod);
+    if (jniFrame->CheckForException())
+        return false;
+
+    return true;
 }
 
-void
-AndroidLayerRendererFrame::DrawBackground(JNIEnv *env)
+bool
+AndroidLayerRendererFrame::DrawForeground(AutoLocalJNIFrame *jniFrame)
 {
-    env->CallVoidMethod(wrapped_obj, jDrawBackgroundMethod);
+    if (!jniFrame || !jniFrame->GetEnv())
+        return false;
+
+    jniFrame->GetEnv()->CallVoidMethod(wrapped_obj, jDrawForegroundMethod);
+    if (jniFrame->CheckForException())
+        return false;
+
+    return true;
 }
 
-void
-AndroidLayerRendererFrame::DrawForeground(JNIEnv *env)
+bool
+AndroidLayerRendererFrame::EndDrawing(AutoLocalJNIFrame *jniFrame)
 {
-    env->CallVoidMethod(wrapped_obj, jDrawForegroundMethod);
-}
+    if (!jniFrame || !jniFrame->GetEnv())
+        return false;
 
-void
-AndroidLayerRendererFrame::EndDrawing(JNIEnv *env)
-{
-    env->CallVoidMethod(wrapped_obj, jEndDrawingMethod);
+    jniFrame->GetEnv()->CallVoidMethod(wrapped_obj, jEndDrawingMethod);
+    if (jniFrame->CheckForException())
+        return false;
+
+    return true;
 }
 
 float
 AndroidViewTransform::GetX(JNIEnv *env)
 {
     if (!env)
         return 0.0f;
     return env->GetFloatField(wrapped_obj, jXField);
--- a/widget/android/AndroidJavaWrappers.h
+++ b/widget/android/AndroidJavaWrappers.h
@@ -176,20 +176,20 @@ private:
 
 class AndroidLayerRendererFrame : public WrappedJavaObject {
 public:
     static void InitLayerRendererFrameClass(JNIEnv *jEnv);
 
     void Init(JNIEnv *env, jobject jobj);
     void Dispose(JNIEnv *env);
 
-    void BeginDrawing(JNIEnv *env);
-    void DrawBackground(JNIEnv *env);
-    void DrawForeground(JNIEnv *env);
-    void EndDrawing(JNIEnv *env);
+    bool BeginDrawing(AutoLocalJNIFrame *jniFrame);
+    bool DrawBackground(AutoLocalJNIFrame *jniFrame);
+    bool DrawForeground(AutoLocalJNIFrame *jniFrame);
+    bool EndDrawing(AutoLocalJNIFrame *jniFrame);
 
 private:
     static jclass jLayerRendererFrameClass;
     static jmethodID jBeginDrawingMethod;
     static jmethodID jDrawBackgroundMethod;
     static jmethodID jDrawForegroundMethod;
     static jmethodID jEndDrawingMethod;
 };
@@ -203,19 +203,19 @@ public:
     AndroidGeckoLayerClient() {}
     AndroidGeckoLayerClient(jobject jobj) { Init(jobj); }
 
     void SetFirstPaintViewport(float aOffsetX, float aOffsetY, float aZoom, float aPageWidth, float aPageHeight,
                                float aCssPageWidth, float aCssPageHeight);
     void SetPageSize(float aZoom, float aPageWidth, float aPageHeight, float aCssPageWidth, float aCssPageHeight);
     void SyncViewportInfo(const nsIntRect& aDisplayPort, float aDisplayResolution, bool aLayersUpdated,
                           nsIntPoint& aScrollOffset, float& aScaleX, float& aScaleY);
-    bool CreateFrame(JNIEnv *env, AndroidLayerRendererFrame& aFrame);
-    void ActivateProgram(JNIEnv *env);
-    void DeactivateProgram(JNIEnv *env);
+    bool CreateFrame(AutoLocalJNIFrame *jniFrame, AndroidLayerRendererFrame& aFrame);
+    bool ActivateProgram(AutoLocalJNIFrame *jniFrame);
+    bool DeactivateProgram(AutoLocalJNIFrame *jniFrame);
 
 protected:
     static jclass jGeckoLayerClientClass;
     static jmethodID jSetFirstPaintViewport;
     static jmethodID jSetPageSize;
     static jmethodID jSyncViewportInfoMethod;
     static jmethodID jCreateFrameMethod;
     static jmethodID jActivateProgramMethod;
@@ -237,24 +237,24 @@ public:
     enum {
         DRAW_ERROR = 0,
         DRAW_GLES_2 = 1,
         DRAW_2D = 2,
         DRAW_DISABLED = 3
     };
 
     int BeginDrawing();
-    jobject GetSoftwareDrawBitmap(JNIEnv *env, AutoLocalJNIFrame *jniFrame);
-    jobject GetSoftwareDrawBuffer(JNIEnv *env, AutoLocalJNIFrame *jniFrame);
+    jobject GetSoftwareDrawBitmap(AutoLocalJNIFrame *jniFrame);
+    jobject GetSoftwareDrawBuffer(AutoLocalJNIFrame *jniFrame);
     void EndDrawing();
     void Draw2D(jobject bitmap, int width, int height);
     void Draw2D(jobject buffer, int stride);
 
-    jobject GetSurface(JNIEnv *env, AutoLocalJNIFrame *jniFrame);
-    jobject GetSurfaceHolder(JNIEnv *env, AutoLocalJNIFrame *jniFrame);
+    jobject GetSurface(AutoLocalJNIFrame *jniFrame);
+    jobject GetSurfaceHolder(AutoLocalJNIFrame *jniFrame);
 
 protected:
     static jclass jGeckoSurfaceViewClass;
     static jmethodID jBeginDrawingMethod;
     static jmethodID jEndDrawingMethod;
     static jmethodID jDraw2DBitmapMethod;
     static jmethodID jDraw2DBufferMethod;
     static jmethodID jGetSoftwareDrawBitmapMethod;
--- a/widget/android/nsWindow.cpp
+++ b/widget/android/nsWindow.cpp
@@ -912,17 +912,17 @@ nsWindow::OnGlobalAndroidEvent(AndroidGe
         case AndroidGeckoEvent::SURFACE_CREATED:
             sSurfaceExists = true;
 
             if (AndroidBridge::Bridge()->HasNativeWindowAccess()) {
                 AndroidGeckoSurfaceView& sview(AndroidBridge::Bridge()->SurfaceView());
                 JNIEnv *env = AndroidBridge::GetJNIEnv();
                 if (env) {
                     AutoLocalJNIFrame jniFrame(env);
-                    jobject surface = sview.GetSurface(env, &jniFrame);
+                    jobject surface = sview.GetSurface(&jniFrame);
                     if (surface) {
                         sNativeWindow = AndroidBridge::Bridge()->AcquireNativeWindow(env, surface);
                         if (sNativeWindow) {
                             AndroidBridge::Bridge()->SetNativeWindowFormat(sNativeWindow, 0, 0, AndroidBridge::WINDOW_FORMAT_RGB_565);
                         }
                     }
                 }
             }
@@ -1176,17 +1176,17 @@ nsWindow::OnDraw(AndroidGeckoEvent *ae)
             if (targetSurface->CairoStatus()) {
                 ALOG("### Failed to create a valid surface from the bitmap");
             } else {
                 DrawTo(targetSurface);
             }
 
             AndroidBridge::Bridge()->UnlockWindow(sNativeWindow);
         } else if (AndroidBridge::Bridge()->HasNativeBitmapAccess()) {
-            jobject bitmap = sview.GetSoftwareDrawBitmap(env, &jniFrame);
+            jobject bitmap = sview.GetSoftwareDrawBitmap(&jniFrame);
             if (!bitmap) {
                 ALOG("no bitmap to draw into - skipping draw");
                 return;
             }
 
             if (!AndroidBridge::Bridge()->ValidateBitmap(bitmap, mBounds.width, mBounds.height))
                 return;
 
@@ -1205,17 +1205,17 @@ nsWindow::OnDraw(AndroidGeckoEvent *ae)
                 ALOG("### Failed to create a valid surface from the bitmap");
             } else {
                 DrawTo(targetSurface);
             }
 
             AndroidBridge::Bridge()->UnlockBitmap(bitmap);
             sview.Draw2D(bitmap, mBounds.width, mBounds.height);
         } else {
-            jobject bytebuf = sview.GetSoftwareDrawBuffer(env, &jniFrame);
+            jobject bytebuf = sview.GetSoftwareDrawBuffer(&jniFrame);
             if (!bytebuf) {
                 ALOG("no buffer to draw into - skipping draw");
                 return;
             }
 
             void *buf = env->GetDirectBufferAddress(bytebuf);
             int cap = env->GetDirectBufferCapacity(bytebuf);
             if (!buf || cap != (mBounds.width * mBounds.height * 2)) {
@@ -2228,25 +2228,21 @@ nsWindow::DrawWindowUnderlay(LayerManage
     JNIEnv *env = GetJNIForThread();
     NS_ABORT_IF_FALSE(env, "No JNI environment at DrawWindowUnderlay()!");
     if (!env)
         return;
 
     AutoLocalJNIFrame jniFrame(env);
 
     AndroidGeckoLayerClient& client = AndroidBridge::Bridge()->GetLayerClient();
-    if (!client.CreateFrame(env, mLayerRendererFrame))
-        return;
-    client.ActivateProgram(env);
-    if (jniFrame.CheckForException()) return;
-    mLayerRendererFrame.BeginDrawing(env);
-    if (jniFrame.CheckForException()) return;
-    mLayerRendererFrame.DrawBackground(env);
-    if (jniFrame.CheckForException()) return;
-    client.DeactivateProgram(env);
+    if (!client.CreateFrame(&jniFrame, mLayerRendererFrame)) return;
+    if (!client.ActivateProgram(&jniFrame)) return;
+    if (!mLayerRendererFrame.BeginDrawing(&jniFrame)) return;
+    if (!mLayerRendererFrame.DrawBackground(&jniFrame)) return;
+    if (!client.DeactivateProgram(&jniFrame)) return; // redundant, but in case somebody adds code after this...
 }
 
 void
 nsWindow::DrawWindowOverlay(LayerManager* aManager, nsIntRect aRect)
 {
     JNIEnv *env = GetJNIForThread();
     NS_ABORT_IF_FALSE(env, "No JNI environment at DrawWindowOverlay()!");
     if (!env)
@@ -2254,25 +2250,20 @@ nsWindow::DrawWindowOverlay(LayerManager
 
     AutoLocalJNIFrame jniFrame(env);
 
     NS_ABORT_IF_FALSE(!mLayerRendererFrame.isNull(),
                       "Frame should have been created in DrawWindowUnderlay()!");
 
     AndroidGeckoLayerClient& client = AndroidBridge::Bridge()->GetLayerClient();
 
-    client.ActivateProgram(env);
-    if (jniFrame.CheckForException()) return;
-    mLayerRendererFrame.DrawForeground(env);
-    if (jniFrame.CheckForException()) return;
-    mLayerRendererFrame.EndDrawing(env);
-    if (jniFrame.CheckForException()) return;
-    client.DeactivateProgram(env);
-    if (jniFrame.CheckForException()) return;
-
+    if (!client.ActivateProgram(&jniFrame)) return;
+    if (!mLayerRendererFrame.DrawForeground(&jniFrame)) return;
+    if (!mLayerRendererFrame.EndDrawing(&jniFrame)) return;
+    if (!client.DeactivateProgram(&jniFrame)) return;
     mLayerRendererFrame.Dispose(env);
 }
 
 // off-main-thread compositor fields and functions
 
 nsRefPtr<mozilla::layers::CompositorParent> nsWindow::sCompositorParent = 0;
 nsRefPtr<mozilla::layers::CompositorChild> nsWindow::sCompositorChild = 0;
 base::Thread * nsWindow::sCompositorThread = 0;