Merge from mozilla-central.
authorDavid Anderson <danderson@mozilla.com>
Wed, 20 Jun 2012 17:36:56 -0700
changeset 106350 881c4b8e74045a4033f68ec402c245f5939481f8
parent 106349 a0c81536dd0b3278bb92a174696f51f6c0d71f6b (current diff)
parent 97119 e240d6e43c9a675ecbaea450d96cf55601ea0119 (diff)
child 106351 57adfe34193eb24d16b80276dc464eadff3c8535
push id23447
push userdanderson@mozilla.com
push dateTue, 11 Sep 2012 17:34:27 +0000
treeherdermozilla-central@fdfaef738a00 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone16.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge from mozilla-central.
accessible/src/base/AccEvent.cpp
accessible/src/base/NotificationController.cpp
accessible/src/base/TextAttrs.cpp
accessible/src/base/nsAccessibilityService.cpp
accessible/src/base/nsAccessibilityService.h
accessible/src/base/nsTextEquivUtils.cpp
accessible/src/generic/ARIAGridAccessible.cpp
accessible/src/generic/ARIAGridAccessible.h
accessible/src/generic/Accessible.cpp
accessible/src/generic/HyperTextAccessible.cpp
accessible/src/generic/HyperTextAccessible.h
accessible/src/html/HTMLFormControlAccessible.cpp
accessible/src/html/HTMLTableAccessible.cpp
accessible/src/html/HTMLTableAccessible.h
accessible/src/mac/mozTextAccessible.mm
accessible/src/msaa/CAccessibleEditableText.cpp
accessible/src/msaa/CAccessibleEditableText.h
accessible/src/msaa/CAccessibleText.cpp
accessible/src/msaa/CAccessibleText.h
accessible/src/msaa/HyperTextAccessibleWrap.cpp
accessible/src/msaa/HyperTextAccessibleWrap.h
accessible/src/msaa/ia2AccessibleText.cpp
accessible/src/msaa/ia2AccessibleText.h
accessible/src/xforms/nsXFormsFormControlsAccessible.cpp
accessible/src/xul/XULFormControlAccessible.cpp
accessible/src/xul/XULTreeAccessible.cpp
accessible/src/xul/XULTreeGridAccessible.cpp
accessible/src/xul/XULTreeGridAccessible.h
accessible/tests/mochitest/common.js
accessible/tests/mochitest/events.js
b2g/installer/package-manifest.in
browser/app/nsBrowserApp.cpp
browser/app/profile/firefox.js
browser/base/content/browser.js
browser/base/content/browser.xul
browser/components/nsBrowserContentHandler.js
browser/components/shell/src/nsWindowsShellService.cpp
browser/devtools/webconsole/HUDService.jsm
browser/devtools/webconsole/test/browser_webconsole_bug_595934_message_categories.js
browser/devtools/webconsole/test/browser_webconsole_bug_642108_pruneTest.js
build/autoconf/mozconfig2client-mk
build/mobile/devicemanagerADB.py
build/mobile/devicemanagerSUT.py
caps/src/nsScriptSecurityManager.cpp
config/autoconf.mk.in
configure.in
content/base/public/nsContentUtils.h
content/base/public/nsIContent.h
content/base/public/nsINode.h
content/base/src/ThirdPartyUtil.h
content/base/src/nsCCUncollectableMarker.h
content/base/src/nsContentIterator.cpp
content/base/src/nsContentUtils.cpp
content/base/src/nsCrossSiteListenerProxy.cpp
content/base/src/nsCrossSiteListenerProxy.h
content/base/src/nsDOMFile.cpp
content/base/src/nsDOMTokenList.h
content/base/src/nsDocument.cpp
content/base/src/nsDocument.h
content/base/src/nsEventSource.cpp
content/base/src/nsFrameLoader.h
content/base/src/nsFrameMessageManager.h
content/base/src/nsGenericElement.cpp
content/base/src/nsGenericElement.h
content/base/src/nsGkAtomList.h
content/base/src/nsMappedAttributes.h
content/base/src/nsNodeInfoManager.cpp
content/base/src/nsPropertyTable.cpp
content/base/src/nsPropertyTable.h
content/base/src/nsRange.cpp
content/base/src/nsScriptLoader.cpp
content/base/src/nsXMLHttpRequest.cpp
content/base/test/test_bug352728.html
content/canvas/public/nsICanvasRenderingContextInternal.h
content/canvas/src/WebGLContext.cpp
content/canvas/src/WebGLContext.h
content/canvas/src/WebGLContextGL.cpp
content/canvas/src/WebGLContextValidate.cpp
content/canvas/src/nsCanvasRenderingContext2D.cpp
content/canvas/src/nsCanvasRenderingContext2DAzure.cpp
content/canvas/test/test_canvas.html
content/events/src/nsDOMDataTransfer.h
content/events/src/nsDOMEventTargetHelper.h
content/events/src/nsDOMTouchEvent.h
content/events/src/nsEventListenerManager.cpp
content/events/src/nsEventListenerService.h
content/events/src/nsEventStateManager.cpp
content/events/src/nsIMEStateManager.cpp
content/events/src/nsXMLEventsManager.h
content/media/MediaResource.h
content/media/nsAudioStream.cpp
content/media/nsMediaCache.cpp
content/smil/nsSMILAnimationController.cpp
content/smil/nsSMILCSSProperty.cpp
content/svg/content/src/DOMSVGAnimatedLengthList.h
content/svg/content/src/DOMSVGAnimatedNumberList.h
content/svg/content/src/DOMSVGAnimatedTransformList.h
content/svg/content/src/DOMSVGLength.h
content/svg/content/src/DOMSVGLengthList.h
content/svg/content/src/DOMSVGMatrix.h
content/svg/content/src/DOMSVGNumber.h
content/svg/content/src/DOMSVGNumberList.h
content/svg/content/src/DOMSVGPathSegList.h
content/svg/content/src/DOMSVGPoint.h
content/svg/content/src/DOMSVGPointList.h
content/svg/content/src/DOMSVGTransform.h
content/svg/content/src/DOMSVGTransformList.h
content/svg/content/src/SVGAnimatedPreserveAspectRatio.h
content/svg/content/src/nsSVGAngle.cpp
content/svg/content/src/nsSVGAngle.h
content/svg/content/src/nsSVGBoolean.h
content/svg/content/src/nsSVGClass.h
content/svg/content/src/nsSVGElement.cpp
content/svg/content/src/nsSVGEnum.h
content/svg/content/src/nsSVGFilters.cpp
content/svg/content/src/nsSVGInteger.h
content/svg/content/src/nsSVGIntegerPair.h
content/svg/content/src/nsSVGLength2.cpp
content/svg/content/src/nsSVGMarkerElement.h
content/svg/content/src/nsSVGNumber2.cpp
content/svg/content/src/nsSVGNumber2.h
content/svg/content/src/nsSVGNumberPair.h
content/svg/content/src/nsSVGRect.h
content/svg/content/src/nsSVGSVGElement.cpp
content/svg/content/src/nsSVGSVGElement.h
content/svg/content/src/nsSVGString.h
content/svg/content/src/nsSVGUseElement.cpp
content/svg/content/src/nsSVGViewBox.h
content/xbl/src/nsXBLBinding.cpp
content/xbl/src/nsXBLInsertionPoint.cpp
content/xbl/src/nsXBLPrototypeBinding.cpp
content/xbl/src/nsXBLService.cpp
content/xslt/src/xpath/nsXPathResult.h
content/xslt/src/xpath/txXPCOMExtensionFunction.cpp
content/xslt/src/xslt/txMozillaStylesheetCompiler.cpp
content/xslt/src/xslt/txMozillaXMLOutput.h
content/xslt/src/xslt/txMozillaXSLTProcessor.h
content/xtf/src/nsXTFElementWrapper.h
content/xul/content/src/nsXULElement.cpp
content/xul/templates/src/nsRDFQuery.h
content/xul/templates/src/nsXULTemplateQueryProcessorRDF.h
content/xul/templates/src/nsXULTemplateQueryProcessorStorage.h
content/xul/templates/src/nsXULTemplateQueryProcessorXML.cpp
content/xul/templates/src/nsXULTemplateQueryProcessorXML.h
content/xul/templates/src/nsXULTemplateResultRDF.h
content/xul/templates/src/nsXULTemplateResultSetRDF.h
docshell/base/nsDocShell.cpp
dom/base/ConsoleAPI.js
dom/base/nsDOMClassInfo.cpp
dom/base/nsDOMClassInfo.h
dom/base/nsDOMClassInfoClasses.h
dom/base/nsDOMScriptObjectFactory.cpp
dom/base/nsDOMScriptObjectFactory.h
dom/base/nsDOMWindowUtils.h
dom/base/nsFocusManager.h
dom/base/nsGlobalWindow.cpp
dom/base/nsGlobalWindow.h
dom/base/nsGlobalWindowCommands.cpp
dom/base/nsJSEnvironment.cpp
dom/base/nsJSEnvironment.h
dom/base/nsJSTimeoutHandler.cpp
dom/base/nsQueryContentEventResult.h
dom/base/nsScriptNameSpaceManager.cpp
dom/base/nsScriptNameSpaceManager.h
dom/base/nsWrapperCache.h
dom/indexedDB/IDBCursor.cpp
dom/indexedDB/IDBDatabase.cpp
dom/indexedDB/IDBKeyRange.cpp
dom/indexedDB/IDBObjectStore.h
dom/indexedDB/IDBTransaction.cpp
dom/indexedDB/IndexedDatabaseManager.cpp
dom/indexedDB/test/unit/test_writer_starvation.js
dom/ipc/ContentChild.cpp
dom/ipc/TabChild.h
dom/src/geolocation/nsGeolocation.cpp
dom/src/geolocation/nsGeolocation.h
dom/src/storage/nsDOMStorage.h
dom/src/storage/nsDOMStoragePersistentDB.cpp
dom/system/nsDeviceSensors.cpp
dom/workers/WorkerPrivate.cpp
dom/workers/XMLHttpRequest.cpp
editor/libeditor/html/nsHTMLEditRules.cpp
editor/libeditor/html/nsHTMLEditRules.h
editor/txmgr/src/nsTransactionItem.cpp
extensions/cookie/nsPermissionManager.cpp
extensions/cookie/nsPermissionManager.h
gfx/gl/GLContext.cpp
gfx/gl/GLContextProviderEGL.cpp
gfx/layers/ImageLayers.h
gfx/thebes/gfxAndroidPlatform.cpp
gfx/thebes/gfxAndroidPlatform.h
gfx/thebes/gfxPlatform.cpp
intl/lwbrk/public/nsILineBreaker.h
js/src/config/autoconf.mk.in
js/src/configure.in
js/src/frontend/BytecodeCompiler.cpp
js/src/frontend/BytecodeCompiler.h
js/src/frontend/BytecodeEmitter.cpp
js/src/frontend/Parser.cpp
js/src/gc/Marking.cpp
js/src/gc/Root.h
js/src/ion/CodeGenerator.cpp
js/src/jsapi.cpp
js/src/jsapi.h
js/src/jsarray.cpp
js/src/jsatom.cpp
js/src/jsatom.h
js/src/jsatominlines.h
js/src/jscntxt.h
js/src/jscompartment.cpp
js/src/jsdbgapi.cpp
js/src/jsgc.cpp
js/src/jsgc.h
js/src/jsinfer.cpp
js/src/jsinfer.h
js/src/jsinterpinlines.h
js/src/jsnum.cpp
js/src/jsnum.h
js/src/jsobj.cpp
js/src/jsopcode.cpp
js/src/jsproxy.cpp
js/src/jspubtd.h
js/src/jsscript.cpp
js/src/jsstr.cpp
js/src/jstypedarray.cpp
js/src/jsutil.h
js/src/jsxml.cpp
js/src/methodjit/FastOps.cpp
js/src/methodjit/MonoIC.cpp
js/src/vm/Debugger.cpp
js/src/vm/ScopeObject.cpp
js/src/vm/Stack-inl.h
js/src/vm/Stack.cpp
js/src/vm/Stack.h
js/src/vm/String.cpp
js/src/vm/String.h
js/xpconnect/idl/xpccomponents.idl
js/xpconnect/public/xpc_map_end.h
js/xpconnect/src/XPCComponents.cpp
js/xpconnect/src/XPCJSRuntime.cpp
js/xpconnect/src/XPCMaps.cpp
js/xpconnect/src/XPCMaps.h
js/xpconnect/src/XPCWrappedJS.cpp
js/xpconnect/src/XPCWrappedNative.cpp
js/xpconnect/src/nsXPConnect.cpp
js/xpconnect/src/xpcprivate.h
js/xpconnect/src/xpcpublic.h
js/xpconnect/wrappers/AccessCheck.cpp
js/xpconnect/wrappers/AccessCheck.h
js/xpconnect/wrappers/XrayWrapper.cpp
layout/base/nsCSSFrameConstructor.cpp
layout/base/nsCSSRendering.cpp
layout/base/nsDisplayList.cpp
layout/base/nsDisplayList.h
layout/base/nsFrameTraversal.cpp
layout/base/nsLayoutHistoryState.cpp
layout/base/nsPresShell.h
layout/base/nsRefreshDriver.h
layout/build/nsLayoutModule.cpp
layout/forms/nsFileControlFrame.h
layout/forms/nsListControlFrame.cpp
layout/forms/nsTextControlFrame.cpp
layout/forms/nsTextControlFrame.h
layout/generic/crashtests/crashtests.list
layout/generic/nsGfxScrollFrame.cpp
layout/generic/nsImageFrame.h
layout/generic/nsSubDocumentFrame.cpp
layout/generic/nsTextFrameThebes.cpp
layout/mathml/nsMathMLmactionFrame.h
layout/printing/nsPagePrintTimer.h
layout/printing/nsPrintEngine.h
layout/reftests/reftest-sanity/reftest.list
layout/reftests/svg/dynamic-use-nested-01.svg
layout/reftests/svg/reftest.list
layout/reftests/svg/smil/reftest.list
layout/style/AnimationCommon.h
layout/style/Loader.h
layout/style/nsDOMMediaQueryList.h
layout/style/nsHTMLCSSStyleSheet.h
layout/style/nsHTMLStyleSheet.h
layout/style/nsIMediaList.h
layout/style/nsLayoutStylesheetCache.h
layout/style/nsStyleSet.h
layout/svg/base/src/nsSVGClipPathFrame.cpp
layout/svg/base/src/nsSVGClipPathFrame.h
layout/svg/base/src/nsSVGFilterFrame.cpp
layout/svg/base/src/nsSVGGlyphFrame.cpp
layout/svg/base/src/nsSVGIntegrationUtils.cpp
layout/svg/base/src/nsSVGIntegrationUtils.h
layout/svg/base/src/nsSVGPathGeometryFrame.cpp
layout/svg/base/src/nsSVGUtils.cpp
layout/svg/base/src/nsSVGUtils.h
layout/xul/base/public/nsXULPopupManager.h
layout/xul/base/src/nsMenuFrame.h
layout/xul/base/src/nsXULTooltipListener.h
layout/xul/base/src/tree/src/nsTreeColumns.h
layout/xul/base/src/tree/src/nsTreeContentView.h
layout/xul/base/src/tree/src/nsTreeImageListener.h
layout/xul/base/src/tree/src/nsTreeSelection.h
memory/mozjemalloc/jemalloc.c
mfbt/Assertions.cpp
mobile/android/base/AndroidManifest.xml.in
mobile/android/base/GeckoApp.java
mobile/android/base/GeckoAppShell.java
mobile/android/base/LauncherShortcuts.java.in
mobile/android/base/Makefile.in
mobile/android/base/resources/layout-sw600dp/tabs_panel.xml
mobile/android/base/resources/layout-xlarge/tabs_panel.xml
mobile/android/chrome/content/bindings.xml
mobile/android/chrome/content/bindings/dialog.xml
mobile/android/chrome/content/browser.css
modules/libpref/src/init/all.js
mozglue/android/APKOpen.cpp
netwerk/dns/nsHostResolver.cpp
netwerk/protocol/http/HttpBaseChannel.cpp
netwerk/protocol/http/nsHttpChannel.cpp
netwerk/protocol/http/nsHttpConnection.cpp
netwerk/protocol/http/nsHttpConnectionInfo.cpp
netwerk/protocol/http/nsHttpConnectionInfo.h
netwerk/protocol/http/nsHttpConnectionMgr.cpp
netwerk/protocol/http/nsHttpTransaction.cpp
parser/html/nsParserUtils.cpp
testing/mochitest/mozprefs.js
toolkit/components/telemetry/Telemetry.cpp
toolkit/components/telemetry/TelemetryHistograms.h
toolkit/content/widgets/popup.xml
toolkit/content/widgets/tabbox.xml
toolkit/content/widgets/videocontrols.xml
toolkit/content/xul.css
toolkit/crashreporter/Makefile.in
toolkit/mozapps/installer/packager.mk
toolkit/themes/winstripe/global/arrow/panelarrow-down-aero.png
toolkit/themes/winstripe/global/arrow/panelarrow-down.png
toolkit/themes/winstripe/global/arrow/panelarrow-horiz-aero.png
toolkit/themes/winstripe/global/arrow/panelarrow-horiz.png
toolkit/themes/winstripe/global/arrow/panelarrow-up-aero.png
toolkit/themes/winstripe/global/arrow/panelarrow-up.png
toolkit/themes/winstripe/global/popup-aero.css
toolkit/xre/nsAppData.cpp
toolkit/xre/nsAppRunner.cpp
toolkit/xre/nsAppRunner.h
toolkit/xre/nsEmbedFunctions.cpp
toolkit/xre/nsNativeAppSupportUnix.cpp
toolkit/xre/nsSigHandlers.cpp
uriloader/base/nsURILoader.cpp
view/src/nsView.cpp
widget/android/nsWindow.cpp
widget/android/nsWindow.h
widget/cocoa/nsCocoaWindow.mm
widget/nsGUIEvent.h
widget/windows/KeyboardLayout.cpp
widget/windows/KeyboardLayout.h
widget/windows/nsIMM32Handler.cpp
widget/windows/nsNativeDragTarget.cpp
widget/windows/nsWindow.cpp
widget/windows/nsWindow.h
widget/windows/nsWindowDefs.h
widget/xpwidgets/PuppetWidget.h
widget/xpwidgets/nsBaseWidget.cpp
widget/xpwidgets/nsClipboardPrivacyHandler.h
widget/xpwidgets/nsNativeTheme.h
xpcom/base/nsAgg.h
xpcom/base/nsCycleCollector.cpp
xpcom/glue/nsCycleCollectionParticipant.cpp
xpcom/glue/nsCycleCollectionParticipant.h
xpcom/io/nsLocalFileUnix.cpp
xpcom/reflect/xptinfo/src/xptiInterfaceInfoManager.cpp
xpcom/reflect/xptinfo/src/xptiprivate.h
xulrunner/makefiles.sh
--- a/Makefile.in
+++ b/Makefile.in
@@ -161,16 +161,17 @@ ifdef USE_ELF_HACK
 endif
 	echo building symbol store
 	$(RM) -r $(DIST)/crashreporter-symbols
 	$(RM) "$(DIST)/$(SYMBOL_ARCHIVE_BASENAME).zip"
 	$(NSINSTALL) -D $(DIST)/crashreporter-symbols
 	OBJCOPY="$(OBJCOPY)" \
 	$(PYTHON) $(topsrcdir)/toolkit/crashreporter/tools/symbolstore.py \
 	  $(MAKE_SYM_STORE_ARGS)                                          \
+	  --exclude="*test*" --exclude="*Test*"                           \
 	  $(foreach dir,$(SYM_STORE_SOURCE_DIRS),-s $(dir))               \
 	  $(DUMP_SYMS_BIN)                                                \
 	  $(DIST)/crashreporter-symbols                                   \
 	  $(MAKE_SYM_STORE_PATH) >                                        \
 	  $(DIST)/crashreporter-symbols/$(SYMBOL_INDEX_NAME)
 	echo packing symbols
 	$(NSINSTALL) -D $(DIST)/$(PKG_PATH)
 	cd $(DIST)/crashreporter-symbols && \
--- a/accessible/src/base/AccEvent.cpp
+++ b/accessible/src/base/AccEvent.cpp
@@ -83,17 +83,17 @@ AccEvent::CreateXPCOMObject()
   nsAccEvent* event = new nsAccEvent(this);
   NS_IF_ADDREF(event);
   return event;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // AccEvent cycle collection
 
-NS_IMPL_CYCLE_COLLECTION_CLASS(AccEvent)
+NS_IMPL_CYCLE_COLLECTION_NATIVE_CLASS(AccEvent)
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_NATIVE(AccEvent)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mAccessible)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_BEGIN(AccEvent)
   NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mAccessible");
   cb.NoteXPCOMChild(static_cast<nsIAccessible*>(tmp->mAccessible));
--- a/accessible/src/base/NotificationController.cpp
+++ b/accessible/src/base/NotificationController.cpp
@@ -51,17 +51,17 @@ NotificationController::~NotificationCon
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // NotificationCollector: AddRef/Release and cycle collection
 
 NS_IMPL_ADDREF(NotificationController)
 NS_IMPL_RELEASE(NotificationController)
 
-NS_IMPL_CYCLE_COLLECTION_CLASS(NotificationController)
+NS_IMPL_CYCLE_COLLECTION_NATIVE_CLASS(NotificationController)
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_NATIVE(NotificationController)
   if (tmp->mDocument)
     tmp->Shutdown();
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_BEGIN(NotificationController)
   NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mDocument");
@@ -807,17 +807,17 @@ NotificationController::ContentInsertion
     }
 
     node = node->GetNextSibling();
   }
 
   return haveToUpdate;
 }
 
-NS_IMPL_CYCLE_COLLECTION_CLASS(NotificationController::ContentInsertion)
+NS_IMPL_CYCLE_COLLECTION_NATIVE_CLASS(NotificationController::ContentInsertion)
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_NATIVE(NotificationController::ContentInsertion)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mContainer)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_BEGIN(NotificationController::ContentInsertion)
   NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mContainer");
   cb.NoteXPCOMChild(static_cast<nsIAccessible*>(tmp->mContainer.get()));
--- a/accessible/src/base/StyleInfo.cpp
+++ b/accessible/src/base/StyleInfo.cpp
@@ -42,31 +42,45 @@ StyleInfo::TextAlign(nsAString& aValue)
 void
 StyleInfo::TextIndent(nsAString& aValue)
 {
   aValue.Truncate();
 
   const nsStyleCoord& styleCoord =
     mStyleContext->GetStyleText()->mTextIndent;
 
-  nscoord coordVal;
+  nscoord coordVal = 0;
   switch (styleCoord.GetUnit()) {
     case eStyleUnit_Coord:
       coordVal = styleCoord.GetCoordValue();
       break;
 
     case eStyleUnit_Percent:
     {
       nsIFrame* frame = mElement->GetPrimaryFrame();
       nsIFrame* containerFrame = frame->GetContainingBlock();
       nscoord percentageBase = containerFrame->GetContentRect().width;
       coordVal = NSCoordSaturatingMultiply(percentageBase,
                                            styleCoord.GetPercentValue());
       break;
     }
+
+    case eStyleUnit_Null:
+    case eStyleUnit_Normal:
+    case eStyleUnit_Auto:
+    case eStyleUnit_None:
+    case eStyleUnit_Factor:
+    case eStyleUnit_Degree:
+    case eStyleUnit_Grad:
+    case eStyleUnit_Radian:
+    case eStyleUnit_Turn:
+    case eStyleUnit_Integer:
+    case eStyleUnit_Enumerated:
+    case eStyleUnit_Calc:
+      break;
   }
 
   aValue.AppendFloat(nsPresContext::AppUnitsToFloatCSSPixels(coordVal));
   aValue.AppendLiteral("px");
 }
 
 void
 StyleInfo::Margin(css::Side aSide, nsAString& aValue)
--- a/accessible/src/base/TextAttrs.cpp
+++ b/accessible/src/base/TextAttrs.cpp
@@ -702,16 +702,19 @@ TextAttrsMgr::TextPosTextAttr::
       nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::textPosition,
                              NS_LITERAL_STRING("sub"));
       break;
 
     case eTextPosSuper:
       nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::textPosition,
                              NS_LITERAL_STRING("super"));
       break;
+
+    case eTextPosNone:
+      break;
   }
 }
 
 TextAttrsMgr::TextPosValue
 TextAttrsMgr::TextPosTextAttr::
   GetTextPosValue(nsIFrame* aFrame) const
 {
   const nsStyleCoord& styleCoord = aFrame->GetStyleTextReset()->mVerticalAlign;
@@ -749,16 +752,29 @@ TextAttrsMgr::TextPosTextAttr::
 
     case eStyleUnit_Coord:
     {
        nscoord coordValue = styleCoord.GetCoordValue();
        return coordValue > 0 ?
          eTextPosSuper :
          (coordValue < 0 ? eTextPosSub : eTextPosBaseline);
     }
+
+    case eStyleUnit_Null:
+    case eStyleUnit_Normal:
+    case eStyleUnit_Auto:
+    case eStyleUnit_None:
+    case eStyleUnit_Factor:
+    case eStyleUnit_Degree:
+    case eStyleUnit_Grad:
+    case eStyleUnit_Radian:
+    case eStyleUnit_Turn:
+    case eStyleUnit_Integer:
+    case eStyleUnit_Calc:
+      break;
   }
 
   const nsIContent* content = aFrame->GetContent();
   if (content && content->IsHTML()) {
     const nsIAtom* tagName = content->Tag();
     if (tagName == nsGkAtoms::sup) 
       return eTextPosSuper;
     if (tagName == nsGkAtoms::sub) 
--- a/accessible/src/base/nsAccessibilityService.cpp
+++ b/accessible/src/base/nsAccessibilityService.cpp
@@ -58,16 +58,17 @@
 #include "nsIObserverService.h"
 #include "nsLayoutUtils.h"
 #include "nsNPAPIPluginInstance.h"
 #include "nsISupportsUtils.h"
 #include "nsObjectFrame.h"
 #include "nsTextFragment.h"
 #include "mozilla/FunctionTimer.h"
 #include "mozilla/dom/Element.h"
+#include "mozilla/Preferences.h"
 #include "mozilla/Services.h"
 #include "mozilla/Util.h"
 
 #ifdef MOZ_XUL
 #include "XULAlertAccessible.h"
 #include "XULColorPickerAccessible.h"
 #include "XULComboboxAccessible.h"
 #include "XULElementAccessibles.h"
@@ -1814,13 +1815,35 @@ nsAccessibilityService::CreateAccessible
   return accessible;
 }
 #endif
 
 ////////////////////////////////////////////////////////////////////////////////
 // Services
 ////////////////////////////////////////////////////////////////////////////////
 
-mozilla::a11y::FocusManager*
-mozilla::a11y::FocusMgr()
+namespace mozilla {
+namespace a11y {
+
+FocusManager*
+FocusMgr()
 {
   return nsAccessibilityService::gAccessibilityService;
 }
+
+EPlatformDisabledState
+PlatformDisabledState()
+{
+  static int disabledState = 0xff;
+
+  if (disabledState == 0xff) {
+    disabledState = Preferences::GetInt("accessibility.force_disabled", 0);
+    if (disabledState < ePlatformIsForceEnabled)
+      disabledState = ePlatformIsForceEnabled;
+    else if (disabledState > ePlatformIsDisabled)
+      disabledState = ePlatformIsDisabled;
+  }
+
+  return (EPlatformDisabledState)disabledState;
+}
+
+}
+}
--- a/accessible/src/base/nsAccessibilityService.h
+++ b/accessible/src/base/nsAccessibilityService.h
@@ -21,16 +21,27 @@ class nsITreeView;
 namespace mozilla {
 namespace a11y {
 
 /**
  * Return focus manager.
  */
 FocusManager* FocusMgr();
 
+enum EPlatformDisabledState {
+  ePlatformIsForceEnabled = -1,
+  ePlatformIsEnabled = 0,
+  ePlatformIsDisabled = 1
+};
+
+/**
+ * Return the platform disabled state.
+ */
+EPlatformDisabledState PlatformDisabledState();
+
 #ifdef MOZ_ACCESSIBILITY_ATK
 /**
  * Perform initialization that should be done as soon as possible, in order
  * to minimize startup time.
  * XXX: this function and the next defined in ApplicationAccessibleWrap.cpp
  */
 void PreInit();
 #endif
--- a/accessible/src/base/nsAccessiblePivot.cpp
+++ b/accessible/src/base/nsAccessiblePivot.cpp
@@ -113,17 +113,17 @@ nsAccessiblePivot::SetPosition(nsIAccess
     if (!secondPosition || !IsRootDescendant(secondPosition))
       return NS_ERROR_INVALID_ARG;
   }
 
   // Swap old position with new position, saves us an AddRef/Release.
   mPosition.swap(secondPosition);
   PRInt32 oldStart = mStartOffset, oldEnd = mEndOffset;
   mStartOffset = mEndOffset = -1;
-  NotifyPivotChanged(secondPosition, oldStart, oldEnd);
+  NotifyOfPivotChange(secondPosition, oldStart, oldEnd);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsAccessiblePivot::GetStartOffset(PRInt32* aStartOffset)
 {
   NS_ENSURE_ARG_POINTER(aStartOffset);
@@ -150,34 +150,38 @@ nsAccessiblePivot::SetTextRange(nsIAcces
   NS_ENSURE_ARG(aTextAccessible);
 
   // Check that start offset is smaller than end offset, and that if a value is
   // smaller than 0, both should be -1.
   NS_ENSURE_TRUE(aStartOffset <= aEndOffset &&
                  (aStartOffset >= 0 || (aStartOffset != -1 && aEndOffset != -1)),
                  NS_ERROR_INVALID_ARG);
 
-  nsRefPtr<HyperTextAccessible> newPosition = do_QueryObject(aTextAccessible);
+  nsRefPtr<Accessible> acc(do_QueryObject(aTextAccessible));
+  if (!acc)
+    return NS_ERROR_INVALID_ARG;
+
+  HyperTextAccessible* newPosition = acc->AsHyperText();
   if (!newPosition || !IsRootDescendant(newPosition))
     return NS_ERROR_INVALID_ARG;
 
   // Make sure the given offsets don't exceed the character count.
   PRInt32 charCount = newPosition->CharacterCount();
 
   if (aEndOffset > charCount)
     return NS_ERROR_FAILURE;
 
   PRInt32 oldStart = mStartOffset, oldEnd = mEndOffset;
   mStartOffset = aStartOffset;
   mEndOffset = aEndOffset;
 
   nsRefPtr<Accessible> oldPosition = mPosition.forget();
-  mPosition = newPosition.forget();
+  mPosition = newPosition;
 
-  NotifyPivotChanged(oldPosition, oldStart, oldEnd);
+  NotifyOfPivotChange(oldPosition, oldStart, oldEnd);
 
   return NS_OK;
 }
 
 // Traversal functions
 
 NS_IMETHODIMP
 nsAccessiblePivot::MoveNext(nsIAccessibleTraversalRule* aRule,
@@ -194,19 +198,18 @@ nsAccessiblePivot::MoveNext(nsIAccessibl
   if (anchor && (anchor->IsDefunct() || !IsRootDescendant(anchor)))
     return NS_ERROR_NOT_IN_TREE;
 
   nsresult rv = NS_OK;
   Accessible* accessible =
     SearchForward(anchor, aRule, (aArgc > 1) ? aIncludeStart : false, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  *aResult = accessible;
-  if (*aResult)
-    MovePivotInternal(accessible);
+  if (accessible)
+    *aResult = MovePivotInternal(accessible);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsAccessiblePivot::MovePrevious(nsIAccessibleTraversalRule* aRule,
                                 nsIAccessible* aAnchor,
                                 bool aIncludeStart,
@@ -222,19 +225,18 @@ nsAccessiblePivot::MovePrevious(nsIAcces
   if (anchor && (anchor->IsDefunct() || !IsRootDescendant(anchor)))
     return NS_ERROR_NOT_IN_TREE;
 
   nsresult rv = NS_OK;
   Accessible* accessible =
     SearchBackward(anchor, aRule, (aArgc > 1) ? aIncludeStart : false, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  *aResult = accessible;
-  if (*aResult)
-    MovePivotInternal(accessible);
+  if (accessible)
+    *aResult = MovePivotInternal(accessible);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsAccessiblePivot::MoveFirst(nsIAccessibleTraversalRule* aRule, bool* aResult)
 {
   NS_ENSURE_ARG(aResult);
@@ -242,19 +244,18 @@ nsAccessiblePivot::MoveFirst(nsIAccessib
 
   if (mRoot && mRoot->IsDefunct())
     return NS_ERROR_NOT_IN_TREE;
 
   nsresult rv = NS_OK;
   Accessible* accessible = SearchForward(mRoot, aRule, true, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  *aResult = accessible;
-  if (*aResult)
-    MovePivotInternal(accessible);
+  if (accessible)
+    *aResult = MovePivotInternal(accessible);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsAccessiblePivot::MoveLast(nsIAccessibleTraversalRule* aRule, bool* aResult)
 {
   NS_ENSURE_ARG(aResult);
@@ -271,19 +272,18 @@ nsAccessiblePivot::MoveLast(nsIAccessibl
   // First got to the last accessible in pre-order
   while (lastAccessible->HasChildren())
     lastAccessible = lastAccessible->LastChild();
 
   // Search backwards from last accessible and find the last occurrence in the doc
   accessible = SearchBackward(lastAccessible, aRule, true, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  *aResult = accessible;
-  if (*aResult)
-    MovePivotInternal(accessible);
+  if (accessible)
+    *aResult = MovePivotInternal(accessible);
 
   return NS_OK;
 }
 
 // TODO: Implement
 NS_IMETHODIMP
 nsAccessiblePivot::MoveNextByText(TextBoundaryType aBoundary, bool* aResult)
 {
@@ -338,25 +338,25 @@ nsAccessiblePivot::IsRootDescendant(Acce
   do {
     if (accessible == mRoot)
       return true;
   } while ((accessible = accessible->Parent()));
 
   return false;
 }
 
-void
+bool
 nsAccessiblePivot::MovePivotInternal(Accessible* aPosition)
 {
   nsRefPtr<Accessible> oldPosition = mPosition.forget();
   mPosition = aPosition;
   PRInt32 oldStart = mStartOffset, oldEnd = mEndOffset;
   mStartOffset = mEndOffset = -1;
 
-  NotifyPivotChanged(oldPosition, oldStart, oldEnd);
+  return NotifyOfPivotChange(oldPosition, oldStart, oldEnd);
 }
 
 Accessible*
 nsAccessiblePivot::SearchBackward(Accessible* aAccessible,
                                   nsIAccessibleTraversalRule* aRule,
                                   bool aSearchCurrent,
                                   nsresult* aResult)
 {
@@ -467,25 +467,31 @@ nsAccessiblePivot::SearchForward(Accessi
 
     if (filtered & nsIAccessibleTraversalRule::FILTER_MATCH)
       return accessible;
   }
 
   return nsnull;
 }
 
-void
-nsAccessiblePivot::NotifyPivotChanged(Accessible* aOldPosition,
-                                      PRInt32 aOldStart, PRInt32 aOldEnd)
+bool
+nsAccessiblePivot::NotifyOfPivotChange(Accessible* aOldPosition,
+                                       PRInt32 aOldStart, PRInt32 aOldEnd)
 {
+  if (aOldPosition == mPosition &&
+      aOldStart == mStartOffset && aOldEnd == mEndOffset)
+    return false;
+
   nsTObserverArray<nsCOMPtr<nsIAccessiblePivotObserver> >::ForwardIterator iter(mObservers);
   while (iter.HasMore()) {
     nsIAccessiblePivotObserver* obs = iter.GetNext();
     obs->OnPivotChanged(this, aOldPosition, aOldStart, aOldEnd);
   }
+
+  return true;
 }
 
 nsresult
 RuleCache::ApplyFilter(Accessible* aAccessible, PRUint16* aResult)
 {
   *aResult = nsIAccessibleTraversalRule::FILTER_IGNORE;
 
   if (!mAcceptRoles) {
--- a/accessible/src/base/nsAccessiblePivot.h
+++ b/accessible/src/base/nsAccessiblePivot.h
@@ -39,20 +39,21 @@ public:
   Accessible* Position() { return mPosition; }
 
 private:
   nsAccessiblePivot() MOZ_DELETE;
   nsAccessiblePivot(const nsAccessiblePivot&) MOZ_DELETE;
   void operator = (const nsAccessiblePivot&) MOZ_DELETE;
 
   /*
-   * Notify all observers on a pivot change.
+   * Notify all observers on a pivot change. Return true if it has changed and
+   * observers have been notified.
    */
-  void NotifyPivotChanged(Accessible* aOldAccessible,
-                          PRInt32 aOldStart, PRInt32 aOldEnd);
+  bool NotifyOfPivotChange(Accessible* aOldAccessible,
+                           PRInt32 aOldStart, PRInt32 aOldEnd);
 
   /*
    * Check to see that the given accessible is in the pivot's subtree.
    */
   bool IsRootDescendant(Accessible* aAccessible);
 
 
   /*
@@ -67,19 +68,19 @@ private:
    * Reverse search in preorder for the first accessible to match the rule.
    */
   Accessible* SearchBackward(Accessible* aAccessible,
                              nsIAccessibleTraversalRule* aRule,
                              bool aSearchCurrent,
                              nsresult* aResult);
 
   /*
-   * Update the pivot, and notify observers.
+   * Update the pivot, and notify observers. Return true if it moved.
    */
-  void MovePivotInternal(Accessible* aPosition);
+  bool MovePivotInternal(Accessible* aPosition);
 
   /*
    * The root accessible.
    */
   nsRefPtr<Accessible> mRoot;
 
   /*
    * The current pivot position.
--- a/accessible/src/base/nsTextEquivUtils.cpp
+++ b/accessible/src/base/nsTextEquivUtils.cpp
@@ -487,10 +487,17 @@ PRUint32 nsTextEquivUtils::gRoleToNameRu
   eNoRule,           // ROLE_CALENDAR
   eNoRule,           // ROLE_COMBOBOX_LIST
   eFromSubtree,      // ROLE_COMBOBOX_OPTION
   eNoRule,           // ROLE_IMAGE_MAP
   eFromSubtree,      // ROLE_OPTION
   eFromSubtree,      // ROLE_RICH_OPTION
   eNoRule,           // ROLE_LISTBOX
   eNoRule,           // ROLE_FLAT_EQUATION
-  eFromSubtree       // ROLE_GRID_CELL
+  eFromSubtree,      // ROLE_GRID_CELL
+  eNoRule,           // ROLE_EMBEDDED_OBJECT
+  eFromSubtree,      // ROLE_NOTE
+  eNoRule,           // ROLE_FIGURE
+  eFromSubtree,      // ROLE_CHECK_RICH_OPTION
+  eFromSubtreeIfRec, // ROLE_DEFINITION_LIST
+  eFromSubtree,      // ROLE_TERM
+  eFromSubtree       // ROLE_DEFINITION
 };
--- a/accessible/src/generic/ARIAGridAccessible.cpp
+++ b/accessible/src/generic/ARIAGridAccessible.cpp
@@ -160,124 +160,68 @@ ARIAGridAccessible::GetRowAndColumnIndic
 
   NS_ENSURE_ARG(aCellIndex < rowCount * colsCount);
 
   *aColumnIndex = aCellIndex % colsCount;
   *aRowIndex = aCellIndex / colsCount;
   return NS_OK;
 }
 
-NS_IMETHODIMP
-ARIAGridAccessible::GetColumnDescription(PRInt32 aColumn,
-                                         nsAString& aDescription)
-{
-  aDescription.Truncate();
-
-  if (IsDefunct())
-    return NS_ERROR_FAILURE;
-
-  NS_ENSURE_ARG(IsValidColumn(aColumn));
-
-  // XXX: not implemented
-  return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-NS_IMETHODIMP
-ARIAGridAccessible::GetRowDescription(PRInt32 aRow, nsAString& aDescription)
+bool
+ARIAGridAccessible::IsColSelected(PRUint32 aColIdx)
 {
-  aDescription.Truncate();
-
-  if (IsDefunct())
-    return NS_ERROR_FAILURE;
-
-  NS_ENSURE_ARG(IsValidRow(aRow));
-
-  // XXX: not implemented
-  return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-NS_IMETHODIMP
-ARIAGridAccessible::IsColumnSelected(PRInt32 aColumn, bool* aIsSelected)
-{
-  NS_ENSURE_ARG_POINTER(aIsSelected);
-  *aIsSelected = false;
-
-  if (IsDefunct())
-    return NS_ERROR_FAILURE;
-
-  NS_ENSURE_ARG(IsValidColumn(aColumn));
-
   AccIterator rowIter(this, filters::GetRow);
   Accessible* row = rowIter.Next();
   if (!row)
-    return NS_OK;
+    return false;
 
   do {
     if (!nsAccUtils::IsARIASelected(row)) {
-      Accessible* cell = GetCellInRowAt(row, aColumn);
-      if (!cell) // Do not fail due to wrong markup
-        return NS_OK;
-      
-      if (!nsAccUtils::IsARIASelected(cell))
-        return NS_OK;
+      Accessible* cell = GetCellInRowAt(row, aColIdx);
+      if (!cell || !nsAccUtils::IsARIASelected(cell))
+        return false;
     }
   } while ((row = rowIter.Next()));
 
-  *aIsSelected = true;
-  return NS_OK;
+  return true;
 }
 
-NS_IMETHODIMP
-ARIAGridAccessible::IsRowSelected(PRInt32 aRow, bool* aIsSelected)
+bool
+ARIAGridAccessible::IsRowSelected(PRUint32 aRowIdx)
 {
-  NS_ENSURE_ARG_POINTER(aIsSelected);
-  *aIsSelected = false;
-
-  if (IsDefunct())
-    return NS_ERROR_FAILURE;
-
-  Accessible* row = GetRowAt(aRow);
-  NS_ENSURE_ARG(row);
+  Accessible* row = GetRowAt(aRowIdx);
+  if(!row)
+    return false;
 
   if (!nsAccUtils::IsARIASelected(row)) {
     AccIterator cellIter(row, filters::GetCell);
     Accessible* cell = nsnull;
     while ((cell = cellIter.Next())) {
       if (!nsAccUtils::IsARIASelected(cell))
-        return NS_OK;
+        return false;
     }
   }
 
-  *aIsSelected = true;
-  return NS_OK;
+  return true;
 }
 
-NS_IMETHODIMP
-ARIAGridAccessible::IsCellSelected(PRInt32 aRow, PRInt32 aColumn,
-                                   bool* aIsSelected)
+bool
+ARIAGridAccessible::IsCellSelected(PRUint32 aRowIdx, PRUint32 aColIdx)
 {
-  NS_ENSURE_ARG_POINTER(aIsSelected);
-  *aIsSelected = false;
-
-  if (IsDefunct())
-    return NS_ERROR_FAILURE;
-
-  Accessible* row = GetRowAt(aRow);
-  NS_ENSURE_ARG(row);
+  Accessible* row = GetRowAt(aRowIdx);
+  if(!row)
+    return false;
 
   if (!nsAccUtils::IsARIASelected(row)) {
-    Accessible* cell = GetCellInRowAt(row, aColumn);
-    NS_ENSURE_ARG(cell);
-
-    if (!nsAccUtils::IsARIASelected(cell))
-      return NS_OK;
+    Accessible* cell = GetCellInRowAt(row, aColIdx);
+    if (!cell || !nsAccUtils::IsARIASelected(cell))
+      return false;
   }
 
-  *aIsSelected = true;
-  return NS_OK;
+  return true;
 }
 
 NS_IMETHODIMP
 ARIAGridAccessible::GetSelectedCellCount(PRUint32* aCount)
 {
   NS_ENSURE_ARG_POINTER(aCount);
   *aCount = 0;
 
--- a/accessible/src/generic/ARIAGridAccessible.h
+++ b/accessible/src/generic/ARIAGridAccessible.h
@@ -28,25 +28,28 @@ public:
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIAccessibleTable
   NS_DECL_OR_FORWARD_NSIACCESSIBLETABLE_WITH_XPCACCESSIBLETABLE
 
   // Accessible
-  virtual mozilla::a11y::TableAccessible* AsTable() { return this; }
+  virtual TableAccessible* AsTable() { return this; }
 
   // nsAccessNode
   virtual void Shutdown();
 
   // TableAccessible
   virtual PRUint32 ColCount();
   virtual PRUint32 RowCount();
   virtual Accessible* CellAt(PRUint32 aRowIndex, PRUint32 aColumnIndex);
+  virtual bool IsColSelected(PRUint32 aColIdx);
+  virtual bool IsRowSelected(PRUint32 aRowIdx);
+  virtual bool IsCellSelected(PRUint32 aRowIdx, PRUint32 aColIdx);
   virtual void SelectCol(PRUint32 aColIdx);
   virtual void SelectRow(PRUint32 aRowIdx);
   virtual void UnselectCol(PRUint32 aColIdx);
   virtual void UnselectRow(PRUint32 aRowIdx);
 
 protected:
   /**
    * Return true if the given row index is valid.
--- a/accessible/src/generic/Accessible.cpp
+++ b/accessible/src/generic/Accessible.cpp
@@ -106,17 +106,17 @@ NS_IMPL_RELEASE_INHERITED(Accessible, ns
 nsresult
 Accessible::QueryInterface(REFNSIID aIID, void** aInstancePtr)
 {
   // Custom-built QueryInterface() knows when we support nsIAccessibleSelectable
   // based on role attribute and aria-multiselectable
   *aInstancePtr = nsnull;
 
   if (aIID.Equals(NS_GET_IID(nsXPCOMCycleCollectionParticipant))) {
-    *aInstancePtr = &NS_CYCLE_COLLECTION_NAME(Accessible);
+    *aInstancePtr = NS_CYCLE_COLLECTION_PARTICIPANT(Accessible);
     return NS_OK;
   }
 
   if (aIID.Equals(NS_GET_IID(nsIAccessible))) {
     *aInstancePtr = static_cast<nsIAccessible*>(this);
     NS_ADDREF_THIS();
     return NS_OK;
   }
--- a/accessible/src/generic/HyperTextAccessible.cpp
+++ b/accessible/src/generic/HyperTextAccessible.cpp
@@ -50,22 +50,16 @@ HyperTextAccessible::
 NS_IMPL_ADDREF_INHERITED(HyperTextAccessible, AccessibleWrap)
 NS_IMPL_RELEASE_INHERITED(HyperTextAccessible, AccessibleWrap)
 
 nsresult
 HyperTextAccessible::QueryInterface(REFNSIID aIID, void** aInstancePtr)
 {
   *aInstancePtr = nsnull;
 
-  if (aIID.Equals(NS_GET_IID(HyperTextAccessible))) {
-    *aInstancePtr = static_cast<HyperTextAccessible*>(this);
-    NS_ADDREF_THIS();
-    return NS_OK;
-  }
-
   // ARIA roles that these interfaces are not appropriate for.
   if (!IsTextRole())
     return Accessible::QueryInterface(aIID, aInstancePtr);
 
   if (aIID.Equals(NS_GET_IID(nsIAccessibleText))) {
     *aInstancePtr = static_cast<nsIAccessibleText*>(this);
     NS_ADDREF_THIS();
     return NS_OK;
--- a/accessible/src/generic/HyperTextAccessible.h
+++ b/accessible/src/generic/HyperTextAccessible.h
@@ -19,41 +19,32 @@
 enum EGetTextType { eGetBefore=-1, eGetAt=0, eGetAfter=1 };
 
 // This character marks where in the text returned via nsIAccessibleText(),
 // that embedded object characters exist
 const PRUnichar kEmbeddedObjectChar = 0xfffc;
 const PRUnichar kImaginaryEmbeddedObjectChar = ' ';
 const PRUnichar kForcedNewLineChar = '\n';
 
-#define NS_HYPERTEXTACCESSIBLE_IMPL_CID                 \
-{  /* 245f3bc9-224f-4839-a92e-95239705f30b */           \
-  0x245f3bc9,                                           \
-  0x224f,                                               \
-  0x4839,                                               \
-  { 0xa9, 0x2e, 0x95, 0x23, 0x97, 0x05, 0xf3, 0x0b }    \
-}
-
 /**
   * Special Accessible that knows how contain both text and embedded objects
   */
 class HyperTextAccessible : public AccessibleWrap,
                             public nsIAccessibleText,
                             public nsIAccessibleHyperText,
                             public nsIAccessibleEditableText
 {
 public:
   HyperTextAccessible(nsIContent* aContent, DocAccessible* aDoc);
   virtual ~HyperTextAccessible() { }
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIACCESSIBLETEXT
   NS_DECL_NSIACCESSIBLEHYPERTEXT
   NS_DECL_NSIACCESSIBLEEDITABLETEXT
-  NS_DECLARE_STATIC_IID_ACCESSOR(NS_HYPERTEXTACCESSIBLE_IMPL_CID)
 
   // Accessible
   virtual PRInt32 GetLevelInternal();
   virtual nsresult GetAttributesInternal(nsIPersistentProperties *aAttributes);
   virtual nsresult GetNameInternal(nsAString& aName);
   virtual mozilla::a11y::role NativeRole();
   virtual PRUint64 NativeState();
 
@@ -405,19 +396,16 @@ protected:
 
 private:
   /**
    * End text offsets array.
    */
   nsTArray<PRUint32> mOffsets;
 };
 
-NS_DEFINE_STATIC_IID_ACCESSOR(HyperTextAccessible,
-                              NS_HYPERTEXTACCESSIBLE_IMPL_CID)
-
 
 ////////////////////////////////////////////////////////////////////////////////
 // Accessible downcasting method
 
 inline HyperTextAccessible*
 Accessible::AsHyperText()
 {
   return mFlags & eHyperTextAccessible ?
--- a/accessible/src/html/HTMLFormControlAccessible.cpp
+++ b/accessible/src/html/HTMLFormControlAccessible.cpp
@@ -319,19 +319,18 @@ HTMLButtonAccessible::IsWidget() const
 ////////////////////////////////////////////////////////////////////////////////
 
 HTMLTextFieldAccessible::
   HTMLTextFieldAccessible(nsIContent* aContent, DocAccessible* aDoc) :
   HyperTextAccessibleWrap(aContent, aDoc)
 {
 }
 
-NS_IMPL_ISUPPORTS_INHERITED3(HTMLTextFieldAccessible,
-                             Accessible,
-                             HyperTextAccessible,
+NS_IMPL_ISUPPORTS_INHERITED2(HTMLTextFieldAccessible,
+                             Accessible,                             
                              nsIAccessibleText,
                              nsIAccessibleEditableText)
 
 role
 HTMLTextFieldAccessible::NativeRole()
 {
   if (mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::type,
                             nsGkAtoms::password, eIgnoreCase)) {
--- a/accessible/src/html/HTMLTableAccessible.cpp
+++ b/accessible/src/html/HTMLTableAccessible.cpp
@@ -967,130 +967,85 @@ HTMLTableAccessible::RowExtentAt(PRUint3
   nsresult rv = tableLayout->
     GetCellDataAt(aRowIdx, aColIdx, *getter_AddRefs(domElement),
                   startRowIndex, startColIndex, rowSpan, colSpan,
                   rowExtent, actualColSpan, isSelected);
 
   return rowExtent;
 }
 
-NS_IMETHODIMP
-HTMLTableAccessible::GetColumnDescription(PRInt32 aColumn, nsAString& _retval)
-{
-  return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-NS_IMETHODIMP
-HTMLTableAccessible::GetRowDescription(PRInt32 aRow, nsAString& _retval)
+bool
+HTMLTableAccessible::IsColSelected(PRUint32 aColIdx)
 {
-  return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-NS_IMETHODIMP
-HTMLTableAccessible::IsColumnSelected(PRInt32 aColumn, bool* aIsSelected)
-{
-  NS_ENSURE_ARG_POINTER(aIsSelected);
-  *aIsSelected = false;
+  bool isSelected = false;
 
-  PRInt32 colCount = 0;
-  nsresult rv = GetColumnCount(&colCount);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  if (aColumn < 0 || aColumn >= colCount)
-    return NS_ERROR_INVALID_ARG;
-
-  PRInt32 rowCount = 0;
-  rv = GetRowCount(&rowCount);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  for (PRInt32 rowIdx = 0; rowIdx < rowCount; rowIdx++) {
-    bool isSelected = false;
-    rv = IsCellSelected(rowIdx, aColumn, &isSelected);
-    if (NS_SUCCEEDED(rv)) {
-      *aIsSelected = isSelected;
-      if (!isSelected)
-        break;
-    }
+  PRUint32 rowCount = RowCount();
+  for (PRUint32 rowIdx = 0; rowIdx < rowCount; rowIdx++) {
+    isSelected = IsCellSelected(rowIdx, aColIdx);
+    if (!isSelected)
+      return false;
   }
 
-  return NS_OK;
+  return isSelected;
 }
 
-NS_IMETHODIMP
-HTMLTableAccessible::IsRowSelected(PRInt32 aRow, bool* aIsSelected)
+bool
+HTMLTableAccessible::IsRowSelected(PRUint32 aRowIdx)
 {
-  NS_ENSURE_ARG_POINTER(aIsSelected);
-  *aIsSelected = false;
-
-  PRInt32 rowCount = 0;
-  nsresult rv = GetRowCount(&rowCount);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  if (aRow < 0 || aRow >= rowCount)
-    return NS_ERROR_INVALID_ARG;
+  bool isSelected = false;
 
-  PRInt32 colCount = 0;
-  rv = GetColumnCount(&colCount);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  for (PRInt32 colIdx = 0; colIdx < colCount; colIdx++) {
-    bool isSelected = false;
-    rv = IsCellSelected(aRow, colIdx, &isSelected);
-    if (NS_SUCCEEDED(rv)) {
-      *aIsSelected = isSelected;
-      if (!isSelected)
-        break;
-    }
+  PRUint32 colCount = ColCount();
+  for (PRUint32 colIdx = 0; colIdx < colCount; colIdx++) {
+    isSelected = IsCellSelected(aRowIdx, colIdx);
+    if (!isSelected)
+      return false;
   }
 
-  return NS_OK;
+  return isSelected;
 }
 
-NS_IMETHODIMP
-HTMLTableAccessible::IsCellSelected(PRInt32 aRow, PRInt32 aColumn,
-                                    bool* aIsSelected)
+bool
+HTMLTableAccessible::IsCellSelected(PRUint32 aRowIdx, PRUint32 aColIdx)
 {
-  NS_ENSURE_ARG_POINTER(aIsSelected);
-  *aIsSelected = false;
-
   nsITableLayout *tableLayout = GetTableLayout();
-  NS_ENSURE_STATE(tableLayout);
+  if (!tableLayout)
+    return false;
 
   nsCOMPtr<nsIDOMElement> domElement;
   PRInt32 startRowIndex = 0, startColIndex = 0,
           rowSpan, colSpan, actualRowSpan, actualColSpan;
+  bool isSelected = false;
 
-  nsresult rv = tableLayout->
-    GetCellDataAt(aRow, aColumn, *getter_AddRefs(domElement),
-                  startRowIndex, startColIndex, rowSpan, colSpan,
-                  actualRowSpan, actualColSpan, *aIsSelected);
+  tableLayout->GetCellDataAt(aRowIdx, aColIdx, *getter_AddRefs(domElement),
+                             startRowIndex, startColIndex, rowSpan, colSpan,
+                             actualRowSpan, actualColSpan, isSelected);
 
-  if (rv == NS_TABLELAYOUT_CELL_NOT_FOUND)
-    return NS_ERROR_INVALID_ARG;
-  return rv;
+  return isSelected;
 }
 
 void
 HTMLTableAccessible::SelectRow(PRUint32 aRowIdx)
 {
-  nsresult rv = RemoveRowsOrColumnsFromSelection(aRowIdx,
-                                                 nsISelectionPrivate::TABLESELECTION_ROW,
-                                                 true);
+  nsresult rv =
+    RemoveRowsOrColumnsFromSelection(aRowIdx,
+                                     nsISelectionPrivate::TABLESELECTION_ROW,
+                                     true);
   NS_ASSERTION(NS_SUCCEEDED(rv),
                "RemoveRowsOrColumnsFromSelection() Shouldn't fail!");
 
   AddRowOrColumnToSelection(aRowIdx, nsISelectionPrivate::TABLESELECTION_ROW);
 }
 
 void
 HTMLTableAccessible::SelectCol(PRUint32 aColIdx)
 {
-  nsresult rv = RemoveRowsOrColumnsFromSelection(aColIdx,
-                                                 nsISelectionPrivate::TABLESELECTION_COLUMN,
-                                                 true);
+  nsresult rv =
+    RemoveRowsOrColumnsFromSelection(aColIdx,
+                                     nsISelectionPrivate::TABLESELECTION_COLUMN,
+                                     true);
   NS_ASSERTION(NS_SUCCEEDED(rv),
                "RemoveRowsOrColumnsFromSelection() Shouldn't fail!");
 
   AddRowOrColumnToSelection(aColIdx, nsISelectionPrivate::TABLESELECTION_COLUMN);
 }
 
 void
 HTMLTableAccessible::UnselectRow(PRUint32 aRowIdx)
@@ -1441,17 +1396,18 @@ HTMLTableAccessible::IsProbablyLayoutTab
 
   /**
    * Rules for non-bordered tables with 2-4 columns and 2+ rows from here on forward
    */
 
   // Check for styled background color across rows (alternating background
   // color is a common feature for data tables).
   PRUint32 childCount = ChildCount();
-  nscolor rowColor, prevRowColor;
+  nscolor rowColor = 0;
+  nscolor prevRowColor;
   for (PRUint32 childIdx = 0; childIdx < childCount; childIdx++) {
     Accessible* child = GetChildAt(childIdx);
     if (child->Role() == roles::ROW) {
       prevRowColor = rowColor;
       nsIFrame* rowFrame = child->GetFrame();
       rowColor = rowFrame->GetStyleBackground()->mBackgroundColor;
 
       if (childIdx > 0 && prevRowColor != rowColor)
--- a/accessible/src/html/HTMLTableAccessible.h
+++ b/accessible/src/html/HTMLTableAccessible.h
@@ -101,27 +101,30 @@ public:
   virtual Accessible* Caption();
   virtual void Summary(nsString& aSummary);
   virtual PRUint32 ColCount();
   virtual PRUint32 RowCount();
   virtual Accessible* CellAt(PRUint32 aRowIndex, PRUint32 aColumnIndex);
   virtual PRInt32 CellIndexAt(PRUint32 aRowIdx, PRUint32 aColIdx);
   virtual PRUint32 ColExtentAt(PRUint32 aRowIdx, PRUint32 aColIdx);
   virtual PRUint32 RowExtentAt(PRUint32 aRowIdx, PRUint32 aColIdx);
+  virtual bool IsColSelected(PRUint32 aColIdx);
+  virtual bool IsRowSelected(PRUint32 aRowIdx);
+  virtual bool IsCellSelected(PRUint32 aRowIdx, PRUint32 aColIdx);
   virtual void SelectCol(PRUint32 aColIdx);
   virtual void SelectRow(PRUint32 aRowIdx);
   virtual void UnselectCol(PRUint32 aColIdx);
   virtual void UnselectRow(PRUint32 aRowIdx);
   virtual bool IsProbablyLayoutTable();
 
   // nsAccessNode
   virtual void Shutdown();
 
   // Accessible
-  virtual mozilla::a11y::TableAccessible* AsTable() { return this; }
+  virtual TableAccessible* AsTable() { return this; }
   virtual void Description(nsString& aDescription);
   virtual nsresult GetNameInternal(nsAString& aName);
   virtual a11y::role NativeRole();
   virtual PRUint64 NativeState();
   virtual nsresult GetAttributesInternal(nsIPersistentProperties *aAttributes);
   virtual Relation RelationByType(PRUint32 aRelationType);
 
   // HTMLTableAccessible
--- a/accessible/src/jsat/Presenters.jsm
+++ b/accessible/src/jsat/Presenters.jsm
@@ -299,17 +299,19 @@ AndroidPresenter.prototype = {
 
   textChanged: function AndroidPresenter_textChanged(aIsInserted, aStart,
                                                      aLength, aText,
                                                      aModifiedText) {
     let androidEvent = {
       type: 'Accessibility:Event',
       eventType: this.ANDROID_VIEW_TEXT_CHANGED,
       text: [aText],
-      fromIndex: aStart
+      fromIndex: aStart,
+      removedCount: 0,
+      addedCount: 0
     };
 
     if (aIsInserted) {
       androidEvent.addedCount = aLength;
       androidEvent.beforeText =
         aText.substring(0, aStart) + aText.substring(aStart + aLength);
     } else {
       androidEvent.removedCount = aLength;
--- a/accessible/src/mac/ApplicationAccessibleWrap.mm
+++ b/accessible/src/mac/ApplicationAccessibleWrap.mm
@@ -8,22 +8,24 @@
 
 #include "ApplicationAccessibleWrap.h"
 
 #include "nsAppShell.h"
 
 namespace mozilla {
 namespace a11y {
 
+// Mac a11y whitelisting
 static bool sA11yShouldBeEnabled = false;
 
 bool
 ShouldA11yBeEnabled()
 {
-  return sA11yShouldBeEnabled;
+  EPlatformDisabledState disabledState = PlatformDisabledState();
+  return (disabledState == ePlatformIsForceEnabled) || ((disabledState == ePlatformIsEnabled) && sA11yShouldBeEnabled);
 }
 
 }
 }
 
 @interface GeckoNSApplication(a11y)
 -(void)accessibilitySetValue:(id)value forAttribute:(NSString*)attribute;
 @end
--- a/accessible/src/mac/mozTextAccessible.mm
+++ b/accessible/src/mac/mozTextAccessible.mm
@@ -52,17 +52,17 @@ ToNSString(id aValue)
 
 @implementation mozTextAccessible
 
 - (id)initWithAccessible:(AccessibleWrap*)accessible
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
 
   if ((self = [super initWithAccessible:accessible])) {
-    CallQueryInterface(accessible, &mGeckoTextAccessible);
+    mGeckoTextAccessible = accessible->AsHyperText();
     CallQueryInterface(accessible, &mGeckoEditableTextAccessible);
   }
   return self;
 
   NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
 }
 
 - (BOOL)accessibilityIsIgnored
@@ -307,17 +307,17 @@ ToNSString(id aValue)
 
   return nil;
 }
 
 - (void)expire
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
 
-  NS_IF_RELEASE(mGeckoTextAccessible);
+  mGeckoTextAccessible = nsnull;
   NS_IF_RELEASE(mGeckoEditableTextAccessible);
   [super expire];
 
   NS_OBJC_END_TRY_ABORT_BLOCK;
 }
 
 #pragma mark -
 
--- a/accessible/src/msaa/HyperTextAccessibleWrap.cpp
+++ b/accessible/src/msaa/HyperTextAccessibleWrap.cpp
@@ -10,17 +10,17 @@
 #include "nsEventShell.h"
 
 NS_IMPL_ISUPPORTS_INHERITED0(HyperTextAccessibleWrap,
                              HyperTextAccessible)
 
 IMPL_IUNKNOWN_INHERITED2(HyperTextAccessibleWrap,
                          AccessibleWrap,
                          ia2AccessibleHypertext,
-                         CAccessibleEditableText);
+                         ia2AccessibleEditableText);
 
 nsresult
 HyperTextAccessibleWrap::HandleAccEvent(AccEvent* aEvent)
 {
   PRUint32 eventType = aEvent->GetEventType();
 
   if (eventType == nsIAccessibleEvent::EVENT_TEXT_REMOVED ||
       eventType == nsIAccessibleEvent::EVENT_TEXT_INSERTED) {
--- a/accessible/src/msaa/HyperTextAccessibleWrap.h
+++ b/accessible/src/msaa/HyperTextAccessibleWrap.h
@@ -4,23 +4,22 @@
 /* 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 mozilla_a11y_HyperTextAccessibleWrap_h__
 #define mozilla_a11y_HyperTextAccessibleWrap_h__
 
 #include "HyperTextAccessible.h"
-#include "CAccessibleText.h"
-#include "CAccessibleEditableText.h"
+#include "ia2AccessibleEditableText.h"
 #include "ia2AccessibleHyperText.h"
 
 class HyperTextAccessibleWrap : public HyperTextAccessible,
                                 public ia2AccessibleHypertext,
-                                public CAccessibleEditableText
+                                public ia2AccessibleEditableText
 {
 public:
   HyperTextAccessibleWrap(nsIContent* aContent, DocAccessible* aDoc) :
     HyperTextAccessible(aContent, aDoc) {}
 
   // IUnknown
   DECL_IUNKNOWN_INHERITED
 
--- a/accessible/src/msaa/Makefile.in
+++ b/accessible/src/msaa/Makefile.in
@@ -21,29 +21,29 @@ CPPSRCS = \
   ARIAGridAccessibleWrap.cpp \
   DocAccessibleWrap.cpp \
   HTMLTableAccessibleWrap.cpp \
   HyperTextAccessibleWrap.cpp \
   ImageAccessibleWrap.cpp \
   nsAccessNodeWrap.cpp \
   nsHTMLWin32ObjectAccessible.cpp \
   nsWinUtils.cpp \
-  CAccessibleText.cpp \
-  CAccessibleEditableText.cpp \
   CAccessibleHyperlink.cpp \
   CAccessibleTable.cpp \
   CAccessibleTableCell.cpp \
   CAccessibleValue.cpp \
   Compatibility.cpp \
   EnumVariant.cpp \
   ia2AccessibleAction.cpp \
   ia2AccessibleComponent.cpp \
+  ia2AccessibleEditableText.cpp \
   ia2AccessibleImage.cpp \
   ia2AccessibleHypertext.cpp \
   ia2AccessibleRelation.cpp \
+  ia2AccessibleText.cpp \
   RootAccessibleWrap.cpp \
   TextLeafAccessibleWrap.cpp \
   $(NULL)
 
 ifdef MOZ_XUL
 CPPSRCS += \
   XULListboxAccessibleWrap.cpp \
   XULMenuAccessibleWrap.cpp \
rename from accessible/src/msaa/CAccessibleEditableText.cpp
rename to accessible/src/msaa/ia2AccessibleEditableText.cpp
--- a/accessible/src/msaa/CAccessibleEditableText.cpp
+++ b/accessible/src/msaa/ia2AccessibleEditableText.cpp
@@ -1,27 +1,27 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim:expandtab:shiftwidth=2:tabstop=2:
  */
 /* 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 "CAccessibleEditableText.h"
+#include "ia2AccessibleEditableText.h"
 
 #include "AccessibleEditableText_i.c"
-#include "HyperTextAccessible.h"
+#include "HyperTextAccessibleWrap.h"
 
 #include "nsCOMPtr.h"
 #include "nsString.h"
 
 // IUnknown
 
 STDMETHODIMP
-CAccessibleEditableText::QueryInterface(REFIID iid, void** ppv)
+ia2AccessibleEditableText::QueryInterface(REFIID iid, void** ppv)
 {
   *ppv = NULL;
 
   if (IID_IAccessibleEditableText == iid) {
     nsCOMPtr<nsIAccessibleEditableText> editTextAcc(do_QueryObject(this));
     if (!editTextAcc)
       return E_NOINTERFACE;
     *ppv = static_cast<IAccessibleEditableText*>(this);
@@ -30,99 +30,99 @@ CAccessibleEditableText::QueryInterface(
   }
 
   return E_NOINTERFACE;
 }
 
 // IAccessibleEditableText
 
 STDMETHODIMP
-CAccessibleEditableText::copyText(long aStartOffset, long aEndOffset)
+ia2AccessibleEditableText::copyText(long aStartOffset, long aEndOffset)
 {
 __try {
-  nsRefPtr<HyperTextAccessible> textAcc(do_QueryObject(this));
+  HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
   if (textAcc->IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
   nsresult rv = textAcc->CopyText(aStartOffset, aEndOffset);
   return GetHRESULT(rv);
 
 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return E_FAIL;
 }
 
 STDMETHODIMP
-CAccessibleEditableText::deleteText(long aStartOffset, long aEndOffset)
+ia2AccessibleEditableText::deleteText(long aStartOffset, long aEndOffset)
 {
 __try {
-  nsRefPtr<HyperTextAccessible> textAcc(do_QueryObject(this));
+  HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
   if (textAcc->IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
   nsresult rv = textAcc->DeleteText(aStartOffset, aEndOffset);
   return GetHRESULT(rv);
 
 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return E_FAIL;
 }
 
 STDMETHODIMP
-CAccessibleEditableText::insertText(long aOffset, BSTR *aText)
+ia2AccessibleEditableText::insertText(long aOffset, BSTR *aText)
 {
 __try {
-  nsRefPtr<HyperTextAccessible> textAcc(do_QueryObject(this));
+  HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
   if (textAcc->IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
   PRUint32 length = ::SysStringLen(*aText);
   nsAutoString text(*aText, length);
 
   nsresult rv = textAcc->InsertText(text, aOffset);
   return GetHRESULT(rv);
 
 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return E_FAIL;
 }
 
 STDMETHODIMP
-CAccessibleEditableText::cutText(long aStartOffset, long aEndOffset)
+ia2AccessibleEditableText::cutText(long aStartOffset, long aEndOffset)
 {
 __try {
-  nsRefPtr<HyperTextAccessible> textAcc(do_QueryObject(this));
+  HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
   if (textAcc->IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
   nsresult rv = textAcc->CutText(aStartOffset, aEndOffset);
   return GetHRESULT(rv);
 
 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return E_FAIL;
 }
 
 STDMETHODIMP
-CAccessibleEditableText::pasteText(long aOffset)
+ia2AccessibleEditableText::pasteText(long aOffset)
 {
 __try {
-  nsRefPtr<HyperTextAccessible> textAcc(do_QueryObject(this));
+  HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
   if (textAcc->IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
   nsresult rv = textAcc->PasteText(aOffset);
   return GetHRESULT(rv);
 
 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return E_FAIL;
 }
 
 STDMETHODIMP
-CAccessibleEditableText::replaceText(long aStartOffset, long aEndOffset,
-                                     BSTR *aText)
+ia2AccessibleEditableText::replaceText(long aStartOffset, long aEndOffset,
+                                       BSTR *aText)
 {
 __try {
-  nsRefPtr<HyperTextAccessible> textAcc(do_QueryObject(this));
+  HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
   if (textAcc->IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
   nsresult rv = textAcc->DeleteText(aStartOffset, aEndOffset);
   if (NS_FAILED(rv))
     return GetHRESULT(rv);
 
   PRUint32 length = ::SysStringLen(*aText);
@@ -131,16 +131,16 @@ CAccessibleEditableText::replaceText(lon
   rv = textAcc->InsertText(text, aStartOffset);
   return GetHRESULT(rv);
 
 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return E_FAIL;
 }
 
 STDMETHODIMP
-CAccessibleEditableText::setAttributes(long aStartOffset, long aEndOffset,
-                                       BSTR *aAttributes)
+ia2AccessibleEditableText::setAttributes(long aStartOffset, long aEndOffset,
+                                         BSTR *aAttributes)
 {
 __try {
 
 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return E_NOTIMPL;
 }
rename from accessible/src/msaa/CAccessibleEditableText.h
rename to accessible/src/msaa/ia2AccessibleEditableText.h
--- a/accessible/src/msaa/CAccessibleEditableText.h
+++ b/accessible/src/msaa/ia2AccessibleEditableText.h
@@ -8,17 +8,17 @@
 #ifndef _ACCESSIBLE_EDITABLETEXT_H
 #define _ACCESSIBLE_EDITABLETEXT_H
 
 #include "nsISupports.h"
 #include "nsIAccessibleEditableText.h"
 
 #include "AccessibleEditableText.h"
 
-class CAccessibleEditableText: public IAccessibleEditableText
+class ia2AccessibleEditableText: public IAccessibleEditableText
 {
 public:
 
   // IUnknown
   STDMETHODIMP QueryInterface(REFIID, void**);
 
   // IAccessibleEditableText
   virtual HRESULT STDMETHODCALLTYPE copyText(
--- a/accessible/src/msaa/ia2AccessibleHypertext.cpp
+++ b/accessible/src/msaa/ia2AccessibleHypertext.cpp
@@ -22,17 +22,17 @@ ia2AccessibleHypertext::QueryInterface(R
     if (hyperAcc->IsTextRole()) {
       *ppv = static_cast<IAccessibleHypertext*>(this);
       (reinterpret_cast<IUnknown*>(*ppv))->AddRef();
       return S_OK;
     }
     return E_NOINTERFACE;
   }
 
-  return CAccessibleText::QueryInterface(iid, ppv);
+  return ia2AccessibleText::QueryInterface(iid, ppv);
 }
 
 // IAccessibleHypertext
 
 STDMETHODIMP
 ia2AccessibleHypertext::get_nHyperlinks(long* aHyperlinkCount)
 {
 __try {
--- a/accessible/src/msaa/ia2AccessibleHypertext.h
+++ b/accessible/src/msaa/ia2AccessibleHypertext.h
@@ -5,29 +5,29 @@
  * 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 _ACCESSIBLE_HYPERTEXT_H
 #define _ACCESSIBLE_HYPERTEXT_H
 
 #include "nsISupports.h"
 
-#include "CAccessibleText.h"
+#include "ia2AccessibleText.h"
 #include "AccessibleHypertext.h"
 
-class ia2AccessibleHypertext : public CAccessibleText,
+class ia2AccessibleHypertext : public ia2AccessibleText,
                                public IAccessibleHypertext
 {
 public:
 
   // IUnknown
   STDMETHODIMP QueryInterface(REFIID, void**);
 
   // IAccessibleText
-  FORWARD_IACCESSIBLETEXT(CAccessibleText)
+  FORWARD_IACCESSIBLETEXT(ia2AccessibleText)
 
   // IAccessibleHypertext
   virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_nHyperlinks(
       /* [retval][out] */ long* hyperlinkCount);
 
   virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_hyperlink(
       /* [in] */ long index,
       /* [retval][out] */ IAccessibleHyperlink** hyperlink);
rename from accessible/src/msaa/CAccessibleText.cpp
rename to accessible/src/msaa/ia2AccessibleText.cpp
--- a/accessible/src/msaa/CAccessibleText.cpp
+++ b/accessible/src/msaa/ia2AccessibleText.cpp
@@ -1,28 +1,28 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim:expandtab:shiftwidth=2:tabstop=2:
  */
 /* 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 "CAccessibleText.h"
+#include "ia2AccessibleText.h"
 
 #include "Accessible2.h"
 #include "AccessibleText_i.c"
 
-#include "HyperTextAccessible.h"
+#include "HyperTextAccessibleWrap.h"
 
 #include "nsIPersistentProperties2.h"
 
 // IUnknown
 
 STDMETHODIMP
-CAccessibleText::QueryInterface(REFIID iid, void** ppv)
+ia2AccessibleText::QueryInterface(REFIID iid, void** ppv)
 {
   *ppv = NULL;
 
   if (IID_IAccessibleText == iid) {
     nsCOMPtr<nsIAccessibleText> textAcc(do_QueryObject(this));
     if (!textAcc) {
       return E_NOINTERFACE;
     }
@@ -32,43 +32,43 @@ CAccessibleText::QueryInterface(REFIID i
   }
 
   return E_NOINTERFACE;
 }
 
 // IAccessibleText
 
 STDMETHODIMP
-CAccessibleText::addSelection(long aStartOffset, long aEndOffset)
+ia2AccessibleText::addSelection(long aStartOffset, long aEndOffset)
 {
 __try {
-  nsRefPtr<HyperTextAccessible> textAcc(do_QueryObject(this));
+  HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
   if (textAcc->IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
   nsresult rv = textAcc->AddSelection(aStartOffset, aEndOffset);
   return GetHRESULT(rv);
 
 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return E_FAIL;
 }
 
 STDMETHODIMP
-CAccessibleText::get_attributes(long aOffset, long *aStartOffset,
-                                long *aEndOffset, BSTR *aTextAttributes)
+ia2AccessibleText::get_attributes(long aOffset, long *aStartOffset,
+                                  long *aEndOffset, BSTR *aTextAttributes)
 {
 __try {
   if (!aStartOffset || !aEndOffset || !aTextAttributes)
     return E_INVALIDARG;
 
   *aStartOffset = 0;
   *aEndOffset = 0;
   *aTextAttributes = NULL;
 
-  nsRefPtr<HyperTextAccessible> textAcc(do_QueryObject(this));
+  HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
   if (textAcc->IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
   PRInt32 startOffset = 0, endOffset = 0;
   nsCOMPtr<nsIPersistentProperties> attributes;
   nsresult rv = textAcc->GetTextAttributes(true, aOffset,
                                            &startOffset, &endOffset,
                                            getter_AddRefs(attributes));
@@ -85,50 +85,50 @@ CAccessibleText::get_attributes(long aOf
 
   return S_OK;
 
 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return E_FAIL;
 }
 
 STDMETHODIMP
-CAccessibleText::get_caretOffset(long *aOffset)
+ia2AccessibleText::get_caretOffset(long *aOffset)
 {
 __try {
   *aOffset = -1;
 
-  nsRefPtr<HyperTextAccessible> textAcc(do_QueryObject(this));
+  HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
   if (textAcc->IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
   PRInt32 offset = 0;
   nsresult rv = textAcc->GetCaretOffset(&offset);
   if (NS_FAILED(rv))
     return GetHRESULT(rv);
 
   *aOffset = offset;
   return offset != -1 ? S_OK : S_FALSE;
 
 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return E_FAIL;
 }
 
 STDMETHODIMP
-CAccessibleText::get_characterExtents(long aOffset,
-                                      enum IA2CoordinateType aCoordType,
-                                      long *aX, long *aY,
-                                      long *aWidth, long *aHeight)
+ia2AccessibleText::get_characterExtents(long aOffset,
+                                        enum IA2CoordinateType aCoordType,
+                                        long *aX, long *aY,
+                                        long *aWidth, long *aHeight)
 {
 __try {
   *aX = 0;
   *aY = 0;
   *aWidth = 0;
   *aHeight = 0;
 
-  nsRefPtr<HyperTextAccessible> textAcc(do_QueryObject(this));
+  HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
   if (textAcc->IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
   PRUint32 geckoCoordType = (aCoordType == IA2_COORDTYPE_SCREEN_RELATIVE) ?
     nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE :
     nsIAccessibleCoordinateType::COORDTYPE_PARENT_RELATIVE;
 
   PRInt32 x = 0, y =0, width = 0, height = 0;
@@ -143,46 +143,46 @@ CAccessibleText::get_characterExtents(lo
   *aHeight = height;
   return S_OK;
 
 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return E_FAIL;
 }
 
 STDMETHODIMP
-CAccessibleText::get_nSelections(long *aNSelections)
+ia2AccessibleText::get_nSelections(long *aNSelections)
 {
 __try {
   *aNSelections = 0;
 
-  nsRefPtr<HyperTextAccessible> textAcc(do_QueryObject(this));
+  HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
   if (textAcc->IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
   PRInt32 selCount = 0;
   nsresult rv = textAcc->GetSelectionCount(&selCount);
   if (NS_FAILED(rv))
     return GetHRESULT(rv);
 
   *aNSelections = selCount;
   return S_OK;
 
 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return E_FAIL;
 }
 
 STDMETHODIMP
-CAccessibleText::get_offsetAtPoint(long aX, long aY,
-                                   enum IA2CoordinateType aCoordType,
-                                   long *aOffset)
+ia2AccessibleText::get_offsetAtPoint(long aX, long aY,
+                                     enum IA2CoordinateType aCoordType,
+                                     long *aOffset)
 {
 __try {
   *aOffset = 0;
 
-  nsRefPtr<HyperTextAccessible> textAcc(do_QueryObject(this));
+  HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
   if (textAcc->IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
   PRUint32 geckoCoordType = (aCoordType == IA2_COORDTYPE_SCREEN_RELATIVE) ?
     nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE :
     nsIAccessibleCoordinateType::COORDTYPE_PARENT_RELATIVE;
 
   PRInt32 offset = 0;
@@ -193,24 +193,24 @@ CAccessibleText::get_offsetAtPoint(long 
   *aOffset = offset;
   return S_OK;
 
 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return E_FAIL;
 }
 
 STDMETHODIMP
-CAccessibleText::get_selection(long aSelectionIndex, long *aStartOffset,
-                               long *aEndOffset)
+ia2AccessibleText::get_selection(long aSelectionIndex, long *aStartOffset,
+                                 long *aEndOffset)
 {
 __try {
   *aStartOffset = 0;
   *aEndOffset = 0;
 
-  nsRefPtr<HyperTextAccessible> textAcc(do_QueryObject(this));
+  HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
   if (textAcc->IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
   PRInt32 startOffset = 0, endOffset = 0;
   nsresult rv = textAcc->GetSelectionBounds(aSelectionIndex,
                                             &startOffset, &endOffset);
   if (NS_FAILED(rv))
     return GetHRESULT(rv);
@@ -219,22 +219,22 @@ CAccessibleText::get_selection(long aSel
   *aEndOffset = endOffset;
   return S_OK;
 
 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return E_FAIL;
 }
 
 STDMETHODIMP
-CAccessibleText::get_text(long aStartOffset, long aEndOffset, BSTR *aText)
+ia2AccessibleText::get_text(long aStartOffset, long aEndOffset, BSTR *aText)
 {
 __try {
   *aText = NULL;
 
-  nsRefPtr<HyperTextAccessible> textAcc(do_QueryObject(this));
+  HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
   if (textAcc->IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
   nsAutoString text;
   nsresult rv = textAcc->GetText(aStartOffset, aEndOffset, text);
   if (NS_FAILED(rv))
     return GetHRESULT(rv);
 
@@ -244,27 +244,27 @@ CAccessibleText::get_text(long aStartOff
   *aText = ::SysAllocStringLen(text.get(), text.Length());
   return *aText ? S_OK : E_OUTOFMEMORY;
 
 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return E_FAIL;
 }
 
 STDMETHODIMP
-CAccessibleText::get_textBeforeOffset(long aOffset,
-                                      enum IA2TextBoundaryType aBoundaryType,
-                                      long *aStartOffset, long *aEndOffset,
-                                      BSTR *aText)
+ia2AccessibleText::get_textBeforeOffset(long aOffset,
+                                        enum IA2TextBoundaryType aBoundaryType,
+                                        long *aStartOffset, long *aEndOffset,
+                                        BSTR *aText)
 {
 __try {
   *aStartOffset = 0;
   *aEndOffset = 0;
   *aText = NULL;
 
-  nsRefPtr<HyperTextAccessible> textAcc(do_QueryObject(this));
+  HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
   if (textAcc->IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
   nsresult rv = NS_OK;
   nsAutoString text;
   PRInt32 startOffset = 0, endOffset = 0;
 
   if (aBoundaryType == IA2_TEXT_BOUNDARY_ALL) {
@@ -291,27 +291,27 @@ CAccessibleText::get_textBeforeOffset(lo
   *aText = ::SysAllocStringLen(text.get(), text.Length());
   return *aText ? S_OK : E_OUTOFMEMORY;
 
 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return E_FAIL;
 }
 
 STDMETHODIMP
-CAccessibleText::get_textAfterOffset(long aOffset,
-                                     enum IA2TextBoundaryType aBoundaryType,
-                                     long *aStartOffset, long *aEndOffset,
-                                     BSTR *aText)
+ia2AccessibleText::get_textAfterOffset(long aOffset,
+                                       enum IA2TextBoundaryType aBoundaryType,
+                                       long *aStartOffset, long *aEndOffset,
+                                       BSTR *aText)
 {
 __try {
   *aStartOffset = 0;
   *aEndOffset = 0;
   *aText = NULL;
 
-  nsRefPtr<HyperTextAccessible> textAcc(do_QueryObject(this));
+  HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
   if (textAcc->IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
   nsresult rv = NS_OK;
   nsAutoString text;
   PRInt32 startOffset = 0, endOffset = 0;
 
   if (aBoundaryType == IA2_TEXT_BOUNDARY_ALL) {
@@ -338,27 +338,27 @@ CAccessibleText::get_textAfterOffset(lon
   *aText = ::SysAllocStringLen(text.get(), text.Length());
   return *aText ? S_OK : E_OUTOFMEMORY;
 
 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return E_FAIL;
 }
 
 STDMETHODIMP
-CAccessibleText::get_textAtOffset(long aOffset,
-                                  enum IA2TextBoundaryType aBoundaryType,
-                                  long *aStartOffset, long *aEndOffset,
-                                  BSTR *aText)
+ia2AccessibleText::get_textAtOffset(long aOffset,
+                                    enum IA2TextBoundaryType aBoundaryType,
+                                    long *aStartOffset, long *aEndOffset,
+                                    BSTR *aText)
 {
 __try {
   *aStartOffset = 0;
   *aEndOffset = 0;
   *aText = NULL;
 
-  nsRefPtr<HyperTextAccessible> textAcc(do_QueryObject(this));
+  HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
   if (textAcc->IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
   nsresult rv = NS_OK;
   nsAutoString text;
   PRInt32 startOffset = 0, endOffset = 0;
 
   if (aBoundaryType == IA2_TEXT_BOUNDARY_ALL) {
@@ -385,142 +385,142 @@ CAccessibleText::get_textAtOffset(long a
   *aText = ::SysAllocStringLen(text.get(), text.Length());
   return *aText ? S_OK : E_OUTOFMEMORY;
 
 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return E_FAIL;
 }
 
 STDMETHODIMP
-CAccessibleText::removeSelection(long aSelectionIndex)
+ia2AccessibleText::removeSelection(long aSelectionIndex)
 {
 __try {
-  nsRefPtr<HyperTextAccessible> textAcc(do_QueryObject(this));
+  HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
   if (textAcc->IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
   nsresult rv = textAcc->RemoveSelection(aSelectionIndex);
   return GetHRESULT(rv);
 
 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return E_FAIL;
 }
 
 STDMETHODIMP
-CAccessibleText::setCaretOffset(long aOffset)
+ia2AccessibleText::setCaretOffset(long aOffset)
 {
 __try {
-  nsRefPtr<HyperTextAccessible> textAcc(do_QueryObject(this));
+  HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
   if (textAcc->IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
   nsresult rv = textAcc->SetCaretOffset(aOffset);
   return GetHRESULT(rv);
 
 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return E_FAIL;
 }
 
 STDMETHODIMP
-CAccessibleText::setSelection(long aSelectionIndex, long aStartOffset,
-                              long aEndOffset)
+ia2AccessibleText::setSelection(long aSelectionIndex, long aStartOffset,
+                                long aEndOffset)
 {
 __try {
-  nsRefPtr<HyperTextAccessible> textAcc(do_QueryObject(this));
+  HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
   if (textAcc->IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
   nsresult rv = textAcc->SetSelectionBounds(aSelectionIndex,
                                             aStartOffset, aEndOffset);
   return GetHRESULT(rv);
 
 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return E_FAIL;
 }
 
 STDMETHODIMP
-CAccessibleText::get_nCharacters(long *aNCharacters)
+ia2AccessibleText::get_nCharacters(long *aNCharacters)
 {
 __try {
   *aNCharacters = 0;
 
-  nsRefPtr<HyperTextAccessible> textAcc(do_QueryObject(this));
+  HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
   if (textAcc->IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
   *aNCharacters  = textAcc->CharacterCount();
   return S_OK;
 
 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return E_FAIL;
 }
 
 STDMETHODIMP
-CAccessibleText::scrollSubstringTo(long aStartIndex, long aEndIndex,
-                                   enum IA2ScrollType aScrollType)
+ia2AccessibleText::scrollSubstringTo(long aStartIndex, long aEndIndex,
+                                     enum IA2ScrollType aScrollType)
 {
 __try {
-  nsRefPtr<HyperTextAccessible> textAcc(do_QueryObject(this));
+  HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
   if (textAcc->IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
   nsresult rv = textAcc->ScrollSubstringTo(aStartIndex, aEndIndex, aScrollType);
   return GetHRESULT(rv);
 
 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return E_FAIL;
 }
 
 STDMETHODIMP
-CAccessibleText::scrollSubstringToPoint(long aStartIndex, long aEndIndex,
-                                        enum IA2CoordinateType aCoordType,
-                                        long aX, long aY)
+ia2AccessibleText::scrollSubstringToPoint(long aStartIndex, long aEndIndex,
+                                          enum IA2CoordinateType aCoordType,
+                                          long aX, long aY)
 {
 __try {
-  nsRefPtr<HyperTextAccessible> textAcc(do_QueryObject(this));
+  HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
   if (textAcc->IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
   PRUint32 geckoCoordType = (aCoordType == IA2_COORDTYPE_SCREEN_RELATIVE) ?
     nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE :
     nsIAccessibleCoordinateType::COORDTYPE_PARENT_RELATIVE;
 
   nsresult rv = textAcc->ScrollSubstringToPoint(aStartIndex, aEndIndex,
                                                 geckoCoordType, aX, aY);
   return GetHRESULT(rv);
 
 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return E_FAIL;
 }
 
 STDMETHODIMP
-CAccessibleText::get_newText(IA2TextSegment *aNewText)
+ia2AccessibleText::get_newText(IA2TextSegment *aNewText)
 {
 __try {
   return GetModifiedText(true, aNewText);
 
 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return E_FAIL;
 }
 
 STDMETHODIMP
-CAccessibleText::get_oldText(IA2TextSegment *aOldText)
+ia2AccessibleText::get_oldText(IA2TextSegment *aOldText)
 {
 __try {
   return GetModifiedText(false, aOldText);
 
 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return E_FAIL;
 }
 
-// CAccessibleText
+// ia2AccessibleText
 
 HRESULT
-CAccessibleText::GetModifiedText(bool aGetInsertedText,
-                                 IA2TextSegment *aText)
+ia2AccessibleText::GetModifiedText(bool aGetInsertedText,
+                                   IA2TextSegment *aText)
 {
   PRUint32 startOffset = 0, endOffset = 0;
   nsAutoString text;
 
   nsresult rv = GetModifiedText(aGetInsertedText, text,
                                 &startOffset, &endOffset);
   if (NS_FAILED(rv))
     return GetHRESULT(rv);
@@ -531,17 +531,17 @@ CAccessibleText::GetModifiedText(bool aG
   if (text.IsEmpty())
     return S_FALSE;
 
   aText->text = ::SysAllocStringLen(text.get(), text.Length());
   return aText->text ? S_OK : E_OUTOFMEMORY;
 }
 
 AccessibleTextBoundary
-CAccessibleText::GetGeckoTextBoundary(enum IA2TextBoundaryType aBoundaryType)
+ia2AccessibleText::GetGeckoTextBoundary(enum IA2TextBoundaryType aBoundaryType)
 {
   switch (aBoundaryType) {
     case IA2_TEXT_BOUNDARY_CHAR:
       return nsIAccessibleText::BOUNDARY_CHAR;
     case IA2_TEXT_BOUNDARY_WORD:
       return nsIAccessibleText::BOUNDARY_WORD_START;
     case IA2_TEXT_BOUNDARY_LINE:
       return nsIAccessibleText::BOUNDARY_LINE_START;
rename from accessible/src/msaa/CAccessibleText.h
rename to accessible/src/msaa/ia2AccessibleText.h
--- a/accessible/src/msaa/CAccessibleText.h
+++ b/accessible/src/msaa/ia2AccessibleText.h
@@ -8,17 +8,17 @@
 #ifndef _ACCESSIBLE_TEXT_H
 #define _ACCESSIBLE_TEXT_H
 
 #include "nsISupports.h"
 #include "nsIAccessibleText.h"
 
 #include "AccessibleText.h"
 
-class CAccessibleText: public IAccessibleText
+class ia2AccessibleText: public IAccessibleText
 {
 public:
 
   // IUnknown
   STDMETHODIMP QueryInterface(REFIID, void**);
 
   // IAccessibleText
   virtual HRESULT STDMETHODCALLTYPE addSelection(
--- a/accessible/src/xforms/nsXFormsFormControlsAccessible.cpp
+++ b/accessible/src/xforms/nsXFormsFormControlsAccessible.cpp
@@ -114,19 +114,18 @@ nsXFormsTriggerAccessible::DoAction(PRUi
 ////////////////////////////////////////////////////////////////////////////////
 
 nsXFormsInputAccessible::
   nsXFormsInputAccessible(nsIContent* aContent, DocAccessible* aDoc) :
   nsXFormsEditableAccessible(aContent, aDoc)
 {
 }
 
-NS_IMPL_ISUPPORTS_INHERITED3(nsXFormsInputAccessible,
+NS_IMPL_ISUPPORTS_INHERITED2(nsXFormsInputAccessible,
                              Accessible,
-                             HyperTextAccessible,
                              nsIAccessibleText,
                              nsIAccessibleEditableText)
 
 role
 nsXFormsInputAccessible::NativeRole()
 {
   return roles::ENTRY;
 }
--- a/accessible/src/xpcom/xpcAccessibleTable.cpp
+++ b/accessible/src/xpcom/xpcAccessibleTable.cpp
@@ -115,16 +115,99 @@ xpcAccessibleTable::GetRowExtentAt(PRInt
       aColIdx < 0 || static_cast<PRUint32>(aColIdx) >= mTable->ColCount())
     return NS_ERROR_INVALID_ARG;
 
   *aRowExtent = mTable->RowExtentAt(aRowIdx, aColIdx);
   return NS_OK;
 }
 
 nsresult
+xpcAccessibleTable::GetColumnDescription(PRInt32 aColIdx,
+                                         nsAString& aDescription)
+{
+  if (!mTable)
+    return NS_ERROR_FAILURE;
+
+  if (aColIdx < 0 || static_cast<PRUint32>(aColIdx) >= mTable->ColCount())
+    return NS_ERROR_INVALID_ARG;
+
+  nsAutoString description;
+  mTable->ColDescription(aColIdx, description);
+  aDescription.Assign(description);
+
+  return NS_OK;
+}
+
+nsresult
+xpcAccessibleTable::GetRowDescription(PRInt32 aRowIdx, nsAString& aDescription)
+{
+  if (!mTable)
+    return NS_ERROR_FAILURE;
+
+  if (aRowIdx < 0 || static_cast<PRUint32>(aRowIdx) >= mTable->ColCount())
+    return NS_ERROR_INVALID_ARG;
+
+  nsAutoString description;
+  mTable->RowDescription(aRowIdx, description);
+  aDescription.Assign(description);
+
+  return NS_OK;
+}
+
+nsresult
+xpcAccessibleTable::IsColumnSelected(PRInt32 aColIdx, bool* aIsSelected)
+{
+  NS_ENSURE_ARG_POINTER(aIsSelected);
+  *aIsSelected = false;
+
+  if (!mTable)
+    return NS_ERROR_FAILURE;
+
+  if (aColIdx < 0 || static_cast<PRUint32>(aColIdx) >= mTable->ColCount())
+    return NS_ERROR_INVALID_ARG;
+
+  *aIsSelected = mTable->IsColSelected(aColIdx);
+  return NS_OK;
+}
+
+nsresult
+xpcAccessibleTable::IsRowSelected(PRInt32 aRowIdx, bool* aIsSelected)
+{
+  NS_ENSURE_ARG_POINTER(aIsSelected);
+  *aIsSelected = false;
+
+  if (!mTable)
+    return NS_ERROR_FAILURE;
+
+  if (aRowIdx < 0 || static_cast<PRUint32>(aRowIdx) >= mTable->RowCount())
+    return NS_ERROR_INVALID_ARG;
+
+  *aIsSelected = mTable->IsRowSelected(aRowIdx);
+  return NS_OK;
+}
+
+nsresult
+xpcAccessibleTable::IsCellSelected(PRInt32 aRowIdx, PRInt32 aColIdx,
+                                   bool* aIsSelected)
+{
+  NS_ENSURE_ARG_POINTER(aIsSelected);
+  *aIsSelected = false;
+
+  if (!mTable)
+    return NS_ERROR_FAILURE;
+
+  if (aRowIdx < 0 || static_cast<PRUint32>(aRowIdx) >= mTable->RowCount() ||
+      aColIdx < 0 || static_cast<PRUint32>(aColIdx) >= mTable->ColCount())
+    return NS_ERROR_INVALID_ARG;
+
+  *aIsSelected = mTable->IsCellSelected(aRowIdx, aColIdx);
+  return NS_OK;
+}
+
+nsresult
 xpcAccessibleTable::GetSummary(nsAString& aSummary)
 {
   if (!mTable)
     return NS_ERROR_FAILURE;
 
   nsAutoString summary;
   mTable->Summary(summary);
   aSummary.Assign(summary);
--- a/accessible/src/xpcom/xpcAccessibleTable.h
+++ b/accessible/src/xpcom/xpcAccessibleTable.h
@@ -29,16 +29,21 @@ public:
   nsresult GetCellAt(PRInt32 aRowIndex, PRInt32 aColumnIndex,
                      nsIAccessible** aCell);
   nsresult GetCellIndexAt(PRInt32 aRowIndex, PRInt32 aColumnIndex,
                           PRInt32* aCellIndex);
   nsresult GetColumnExtentAt(PRInt32 row, PRInt32 column,
                              PRInt32* aColumnExtent);
   nsresult GetRowExtentAt(PRInt32 row, PRInt32 column,
                           PRInt32* aRowExtent);
+  nsresult GetColumnDescription(PRInt32 aColIdx, nsAString& aDescription);
+  nsresult GetRowDescription(PRInt32 aRowIdx, nsAString& aDescription);
+  nsresult IsColumnSelected(PRInt32 aColIdx, bool* _retval);
+  nsresult IsRowSelected(PRInt32 aRowIdx, bool* _retval);
+  nsresult IsCellSelected(PRInt32 aRowIdx, PRInt32 aColIdx, bool* _retval);
   nsresult SelectColumn(PRInt32 aColIdx);
   nsresult SelectRow(PRInt32 aRowIdx);
   nsresult UnselectColumn(PRInt32 aColIdx);
   nsresult UnselectRow(PRInt32 aRowIdx);
   nsresult IsProbablyForLayout(bool* aIsForLayout);
 
 protected:
   mozilla::a11y::TableAccessible* mTable;
@@ -59,21 +64,26 @@ protected:
     { return xpcAccessibleTable::GetCellIndexAt(rowIndex, columnIndex, _retval); } \
   NS_SCRIPTABLE NS_IMETHOD GetColumnIndexAt(PRInt32 cellIndex, PRInt32 *_retval NS_OUTPARAM); \
   NS_SCRIPTABLE NS_IMETHOD GetRowIndexAt(PRInt32 cellIndex, PRInt32 *_retval NS_OUTPARAM); \
   NS_SCRIPTABLE NS_IMETHOD GetRowAndColumnIndicesAt(PRInt32 cellIndex, PRInt32 *rowIndex NS_OUTPARAM, PRInt32 *columnIndex NS_OUTPARAM); \
   NS_SCRIPTABLE NS_IMETHOD GetColumnExtentAt(PRInt32 row, PRInt32 column, PRInt32* _retval NS_OUTPARAM) \
     { return xpcAccessibleTable::GetColumnExtentAt(row, column, _retval); } \
   NS_SCRIPTABLE NS_IMETHOD GetRowExtentAt(PRInt32 row, PRInt32 column, PRInt32* _retval NS_OUTPARAM) \
     { return xpcAccessibleTable::GetRowExtentAt(row, column, _retval); } \
-  NS_SCRIPTABLE NS_IMETHOD GetColumnDescription(PRInt32 columnIndex, nsAString & _retval NS_OUTPARAM); \
-  NS_SCRIPTABLE NS_IMETHOD GetRowDescription(PRInt32 rowIndex, nsAString & _retval NS_OUTPARAM); \
-  NS_SCRIPTABLE NS_IMETHOD IsColumnSelected(PRInt32 columnIndex, bool *_retval NS_OUTPARAM); \
-  NS_SCRIPTABLE NS_IMETHOD IsRowSelected(PRInt32 rowIndex, bool *_retval NS_OUTPARAM); \
-  NS_SCRIPTABLE NS_IMETHOD IsCellSelected(PRInt32 rowIndex, PRInt32 columnIndex, bool *_retval NS_OUTPARAM); \
+  NS_SCRIPTABLE NS_IMETHOD GetColumnDescription(PRInt32 columnIndex, nsAString& _retval NS_OUTPARAM) \
+    { return xpcAccessibleTable::GetColumnDescription(columnIndex, _retval); } \
+  NS_SCRIPTABLE NS_IMETHOD GetRowDescription(PRInt32 rowIndex, nsAString& _retval NS_OUTPARAM) \
+    { return xpcAccessibleTable::GetRowDescription(rowIndex, _retval); } \
+  NS_SCRIPTABLE NS_IMETHOD IsColumnSelected(PRInt32 colIdx, bool* _retval NS_OUTPARAM) \
+    { return xpcAccessibleTable::IsColumnSelected(colIdx, _retval); } \
+  NS_SCRIPTABLE NS_IMETHOD IsRowSelected(PRInt32 rowIdx, bool* _retval NS_OUTPARAM) \
+    { return xpcAccessibleTable::IsRowSelected(rowIdx, _retval); } \
+  NS_SCRIPTABLE NS_IMETHOD IsCellSelected(PRInt32 rowIdx, PRInt32 colIdx, bool* _retval NS_OUTPARAM) \
+    { return xpcAccessibleTable::IsCellSelected(rowIdx, colIdx, _retval); } \
   NS_SCRIPTABLE NS_IMETHOD GetSelectedCellCount(PRUint32 *aSelectedCellCount); \
   NS_SCRIPTABLE NS_IMETHOD GetSelectedColumnCount(PRUint32 *aSelectedColumnCount); \
   NS_SCRIPTABLE NS_IMETHOD GetSelectedRowCount(PRUint32 *aSelectedRowCount); \
   NS_SCRIPTABLE NS_IMETHOD GetSelectedCells(nsIArray * *aSelectedCells); \
   NS_SCRIPTABLE NS_IMETHOD GetSelectedCellIndices(PRUint32 *cellsArraySize NS_OUTPARAM, PRInt32 **cellsArray NS_OUTPARAM); \
   NS_SCRIPTABLE NS_IMETHOD GetSelectedColumnIndices(PRUint32 *rowsArraySize NS_OUTPARAM, PRInt32 **rowsArray NS_OUTPARAM); \
   NS_SCRIPTABLE NS_IMETHOD GetSelectedRowIndices(PRUint32 *rowsArraySize NS_OUTPARAM, PRInt32 **rowsArray NS_OUTPARAM); \
   NS_SCRIPTABLE NS_IMETHOD SelectRow(PRInt32 aRowIdx) \
--- a/accessible/src/xul/XULFormControlAccessible.cpp
+++ b/accessible/src/xul/XULFormControlAccessible.cpp
@@ -680,19 +680,18 @@ XULToolbarSeparatorAccessible::NativeSta
 ////////////////////////////////////////////////////////////////////////////////
 
 XULTextFieldAccessible::
  XULTextFieldAccessible(nsIContent* aContent, DocAccessible* aDoc) :
  HyperTextAccessibleWrap(aContent, aDoc)
 {
 }
 
-NS_IMPL_ISUPPORTS_INHERITED3(XULTextFieldAccessible,
+NS_IMPL_ISUPPORTS_INHERITED2(XULTextFieldAccessible,
                              Accessible,
-                             HyperTextAccessible,
                              nsIAccessibleText,
                              nsIAccessibleEditableText)
 
 ////////////////////////////////////////////////////////////////////////////////
 // XULTextFieldAccessible: nsIAccessible
 
 void
 XULTextFieldAccessible::Value(nsString& aValue)
--- a/accessible/src/xul/XULListboxAccessible.cpp
+++ b/accessible/src/xul/XULListboxAccessible.cpp
@@ -311,83 +311,52 @@ XULListboxAccessible::GetRowAndColumnInd
   nsresult rv = GetColumnCount(&columnCount);
   NS_ENSURE_SUCCESS(rv, rv);
 
   *aColumnIndex = aCellIndex % columnCount;
   *aRowIndex = aCellIndex / columnCount;
   return NS_OK;
 }
 
-NS_IMETHODIMP
-XULListboxAccessible::GetColumnDescription(PRInt32 aColumn,
-                                           nsAString& aDescription)
-{
-  aDescription.Truncate();
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-XULListboxAccessible::GetRowDescription(PRInt32 aRow, nsAString& aDescription)
+bool
+XULListboxAccessible::IsColSelected(PRUint32 aColIdx)
 {
-  aDescription.Truncate();
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-XULListboxAccessible::IsColumnSelected(PRInt32 aColumn, bool* aIsSelected)
-{
-  NS_ENSURE_ARG_POINTER(aIsSelected);
-  *aIsSelected = false;
-
-  if (IsDefunct())
-    return NS_ERROR_FAILURE;
-
   nsCOMPtr<nsIDOMXULMultiSelectControlElement> control =
     do_QueryInterface(mContent);
   NS_ASSERTION(control,
                "Doesn't implement nsIDOMXULMultiSelectControlElement.");
 
   PRInt32 selectedrowCount = 0;
   nsresult rv = control->GetSelectedCount(&selectedrowCount);
-  NS_ENSURE_SUCCESS(rv, rv);
+  NS_ENSURE_SUCCESS(rv, false);
 
-  PRInt32 rowCount = 0;
-  rv = GetRowCount(&rowCount);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  *aIsSelected = (selectedrowCount == rowCount);
-  return NS_OK;
+  return selectedrowCount == RowCount();
 }
 
-NS_IMETHODIMP
-XULListboxAccessible::IsRowSelected(PRInt32 aRow, bool* aIsSelected)
+bool
+XULListboxAccessible::IsRowSelected(PRUint32 aRowIdx)
 {
-  NS_ENSURE_ARG_POINTER(aIsSelected);
-  *aIsSelected = false;
-
-  if (IsDefunct())
-    return NS_ERROR_FAILURE;
-
   nsCOMPtr<nsIDOMXULSelectControlElement> control =
     do_QueryInterface(mContent);
   NS_ASSERTION(control,
                "Doesn't implement nsIDOMXULSelectControlElement.");
 
   nsCOMPtr<nsIDOMXULSelectControlItemElement> item;
-  control->GetItemAtIndex(aRow, getter_AddRefs(item));
-  NS_ENSURE_TRUE(item, NS_ERROR_INVALID_ARG);
+  nsresult rv = control->GetItemAtIndex(aRowIdx, getter_AddRefs(item));
+  NS_ENSURE_SUCCESS(rv, false);
 
-  return item->GetSelected(aIsSelected);
+  bool isSelected = false;
+  item->GetSelected(&isSelected);
+  return isSelected;
 }
 
-NS_IMETHODIMP
-XULListboxAccessible::IsCellSelected(PRInt32 aRowIndex, PRInt32 aColumnIndex,
-                                     bool* aIsSelected)
+bool
+XULListboxAccessible::IsCellSelected(PRUint32 aRowIdx, PRUint32 aColIdx)
 {
-  return IsRowSelected(aRowIndex, aIsSelected);
+  return IsRowSelected(aRowIdx);
 }
 
 NS_IMETHODIMP
 XULListboxAccessible::GetSelectedCellCount(PRUint32* aCount)
 {
   NS_ENSURE_ARG_POINTER(aCount);
   *aCount = 0;
 
--- a/accessible/src/xul/XULListboxAccessible.h
+++ b/accessible/src/xul/XULListboxAccessible.h
@@ -71,16 +71,19 @@ public:
 
   // nsIAccessibleTable
   NS_DECL_OR_FORWARD_NSIACCESSIBLETABLE_WITH_XPCACCESSIBLETABLE
 
   // TableAccessible
   virtual PRUint32 ColCount();
   virtual PRUint32 RowCount();
   virtual Accessible* CellAt(PRUint32 aRowIndex, PRUint32 aColumnIndex);
+  virtual bool IsColSelected(PRUint32 aColIdx);
+  virtual bool IsRowSelected(PRUint32 aRowIdx);
+  virtual bool IsCellSelected(PRUint32 aRowIdx, PRUint32 aColIdx);
   virtual void SelectRow(PRUint32 aRowIdx);
   virtual void UnselectRow(PRUint32 aRowIdx);
 
   // nsAccessNode
   virtual void Shutdown();
 
   // Accessible
   virtual void Value(nsString& aValue);
--- a/accessible/src/xul/XULTreeAccessible.cpp
+++ b/accessible/src/xul/XULTreeAccessible.cpp
@@ -548,16 +548,21 @@ XULTreeAccessible::GetTreeItemAccessible
 }
 
 void
 XULTreeAccessible::InvalidateCache(PRInt32 aRow, PRInt32 aCount)
 {
   if (IsDefunct())
     return;
 
+  if (!mTreeView) {
+    ClearCache(mAccessibleCache);
+    return;
+  }
+
   // Do not invalidate the cache if rows have been inserted.
   if (aCount > 0)
     return;
 
   DocAccessible* document = Document();
 
   // Fire destroy event for removed tree items and delete them from caches.
   for (PRInt32 rowIdx = aRow; rowIdx < aRow - aCount; rowIdx++) {
@@ -601,16 +606,21 @@ XULTreeAccessible::InvalidateCache(PRInt
 
 void
 XULTreeAccessible::TreeViewInvalidated(PRInt32 aStartRow, PRInt32 aEndRow,
                                        PRInt32 aStartCol, PRInt32 aEndCol)
 {
   if (IsDefunct())
     return;
 
+  if (!mTreeView) {
+    ClearCache(mAccessibleCache);
+    return;
+  }
+
   PRInt32 endRow = aEndRow;
 
   nsresult rv;
   if (endRow == -1) {
     PRInt32 rowCount = 0;
     rv = mTreeView->GetRowCount(&rowCount);
     if (NS_FAILED(rv))
       return;
--- a/accessible/src/xul/XULTreeGridAccessible.cpp
+++ b/accessible/src/xul/XULTreeGridAccessible.cpp
@@ -363,93 +363,63 @@ XULTreeGridAccessible::GetRowAndColumnIn
   nsresult rv = GetColumnCount(&columnCount);
   NS_ENSURE_SUCCESS(rv, rv);
 
   *aColumnIndex = aCellIndex % columnCount;
   *aRowIndex = aCellIndex / columnCount;
   return NS_OK;
 }
 
-NS_IMETHODIMP
-XULTreeGridAccessible::GetColumnDescription(PRInt32 aColumnIndex,
-                                            nsAString& aDescription)
+void
+XULTreeGridAccessible::ColDescription(PRUint32 aColIdx, nsString& aDescription)
 {
   aDescription.Truncate();
 
-  if (IsDefunct())
-    return NS_ERROR_FAILURE;
-
   nsCOMPtr<nsIAccessible> treeColumns;
   Accessible::GetFirstChild(getter_AddRefs(treeColumns));
   if (treeColumns) {
     nsCOMPtr<nsIAccessible> treeColumnItem;
-    treeColumns->GetChildAt(aColumnIndex, getter_AddRefs(treeColumnItem));
+    treeColumns->GetChildAt(aColIdx, getter_AddRefs(treeColumnItem));
     if (treeColumnItem)
-      return treeColumnItem->GetName(aDescription);
+      treeColumnItem->GetName(aDescription);
   }
-
-  return NS_OK;
 }
 
-NS_IMETHODIMP
-XULTreeGridAccessible::GetRowDescription(PRInt32 aRowIndex,
-                                         nsAString& aDescription)
+bool
+XULTreeGridAccessible::IsColSelected(PRUint32 aColIdx)
 {
-  aDescription.Truncate();
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-XULTreeGridAccessible::IsColumnSelected(PRInt32 aColumnIndex, bool* aIsSelected)
-{
-  NS_ENSURE_ARG_POINTER(aIsSelected);
-  *aIsSelected = false;
-
-  if (IsDefunct())
-    return NS_ERROR_FAILURE;
-
   // If all the row has been selected, then all the columns are selected.
   // Because we can't select a column alone.
 
-  PRInt32 rowCount = 0;
-  nsresult rv = GetRowCount(&rowCount);
-  NS_ENSURE_SUCCESS(rv, rv);
+  PRInt32 selectedrowCount = 0;
+  nsresult rv = GetSelectionCount(&selectedrowCount);
+  NS_ENSURE_SUCCESS(rv, false);
 
-  PRInt32 selectedrowCount = 0;
-  rv = GetSelectionCount(&selectedrowCount);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  *aIsSelected = rowCount == selectedrowCount;
-  return NS_OK;
+  return selectedrowCount == RowCount();
 }
 
-NS_IMETHODIMP
-XULTreeGridAccessible::IsRowSelected(PRInt32 aRowIndex, bool* aIsSelected)
+bool
+XULTreeGridAccessible::IsRowSelected(PRUint32 aRowIdx)
 {
-  NS_ENSURE_ARG_POINTER(aIsSelected);
-  *aIsSelected = false;
-
-  if (IsDefunct())
-    return NS_ERROR_FAILURE;
-
   if (!mTreeView)
-    return NS_ERROR_INVALID_ARG;
+    return false;
 
   nsCOMPtr<nsITreeSelection> selection;
   nsresult rv = mTreeView->GetSelection(getter_AddRefs(selection));
-  NS_ENSURE_SUCCESS(rv, rv);
+  NS_ENSURE_SUCCESS(rv, false);
 
-  return selection->IsSelected(aRowIndex, aIsSelected);
+  bool isSelected = false;
+  selection->IsSelected(aRowIdx, &isSelected);
+  return isSelected;
 }
 
-NS_IMETHODIMP
-XULTreeGridAccessible::IsCellSelected(PRInt32 aRowIndex, PRInt32 aColumnIndex,
-                                      bool* aIsSelected)
+bool
+XULTreeGridAccessible::IsCellSelected(PRUint32 aRowIdx, PRUint32 aColIdx)
 {
-  return IsRowSelected(aRowIndex, aIsSelected);
+  return IsRowSelected(aRowIdx);
 }
 
 void
 XULTreeGridAccessible::SelectRow(PRUint32 aRowIdx)
 {
   if (!mTreeView)
     return;
 
--- a/accessible/src/xul/XULTreeGridAccessible.h
+++ b/accessible/src/xul/XULTreeGridAccessible.h
@@ -29,16 +29,20 @@ public:
 
   // nsIAccessibleTable
   NS_DECL_OR_FORWARD_NSIACCESSIBLETABLE_WITH_XPCACCESSIBLETABLE
 
   // TableAccessible
   virtual PRUint32 ColCount();
   virtual PRUint32 RowCount();
   virtual Accessible* CellAt(PRUint32 aRowIndex, PRUint32 aColumnIndex);
+  virtual void ColDescription(PRUint32 aColIdx, nsString& aDescription);
+  virtual bool IsColSelected(PRUint32 aColIdx);
+  virtual bool IsRowSelected(PRUint32 aRowIdx);
+  virtual bool IsCellSelected(PRUint32 aRowIdx, PRUint32 aColIdx);
   virtual void SelectRow(PRUint32 aRowIdx);
   virtual void UnselectRow(PRUint32 aRowIdx);
 
   // nsAccessNode
   virtual void Shutdown();
 
   // Accessible
   virtual TableAccessible* AsTable() { return this; }
--- a/accessible/tests/mochitest/attributes/test_text.html
+++ b/accessible/tests/mochitest/attributes/test_text.html
@@ -302,16 +302,34 @@
         "text-line-through-style": "solid",
         "text-line-through-color": gComputedStyle.color
       };
       testTextAttrs(ID, 110, attrs, defAttrs, 109, 122);
 
       attrs = {};
       testTextAttrs(ID, 123, attrs, defAttrs, 122, 130);
 
+      attrs = {
+        "text-line-through-style": "solid",
+        "text-line-through-color": gComputedStyle.color
+      };
+      testTextAttrs(ID, 131, attrs, defAttrs, 130, 143);
+
+      attrs = {};
+      testTextAttrs(ID, 144, attrs, defAttrs, 143, 151);
+
+      attrs = {
+        "text-line-through-style": "solid",
+        "text-line-through-color": gComputedStyle.color
+      };
+      testTextAttrs(ID, 152, attrs, defAttrs, 151, 164);
+
+      attrs = {};
+      testTextAttrs(ID, 165, attrs, defAttrs, 164, 172);
+
       //////////////////////////////////////////////////////////////////////////
       // area10, different single style spans in non-styled paragraph
       ID = "area10";
       defAttrs = buildDefaultTextAttrs(ID, "12pt");
       testDefaultTextAttrs(ID, defAttrs);
 
       attrs = {};
       testTextAttrs(ID, 0, attrs, defAttrs, 0, 7);
@@ -616,16 +634,18 @@
 
   <p id="area9" style="font-size: smaller">Small
     <span style="font-size: 120%">bigger</span> smaller
     <span style="background-color: blue;">background blue</span> normal
     <span style="font-style: italic;">Different styling</span> normal
     <span style="font-family: monospace;">Different font</span> normal
     <span style="text-decoration: underline;">underlined</span> normal
     <span style="text-decoration: line-through;">strikethrough</span> normal
+    <s>strikethrough</s> normal
+    <strike>strikethrough</strike> normal
   </p>
 
   <p id="area10">Normal
     <span style="font-size: 120%">bigger</span> smaller
     <span style="background-color: blue;">background blue</span> normal
     <span style="font-style: italic;">Different styling</span> normal
     <span style="font-family: monospace;">Different font</span> normal
     <span style="text-decoration: underline;">underlined</span> normal
--- a/accessible/tests/mochitest/bounds/test_zoom.html
+++ b/accessible/tests/mochitest/bounds/test_zoom.html
@@ -10,37 +10,46 @@
   <script type="application/javascript"
           src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
 
   <script type="application/javascript"
           src="../common.js"></script>
   <script type="application/javascript"
           src="../role.js"></script>
   <script type="application/javascript"
+          src="../events.js"></script>
+  <script type="application/javascript"
           src="../layout.js"></script>
   <script type="application/javascript"
           src="../browser.js"></script>
 
   <script type="application/javascript">
+    //gA11yEventDumpToConsole = true;
+    function doPreTest()
+    {
+      var tabDocument = currentTabDocument();
+      var imgMap = tabDocument.getElementById("imgmap");
+      waitForImageMap(imgMap, doTest);
+    }
+
     function doTest()
     {
       // Bug 746176: Failure of this whole test file on OS X.
       if (MAC) {
         todo(false, "Fix bug 746176 on Mac");
         closeBrowserWindow();
         SimpleTest.finish();
         return;
       }
 
       var tabDocument = currentTabDocument();
       var p1 = tabDocument.getElementById("p1");
       var p2 = tabDocument.getElementById("p2");
 
       var imgMap = tabDocument.getElementById("imgmap");
-      ensureImageMapTree(imgMap);
       var imgMapAcc = getAccessible(imgMap);
       var area = imgMapAcc.firstChild;
 
       testBounds(p1);
       testBounds(p2);
       testBounds(area);
 
       zoomDocument(tabDocument, 2.0);
@@ -60,20 +69,21 @@
     url += "        coords=17,0,30,14' alt='mozilla.org' shape='rect'>";
     url += "</map>";
     url += "<img id='imgmap' width='447' height='15'";
     url += "     usemap='%23atoz_map'";
     url += "     src='chrome%3A%2F%2Fmochitests%2Fcontent%2Fa11y%2Faccessible%2Fletters.gif'>";
     url += "</body></html>";
 
     SimpleTest.waitForExplicitFinish();
-    openBrowserWindow(doTest,
+    openBrowserWindow(doPreTest,
                       url,
                       { left: 0, top: 0, width: 600, height: 600 });
   </script>
+
 </head>
 <body>
 
   <a target="_blank"
      href="https://bugzilla.mozilla.org/show_bug.cgi?id=650241"
      title="Location returned by accessibles incorrect when page zoomed">
     Mozilla Bug 650241
   </a>
--- a/accessible/tests/mochitest/common.js
+++ b/accessible/tests/mochitest/common.js
@@ -509,34 +509,16 @@ function testDefunctAccessible(aAcc, aNo
     aAcc.parent;
   } catch (e) {
     success = (e.result == Components.results.NS_ERROR_FAILURE);
   }
   ok(success, "parent" + msg);
 }
 
 /**
- * Ensure that image map accessible tree is created.
- */
-function ensureImageMapTree(aID)
-{
-  // XXX: We send a useless mouse move to the image to force it to setup its
-  // image map, because flushing layout won't do it. Hopefully bug 135040
-  // will make this not suck.
-  var image = getNode(aID);
-  synthesizeMouse(image, 10, 10, { type: "mousemove" },
-                  image.ownerDocument.defaultView);
-
-  // XXX This may affect a11y more than other code because imagemaps may not
-  // get drawn or have an mouse event over them. Bug 570322 tracks a11y
-  // dealing with this.
-  todo(false, "Need to remove this image map workaround.");
-}
-
-/**
  * Convert role to human readable string.
  */
 function roleToString(aRole)
 {
   return gAccRetrieval.getStringRole(aRole);
 }
 
 /**
--- a/accessible/tests/mochitest/events.js
+++ b/accessible/tests/mochitest/events.js
@@ -94,16 +94,31 @@ function waitForEvent(aEventType, aTarge
       );
     }
   };
 
   registerA11yEventListener(aEventType, handler);
 }
 
 /**
+ * Call the given function when the tree of the given image map is built.
+ */
+function waitForImageMap(aImageMapID, aTestFunc)
+{
+  synthesizeMouse(aImageMapID, 10, 10, { type: "mousemove" },
+                  aImageMapID.ownerDocument.defaultView);
+
+  var imageMapAcc = getAccessible(aImageMapID);
+  if (imageMapAcc.firstChild)
+    return aTestFunc();
+
+  waitForEvent(EVENT_REORDER, imageMapAcc, aTestFunc);
+}
+
+/**
  * Register accessibility event listener.
  *
  * @param aEventType     the accessible event type (see nsIAccessibleEvent for
  *                       available constants).
  * @param aEventHandler  event listener object, when accessible event of the
  *                       given type is handled then 'handleEvent' method of
  *                       this object is invoked with nsIAccessibleEvent object
  *                       as the first argument.
--- a/accessible/tests/mochitest/hyperlink/test_general.html
+++ b/accessible/tests/mochitest/hyperlink/test_general.html
@@ -53,16 +53,21 @@ https://bugzilla.mozilla.org/show_bug.cg
         if (actionCount)
           ok(false, "Exception on action name getting for ID " + aId);
         else
           ok(true, "Correct action name for ID " + aId);
       }
     }
 
     //gA11yEventDumpToConsole = true; // debug stuff
+    function doPreTest()
+    {
+      var imgMap = document.getElementById("imgmap");
+      waitForImageMap(imgMap, doTest);
+    }
 
     var gQueue = null;
     function doTest()
     {
       //////////////////////////////////////////////////////////////////////////
       // normal hyperlink
       var normalHyperlinkAcc = getAccessible("NormalHyperlink",
                                              [nsIAccessibleHyperLink]);
@@ -85,17 +90,16 @@ https://bugzilla.mozilla.org/show_bug.cg
       // ARIA hyperlink with status invalid
       var invalidAriaHyperlinkAcc = getAccessible("InvalidAriaHyperlink",
                                                   [nsIAccessibleHyperLink]);
       is(invalidAriaHyperlinkAcc.valid, false, "Should not be valid!");
       testStates(invalidAriaHyperlinkAcc, STATE_LINKED, EXT_STATE_HORIZONTAL);
 
       //////////////////////////////////////////////////////////////////////////
       // image map and its link children
-      ensureImageMapTree("imgmap");
 
       var imageMapHyperlinkAcc = getAccessible("imgmap",
                                                [nsIAccessibleHyperLink]);
       testThis("imgmap", imageMapHyperlinkAcc, ROLE_IMAGE_MAP, 2, "b", true,
                79, 80);
       is(imageMapHyperlinkAcc.getURI(0).spec,
          "http://www.bbc.co.uk/radio4/atoz/index.shtml#b", "URI wrong!");
       is(imageMapHyperlinkAcc.getURI(1).spec,
@@ -234,18 +238,19 @@ https://bugzilla.mozilla.org/show_bug.cg
       gQueue.push(new focusLink("AriaHyperlink", true));
       gQueue.push(new focusLink("InvalidAriaHyperlink", false));
       gQueue.push(new focusLink("LinkWithSpan", true));
 
       gQueue.invoke(); // Will call SimpleTest.finish();
     }
 
     SimpleTest.waitForExplicitFinish();
-    addA11yLoadEvent(doTest);
+    addA11yLoadEvent(doPreTest);
   </script>
+
 </head>
 <body><a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=418368">Mozilla Bug 418368</a
   ><p id="display"></p
   ><div id="content" style="display: none"></div
   ><pre id="test">
   </pre
   ><br
   >Simple link:<br
--- a/accessible/tests/mochitest/hypertext/test_general.html
+++ b/accessible/tests/mochitest/hypertext/test_general.html
@@ -9,16 +9,18 @@ https://bugzilla.mozilla.org/show_bug.cg
 
   <script type="application/javascript"
           src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
   <script type="application/javascript"
           src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
 
   <script type="application/javascript"
           src="../common.js"></script>
+  <script type="application/javascript"
+          src="../events.js"></script>
 
   <script type="application/javascript">
     var gParagraphAcc;
 
     function testLinkIndexAtOffset(aID, aOffset, aIndex)
     {
       var htAcc = getAccessible(aID, [nsIAccessibleHyperText]);
       is(htAcc.getLinkIndexAtOffset(aOffset), aIndex,
@@ -34,33 +36,39 @@ https://bugzilla.mozilla.org/show_bug.cg
 
       var linkIndex = gParagraphAcc.getLinkIndex(linkAcc);
       is(linkIndex, aExpectedLinkIndex, "Wrong link index for " + aID + "!");
 
       // Just test the link's name to make sure we get the right one.
       is(linkAcc.getAnchor(0).name, aName, "Wrong name for " + aID + "!");
     }
 
+    //gA11yEventDumpToConsole = true;
+    function doPreTest()
+    {
+      var imgMap = document.getElementById("imgmap");
+      waitForImageMap(imgMap, doTest);
+    }
+
     function doTest()
     {
       // Test link count
       gParagraphAcc = getAccessible("testParagraph", [nsIAccessibleHyperText]);
       is(gParagraphAcc.linkCount, 7, "Wrong link count for paragraph!");
 
       // normal hyperlink
       testThis("NormalHyperlink", 14, 0, "Mozilla Foundation");
 
       // ARIA hyperlink
       testThis("AriaHyperlink", 27, 1, "Mozilla Foundation Home");
 
       // ARIA hyperlink with status invalid
       testThis("InvalidAriaHyperlink", 63, 2, "Invalid link");
 
       // image map, but not its link children. They are not part of hypertext.
-      ensureImageMapTree("imgmap");
       testThis("imgmap", 76, 3, "b");
 
       // empty hyperlink
       testThis("emptyLink", 90, 4, null);
 
       // normal hyperlink with embedded span
       testThis("LinkWithSpan", 116, 5, "Heise Online");
 
@@ -93,18 +101,19 @@ https://bugzilla.mozilla.org/show_bug.cg
       testLinkIndexAtOffset("p4", 7, -1); // ' ' of 'xt ' text node
       testLinkIndexAtOffset("p4", 8, 2); // 3d 'mozilla' link
       testLinkIndexAtOffset("p4", 9, 2); // the end, latest link
 
       SimpleTest.finish();
     }
 
     SimpleTest.waitForExplicitFinish();
-    addA11yLoadEvent(doTest);
+    addA11yLoadEvent(doPreTest);
   </script>
+
 </head>
 <body>
 
   <a target="_blank"
      title="Create tests for NSIAccessibleHyperlink interface"
      href="https://bugzilla.mozilla.org/show_bug.cgi?id=418368">
     Mozilla Bug 418368
   </a><br>
--- a/accessible/tests/mochitest/states/test_aria_imgmap.html
+++ b/accessible/tests/mochitest/states/test_aria_imgmap.html
@@ -9,23 +9,30 @@
   <script type="application/javascript"
           src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
 
   <script type="application/javascript"
           src="../common.js"></script>
   <script type="application/javascript"
           src="../role.js"></script>
   <script type="application/javascript"
+          src="../events.js"></script>
+  <script type="application/javascript"
           src="../states.js"></script>
 
   <script type="application/javascript">
+  //gA11yEventDumpToConsole = true;
+  function doPreTest()
+  {
+    var imgMap = document.getElementById("imagemap");
+    waitForImageMap(imgMap, doTest);
+  }
+
   function doTest()
   {
-    ensureImageMapTree("imagemap");
-
     var imageMap = getAccessible("imagemap");
 
     var t1 = imageMap.getChildAt(0);
     testStates(t1, 0, EXT_STATE_EDITABLE, STATE_LINKED);
     var t2 = imageMap.getChildAt(1);
     testStates(t2, 0, EXT_STATE_EDITABLE, STATE_LINKED);
     var rb1 = imageMap.getChildAt(2);
     testStates(rb1, (STATE_CHECKABLE | STATE_CHECKED), 0, STATE_LINKED);
@@ -36,18 +43,19 @@
     var cbox = imageMap.getChildAt(5);
     testStates(cbox, (STATE_HASPOPUP | STATE_COLLAPSED),
                EXT_STATE_EXPANDABLE, STATE_LINKED);
 
     SimpleTest.finish();
   }
 
   SimpleTest.waitForExplicitFinish();
-  addA11yLoadEvent(doTest);
+  addA11yLoadEvent(doPreTest);
   </script>
+
 </head>
 <body>
 
 <a target="_blank"
   href="https://bugzilla.mozilla.org/show_bug.cgi?id=548291"
   title="ARIA states on image maps">
 Mozilla Bug 548291
 </a>
--- a/accessible/tests/mochitest/table/test_table_1.html
+++ b/accessible/tests/mochitest/table/test_table_1.html
@@ -45,44 +45,34 @@ function doTest()
   s.addRange(range);
   range = document.createRange();
   cell = getNode("row2c");
   range.selectNode(cell);
   s.addRange(range);
 
   is(accTable.selectedRowCount, 1, "no cells selected");
 
-  var columnDescription;
-  works = true;
-  try{
-    columnDescription = accTable.getColumnDescription(1);
-  }
-  catch (e) {
-    works = false;
-  }
-  todo(works, "columnDescription should not throw");
+  var columnDescription = accTable.getColumnDescription(1);
+  var rowDescription = accTable.getRowDescription(1);
 
-  var rowDescription;
-  works = true;
-  try {
-    rowDescription = accTable.getRowDescription(1);
-  }
-  catch (e) {
-    works = false;
-  }
-  todo(works, "rowDescription should not throw");
   SimpleTest.finish();
 }
 SimpleTest.waitForExplicitFinish();
 addA11yLoadEvent(doTest);
   </script>
  </head>
  <body >
 
   <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=410052">Mozilla Bug 410052</a>
+  <a target="_blank"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=760878"
+     title="decomtaminate Get Row / Column Description() on accessible tables">
+    Mozilla Bug 760878
+  </a>
+
   <p id="display"></p>
   <div id="content" style="display: none"></div>
   <pre id="test">
   </pre>
 
   <!-- Test Table -->
   <br><br><b> Testing Table:</b><br><br>
   <center>
--- a/accessible/tests/mochitest/tree/test_aria_imgmap.html
+++ b/accessible/tests/mochitest/tree/test_aria_imgmap.html
@@ -9,23 +9,30 @@
   <script type="application/javascript"
           src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
 
   <script type="application/javascript"
           src="../common.js"></script>
   <script type="application/javascript"
           src="../role.js"></script>
   <script type="application/javascript"
+          src="../events.js"></script>
+  <script type="application/javascript"
           src="../states.js"></script>
 
   <script type="application/javascript">
+  //gA11yEventDumpToConsole = true;
+  function doPreTest()
+  {
+    var imgMap = document.getElementById("imagemap");
+    waitForImageMap(imgMap, doTest);
+  }
+
   function doTest()
   {
-    ensureImageMapTree("imagemap");
-
     var accTree = {
       role: ROLE_IMAGE_MAP,
       children: [
         {
           role: ROLE_ENTRY,
           name: "first name"
         },
         {
@@ -65,18 +72,19 @@
 
     // Test image map tree structure, roles, and names.
     testAccessibleTree("imagemap", accTree);
 
     SimpleTest.finish();
   }
 
   SimpleTest.waitForExplicitFinish();
-  addA11yLoadEvent(doTest);
+  addA11yLoadEvent(doPreTest);
   </script>
+
 </head>
 <body>
 
 <a target="_blank"
   href="https://bugzilla.mozilla.org/show_bug.cgi?id=548291"
   title="Accessible tree of ARIA image maps">
 Mozilla Bug 548291
 </a>
--- a/accessible/tests/mochitest/tree/test_img.html
+++ b/accessible/tests/mochitest/tree/test_img.html
@@ -9,18 +9,27 @@
           src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
   <script type="application/javascript"
           src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
 
   <script type="application/javascript"
           src="../common.js"></script>
   <script type="application/javascript"
           src="../role.js"></script>
+  <script type="application/javascript"
+          src="../events.js"></script>
 
   <script type="application/javascript">
+    //gA11yEventDumpToConsole = true;
+    function doPreTest()
+    {
+      var imgMap = document.getElementById("imgmap");
+      waitForImageMap(imgMap, doTest);
+    }
+
     function doTest()
     {
       // image map
       var accTree = {
         role: ROLE_IMAGE_MAP,
         children: [
           {
             role: ROLE_LINK,
@@ -28,33 +37,33 @@
           },
           {
             role: ROLE_LINK,
             children: []
           }
         ]
       };
 
-      ensureImageMapTree("imgmap");
       testAccessibleTree("imgmap", accTree);
 
       // img
       accTree = {
         role: ROLE_GRAPHIC,
         children: []
       };
 
       testAccessibleTree("img", accTree);
 
       SimpleTest.finish();
     }
 
     SimpleTest.waitForExplicitFinish();
-    addA11yLoadEvent(doTest);
+    addA11yLoadEvent(doPreTest);
   </script>
+
 </head>
 <body>
 
   <a target="_blank"
      title="Fix O(n^2) access to all the children of a container"
      href="https://bugzilla.mozilla.org/show_bug.cgi?id=342045">
     Mozilla Bug 342045
   </a>
--- a/accessible/tests/mochitest/treeupdate/test_imagemap.html
+++ b/accessible/tests/mochitest/treeupdate/test_imagemap.html
@@ -319,18 +319,16 @@
                           "http://www.bbc.co.uk/radio4/atoz/index.shtml#b");
         area.setAttribute("coords", "17,0,30,14");
         area.setAttribute("alt", "b");
         area.setAttribute("shape", "rect");
 
         map.appendChild(area);
 
         this.containerNode.appendChild(map);
-
-        ensureImageMapTree(aImageID);
       }
 
       this.finalCheck = function insertMap_finalCheck()
       {
         var accTree =
           { SECTION: [
             { IMAGE_MAP: [
               { LINK: [ ] }
@@ -376,16 +374,21 @@
 
       this.getID = function hideImageMap_getID()
       {
         return "display:none image";
       }
     }
 
     gA11yEventDumpToConsole = true;
+    function doPreTest()
+    {
+      var imgMap = document.getElementById("imgmap");
+      waitForImageMap(imgMap, doTest);
+    }
 
     var gQueue = null;
     function doTest()
     {
       gQueue = new eventQueue();
 
       gQueue.push(new insertArea("imgmap", "map"));
       gQueue.push(new appendArea("imgmap", "map"));
@@ -395,18 +398,19 @@
       gQueue.push(new removeMap("container", "imgmap", "map"));
       gQueue.push(new insertMap("container", "imgmap"));
       gQueue.push(new hideImageMap("container", "imgmap"));
 
       gQueue.invoke(); // Will call SimpleTest.finish();
     }
 
     SimpleTest.waitForExplicitFinish();
-    addA11yLoadEvent(doTest);
+    addA11yLoadEvent(doPreTest);
   </script>
+
 </head>
 <body>
 
   <a target="_blank"
      title="Image map accessible tree is not updated when image map is changed"
      href="https://bugzilla.mozilla.org/show_bug.cgi?id=732389">
     Mozilla Bug 732389
   </a>
--- a/allmakefiles.sh
+++ b/allmakefiles.sh
@@ -112,17 +112,16 @@ if [ "$COMPILER_DEPEND" = "" -a "$MOZ_NA
     config/mkdepend/Makefile
   "
 fi
 
 if [ "$ENABLE_MARIONETTE" ]; then
   add_makefiles "
     testing/marionette/Makefile
     testing/marionette/components/Makefile
-    testing/marionette/tests/Makefile
   "
 fi
 
 if [ "$ENABLE_TESTS" ]; then
   add_makefiles "
     build/autoconf/test/Makefile
     config/makefiles/test/Makefile
     config/tests/makefiles/autodeps/Makefile
--- a/b2g/app/b2g.js
+++ b/b2g/app/b2g.js
@@ -1,45 +1,16 @@
 /* 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/. */
 
 #filter substitution
 
 pref("toolkit.defaultChromeURI", "chrome://browser/content/shell.xul");
 pref("browser.chromeURL", "chrome://browser/content/");
-#ifdef MOZ_OFFICIAL_BRANDING
-pref("browser.homescreenURL", "http://homescreen.gaiamobile.org/");
-#else
-pref("browser.homescreenURL", "http://homescreen.gaiamobile.org/");
-#endif
-
-// All the privileged domains
-// XXX TODO : we should read them from a file somewhere
-pref("b2g.privileged.domains", "http://browser.gaiamobile.org,
-	                            http://calculator.gaiamobile.org,
-	                            http://contacts.gaiamobile.org,
-	                            http://camera.gaiamobile.org,
-	                            http://clock.gaiamobile.org,
-	                            http://crystalskull.gaiamobile.org,
-	                            http://cubevid.gaiamobile.org,
-	                            http://dialer.gaiamobile.org,
-	                            http://gallery.gaiamobile.org,
-	                            http://homescreen.gaiamobile.org,
-	                            http://maps.gaiamobile.org,
-	                            http://market.gaiamobile.org,
-	                            http://music.gaiamobile.org,
-	                            http://penguinpop.gaiamobile.org,
-	                            http://settings.gaiamobile.org,
-	                            http://sms.gaiamobile.org,
-	                            http://towerjelly.gaiamobile.org,
-	                            http://video.gaiamobile.org");
-
-// URL for the dialer application.
-pref("dom.telephony.app.phone.url", "http://dialer.gaiamobile.org,http://homescreen.gaiamobile.org");
 
 // Device pixel to CSS px ratio, in percent. Set to -1 to calculate based on display density.
 pref("browser.viewport.scaleRatio", -1);
 
 /* disable text selection */
 pref("browser.ignoreNativeFrameTextSelection", true);
 
 /* cache prefs */
@@ -390,32 +361,26 @@ pref("browser.link.open_newwindow", 3);
 // 0: no restrictions - divert everything
 // 1: don't divert window.open at all
 // 2: don't divert window.open with features
 pref("browser.link.open_newwindow.restriction", 0);
 
 // Enable browser frames (including OOP, except on Windows, where it doesn't
 // work), but make in-process browser frames the default.
 pref("dom.mozBrowserFramesEnabled", true);
-pref("dom.mozBrowserFramesWhitelist", "http://homescreen.gaiamobile.org,http://browser.gaiamobile.org");
 
 pref("dom.ipc.tabs.disabled", false);
 
 pref("dom.ipc.browser_frames.oop_by_default", false);
 
 // Temporary permission hack for WebSMS
 pref("dom.sms.enabled", true);
-pref("dom.sms.whitelist", "file://,http://homescreen.gaiamobile.org,http://sms.gaiamobile.org");
-
-// Temporary permission hack for WebMobileConnection
-pref("dom.mobileconnection.whitelist", "http://system.gaiamobile.org,http://homescreen.gaiamobile.org,http://dialer.gaiamobile.org");
 
 // Temporary permission hack for WebContacts
 pref("dom.mozContacts.enabled", true);
-pref("dom.mozContacts.whitelist", "http://dialer.gaiamobile.org,http://sms.gaiamobile.org");
 
 // WebSettings
 pref("dom.mozSettings.enabled", true);
 
 // Ignore X-Frame-Options headers.
 pref("b2g.ignoreXFrameOptions", true);
 
 // controls if we want camera support
@@ -432,21 +397,19 @@ pref("media.realtime_decoder.enabled", t
 pref("layout.frame_rate.precise", true);
 
 // Temporary remote js console hack
 pref("b2g.remote-js.enabled", true);
 pref("b2g.remote-js.port", 9999);
 
 // Handle hardware buttons in the b2g chrome package
 pref("b2g.keys.menu.enabled", true);
-pref("b2g.keys.search.enabled", false);
 
-// Screen timeout in minutes
+// Screen timeout in seconds
 pref("power.screen.timeout", 60);
-pref("dom.power.whitelist", "http://homescreen.gaiamobile.org,http://settings.gaiamobile.org");
 
 pref("full-screen-api.enabled", true);
 
 pref("media.volume.steps", 10);
 
 //Enable/disable marionette server, set listening port
 pref("marionette.defaultPrefs.enabled", true);
 pref("marionette.defaultPrefs.port", 2828);
--- a/b2g/chrome/content/dbg-browser-actors.js
+++ b/b2g/chrome/content/dbg-browser-actors.js
@@ -126,16 +126,37 @@ DeviceTabActor.prototype = {
     return this._tabPool;
   },
 
   _contextPool: null,
   get contextActorPool() {
     return this._contextPool;
   },
 
+  /**
+   * Add the specified breakpoint to the default actor pool connection, in order
+   * to be alive as long as the server is.
+   *
+   * @param BreakpointActor actor
+   *        The actor object.
+   */
+  addToBreakpointPool: function DTA_addToBreakpointPool(actor) {
+    this.conn.addActor(actor);
+  },
+
+  /**
+   * Remove the specified breakpint from the default actor pool.
+   *
+   * @param string actor
+   *        The actor ID.
+   */
+  removeFromBreakpointPool: function DTA_removeFromBreakpointPool(actor) {
+    this.conn.removeActor(actor);
+  },
+
   actorPrefix: 'tab',
 
   grip: function DTA_grip() {
     dbg_assert(!this.exited,
                'grip() should not be called on exited browser actor.');
     dbg_assert(this.actorID,
                'tab should have an actorID.');
     return {
--- a/b2g/chrome/content/shell.js
+++ b/b2g/chrome/content/shell.js
@@ -64,18 +64,16 @@ function addPermissions(urls) {
 
     permissions.forEach(function(permission) {
       Services.perms.add(uri, permission, allow);
     });
   });
 }
 
 var shell = {
-  isDebug: false,
-
   get contentBrowser() {
     delete this.contentBrowser;
     return this.contentBrowser = document.getElementById('homescreen');
   },
 
   get homeURL() {
     try {
       let homeSrc = Services.env.get('B2G_HOMESCREEN');
@@ -129,16 +127,24 @@ var shell = {
     } catch (e) {
       dump('shell.js: Error loading ' + webapiUrl + ' as a frame script: ' + e + '\n');
     }
 
     CustomEventManager.init();
 
     WebappsHelper.init();
 
+    // XXX could factor out into a settings->pref map.  Not worth it yet.
+    SettingsListener.observe("debug.fps.enabled", false, function(value) {
+      Services.prefs.setBoolPref("layers.acceleration.draw-fps", value);
+    });
+    SettingsListener.observe("debug.paint-flashing.enabled", false, function(value) {
+      Services.prefs.setBoolPref("nglayout.debug.paint_flashing", value);
+    });
+
     let browser = this.contentBrowser;
     browser.homePage = homeURL;
     browser.goHome();
   },
 
   stop: function shell_stop() {
     ['keydown', 'keypress', 'keyup'].forEach((function unlistenKey(type) {
       window.removeEventListener(type, this, false, true);
@@ -150,28 +156,16 @@ var shell = {
     window.removeEventListener('mozfullscreenchange', this);
     window.removeEventListener('sizemodechange', this);
     this.contentBrowser.removeEventListener('load', this, true);
 
 #ifndef MOZ_WIDGET_GONK
     delete Services.audioManager;
 #endif
   },
-
-  toggleDebug: function shell_toggleDebug() {
-    this.isDebug = !this.isDebug;
-
-    if (this.isDebug) {
-      Services.prefs.setBoolPref("layers.acceleration.draw-fps", true);
-      Services.prefs.setBoolPref("nglayout.debug.paint_flashing", true);
-    } else {
-      Services.prefs.setBoolPref("layers.acceleration.draw-fps", false);
-      Services.prefs.setBoolPref("nglayout.debug.paint_flashing", false);
-    }
-  },
  
   changeVolume: function shell_changeVolume(delta) {
     let steps = 10;
     try {
       steps = Services.prefs.getIntPref("media.volume.steps");
       if (steps <= 0)
         steps = 1;
     } catch(e) {}
@@ -204,21 +198,16 @@ var shell = {
     switch (evt.type) {
       case 'keydown':
       case 'keyup':
       case 'keypress':
         // For debug purposes and because some of the APIs are not yet exposed
         // to the content, let's react on some of the keyup events.
         if (evt.type == 'keyup' && evt.eventPhase == evt.BUBBLING_PHASE) {
           switch (evt.keyCode) {
-            case evt.DOM_VK_F5:
-              if (Services.prefs.getBoolPref('b2g.keys.search.enabled'))
-                this.toggleDebug();
-              break;
-  
             case evt.DOM_VK_PAGE_DOWN:
               this.changeVolume(-1);
               break;
   
             case evt.DOM_VK_PAGE_UP:
               this.changeVolume(1);
               break;
           }
--- a/b2g/installer/package-manifest.in
+++ b/b2g/installer/package-manifest.in
@@ -211,16 +211,17 @@
 @BINPATH@/components/imglib2.xpt
 @BINPATH@/components/imgicon.xpt
 @BINPATH@/components/inspector.xpt
 @BINPATH@/components/intl.xpt
 @BINPATH@/components/jar.xpt
 @BINPATH@/components/jetpack.xpt
 @BINPATH@/components/jsdebugger.xpt
 @BINPATH@/components/jsdservice.xpt
+@BINPATH@/components/jsinspector.xpt
 @BINPATH@/components/layout_base.xpt
 @BINPATH@/components/layout_forms.xpt
 #ifdef NS_PRINTING
 @BINPATH@/components/layout_printing.xpt
 #endif
 @BINPATH@/components/layout_xul_tree.xpt
 @BINPATH@/components/layout_xul.xpt
 @BINPATH@/components/locale.xpt
--- a/browser/app/nsBrowserApp.cpp
+++ b/browser/app/nsBrowserApp.cpp
@@ -15,16 +15,17 @@
 #endif
 
 #ifdef XP_MACOSX
 #include "MacQuirks.h"
 #endif
 
 #include <stdio.h>
 #include <stdarg.h>
+#include <time.h>
 
 #include "nsCOMPtr.h"
 #include "nsIFile.h"
 #include "nsStringGlue.h"
 
 #ifdef XP_WIN
 // we want a wmain entry point
 #include "nsWindowsWMain.cpp"
@@ -236,28 +237,44 @@ int main(int argc, char* argv[])
 
   int gotCounters;
 #if defined(XP_UNIX)
   struct rusage initialRUsage;
   gotCounters = !getrusage(RUSAGE_SELF, &initialRUsage);
 #elif defined(XP_WIN)
   // Don't change the order of these enumeration constants, the order matters
   // for reporting telemetry data.  If new values are added adjust the
-  // STARTUP_USING_PRELOAD histogram.
-  enum PreloadReason { PRELOAD_NONE, PRELOAD_SERVICE };
-  PreloadReason preloadReason = PRELOAD_NONE;
+  // STARTUP_USING_PRELOAD_TRIAL histogram.
+  enum PreloadType{ PREFETCH_PRELOAD,
+                    PREFETCH_NO_PRELOAD,
+                    NO_PREFETCH_PRELOAD,
+                    NO_PREFETCH_NO_PRELOAD };
+  PreloadType preloadType;
 
   IO_COUNTERS ioCounters;
   gotCounters = GetProcessIoCounters(GetCurrentProcess(), &ioCounters);
 
+  srand(time(NULL));
+  bool shouldUsePreload = rand() % 2 == 0;
+
   if (IsPrefetchDisabledViaService()) {
-    preloadReason = PRELOAD_SERVICE;
+    if (shouldUsePreload) {
+      preloadType = NO_PREFETCH_PRELOAD;
+    }  else {
+      preloadType = NO_PREFETCH_NO_PRELOAD;
+    }
+  } else {
+    if (shouldUsePreload) {
+      preloadType = PREFETCH_PRELOAD;
+    }  else {
+      preloadType = PREFETCH_NO_PRELOAD;
+    }
   }
 
-  if (preloadReason != PRELOAD_NONE)
+  if (shouldUsePreload)
 #endif
   {
       XPCOMGlueEnablePreload();
   }
 
   rv = XPCOMGlueStartup(exePath);
   if (NS_FAILED(rv)) {
     Output("Couldn't load XPCOM.\n");
@@ -274,18 +291,18 @@ int main(int argc, char* argv[])
 
   XRE_StartupTimelineRecord(mozilla::StartupTimeline::START, start);
 
 #ifdef XRE_HAS_DLL_BLOCKLIST
   XRE_SetupDllBlocklist();
 #endif
 
 #if defined(XP_WIN)
-  XRE_TelemetryAccumulate(mozilla::Telemetry::STARTUP_USING_PRELOAD,
-                          preloadReason);
+  XRE_TelemetryAccumulate(mozilla::Telemetry::STARTUP_USING_PRELOAD_TRIAL,
+                          preloadType);
 #endif
 
   if (gotCounters) {
 #if defined(XP_WIN)
     XRE_TelemetryAccumulate(mozilla::Telemetry::EARLY_GLUESTARTUP_READ_OPS,
                             int(ioCounters.ReadOperationCount));
     XRE_TelemetryAccumulate(mozilla::Telemetry::EARLY_GLUESTARTUP_READ_TRANSFER,
                             int(ioCounters.ReadTransferCount / 1024));
--- a/browser/app/profile/extensions/testpilot@labs.mozilla.com/modules/lib/unload.js
+++ b/browser/app/profile/extensions/testpilot@labs.mozilla.com/modules/lib/unload.js
@@ -1,11 +1,28 @@
-/* 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/. */
+// Copyright (c) 2009 Thomas Robinson <tlrobinson.net>
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation files
+// (the “Software”), to deal in the Software without restriction,
+// including without limitation the rights to use, copy, modify, merge,
+// publish, distribute, sublicense, and/or sell copies of the Software,
+// and to permit persons to whom the Software is furnished to do so,
+// subject to the following conditions:
+
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+
+// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 // This module was taken from narwhal:
 //
 // http://narwhaljs.org
 
 var observers = [];
 
 exports.when = function (observer) {
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -1019,16 +1019,17 @@ pref("services.sync.prefs.sync.spellchec
 pref("services.sync.prefs.sync.xpinstall.whitelist.required", true);
 #endif
 
 // Disable the error console
 pref("devtools.errorconsole.enabled", false);
 
 // Developer toolbar and GCLI preferences
 pref("devtools.toolbar.enabled", false);
+pref("devtools.toolbar.visible", false);
 pref("devtools.gcli.allowSet", false);
 
 // Enable the Inspector
 pref("devtools.inspector.enabled", true);
 pref("devtools.inspector.htmlHeight", 112);
 pref("devtools.inspector.htmlPanelOpen", false);
 pref("devtools.inspector.sidebarOpen", false);
 pref("devtools.inspector.activeSidebar", "ruleview");
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -971,192 +971,812 @@ let gGestureSupport = {
       return gPrefService[getFunc](branch + aPref);
     }
     catch (e) {
       return aDef;
     }
   },
 };
 
-function BrowserStartup() {
-  var uriToLoad = null;
-
-  // window.arguments[0]: URI to load (string), or an nsISupportsArray of
-  //                      nsISupportsStrings to load, or a xul:tab of
-  //                      a tabbrowser, which will be replaced by this
-  //                      window (for this case, all other arguments are
-  //                      ignored).
-  //                 [1]: character set (string)
-  //                 [2]: referrer (nsIURI)
-  //                 [3]: postData (nsIInputStream)
-  //                 [4]: allowThirdPartyFixup (bool)
-  if ("arguments" in window && window.arguments[0])
-    uriToLoad = window.arguments[0];
-
-  var isLoadingBlank = isBlankPageURL(uriToLoad);
-  var mustLoadSidebar = false;
-
-  prepareForStartup();
-
-  if (uriToLoad && uriToLoad != "about:blank") {
-    if (uriToLoad instanceof Ci.nsISupportsArray) {
-      let count = uriToLoad.Count();
-      let specs = [];
-      for (let i = 0; i < count; i++) {
-        let urisstring = uriToLoad.GetElementAt(i).QueryInterface(Ci.nsISupportsString);
-        specs.push(urisstring.data);
+var gBrowserInit = {
+  onLoad: function() {
+    // window.arguments[0]: URI to load (string), or an nsISupportsArray of
+    //                      nsISupportsStrings to load, or a xul:tab of
+    //                      a tabbrowser, which will be replaced by this
+    //                      window (for this case, all other arguments are
+    //                      ignored).
+    //                 [1]: character set (string)
+    //                 [2]: referrer (nsIURI)
+    //                 [3]: postData (nsIInputStream)
+    //                 [4]: allowThirdPartyFixup (bool)
+    if ("arguments" in window && window.arguments[0])
+      var uriToLoad = window.arguments[0];
+
+    var isLoadingBlank = isBlankPageURL(uriToLoad);
+    var mustLoadSidebar = false;
+
+    gBrowser.addEventListener("DOMUpdatePageReport", gPopupBlockerObserver, false);
+
+    gBrowser.addEventListener("PluginNotFound",     gPluginHandler, true);
+    gBrowser.addEventListener("PluginCrashed",      gPluginHandler, true);
+    gBrowser.addEventListener("PluginBlocklisted",  gPluginHandler, true);
+    gBrowser.addEventListener("PluginOutdated",     gPluginHandler, true);
+    gBrowser.addEventListener("PluginDisabled",     gPluginHandler, true);
+    gBrowser.addEventListener("PluginClickToPlay",  gPluginHandler, true);
+    gBrowser.addEventListener("NewPluginInstalled", gPluginHandler.newPluginInstalled, true);
+#ifdef XP_MACOSX
+    gBrowser.addEventListener("npapi-carbon-event-model-failure", gPluginHandler, true);
+#endif
+
+    Services.obs.addObserver(gPluginHandler.pluginCrashed, "plugin-crashed", false);
+
+    window.addEventListener("AppCommand", HandleAppCommandEvent, true);
+
+    messageManager.loadFrameScript("chrome://browser/content/content.js", true);
+
+    // initialize observers and listeners
+    // and give C++ access to gBrowser
+    gBrowser.init();
+    XULBrowserWindow.init();
+    window.QueryInterface(Ci.nsIInterfaceRequestor)
+          .getInterface(nsIWebNavigation)
+          .QueryInterface(Ci.nsIDocShellTreeItem).treeOwner
+          .QueryInterface(Ci.nsIInterfaceRequestor)
+          .getInterface(Ci.nsIXULWindow)
+          .XULBrowserWindow = window.XULBrowserWindow;
+    window.QueryInterface(Ci.nsIDOMChromeWindow).browserDOMWindow =
+      new nsBrowserAccess();
+
+    // set default character set if provided
+    if ("arguments" in window && window.arguments.length > 1 && window.arguments[1]) {
+      if (window.arguments[1].indexOf("charset=") != -1) {
+        var arrayArgComponents = window.arguments[1].split("=");
+        if (arrayArgComponents) {
+          //we should "inherit" the charset menu setting in a new window
+          getMarkupDocumentViewer().defaultCharacterSet = arrayArgComponents[1];
+        }
       }
-
-      // This function throws for certain malformed URIs, so use exception handling
-      // so that we don't disrupt startup
-      try {
-        gBrowser.loadTabs(specs, false, true);
-      } catch (e) {}
-    }
-    else if (uriToLoad instanceof XULElement) {
-      // swap the given tab with the default about:blank tab and then close
-      // the original tab in the other window.
-
-      // Stop the about:blank load
-      gBrowser.stop();
-      // make sure it has a docshell
-      gBrowser.docShell;
-
-      gBrowser.swapBrowsersAndCloseOther(gBrowser.selectedTab, uriToLoad);
-    }
-    else if (window.arguments.length >= 3) {
-      loadURI(uriToLoad, window.arguments[2], window.arguments[3] || null,
-              window.arguments[4] || false);
-      content.focus();
-    }
-    // Note: loadOneOrMoreURIs *must not* be called if window.arguments.length >= 3.
-    // Such callers expect that window.arguments[0] is handled as a single URI.
-    else
-      loadOneOrMoreURIs(uriToLoad);
-  }
-
-  if (window.opener && !window.opener.closed) {
-    let openerSidebarBox = window.opener.document.getElementById("sidebar-box");
-    // If the opener had a sidebar, open the same sidebar in our window.
-    // The opener can be the hidden window too, if we're coming from the state
-    // where no windows are open, and the hidden window has no sidebar box.
-    if (openerSidebarBox && !openerSidebarBox.hidden) {
-      let sidebarCmd = openerSidebarBox.getAttribute("sidebarcommand");
-      let sidebarCmdElem = document.getElementById(sidebarCmd);
-
-      // dynamically generated sidebars will fail this check.
-      if (sidebarCmdElem) {
-        let sidebarBox = document.getElementById("sidebar-box");
-        let sidebarTitle = document.getElementById("sidebar-title");
-
-        sidebarTitle.setAttribute(
-          "value", window.opener.document.getElementById("sidebar-title").getAttribute("value"));
-        sidebarBox.setAttribute("width", openerSidebarBox.boxObject.width);
-
-        sidebarBox.setAttribute("sidebarcommand", sidebarCmd);
-        // Note: we're setting 'src' on sidebarBox, which is a <vbox>, not on
-        // the <browser id="sidebar">. This lets us delay the actual load until
-        // delayedStartup().
-        sidebarBox.setAttribute(
-          "src", window.opener.document.getElementById("sidebar").getAttribute("src"));
-        mustLoadSidebar = true;
-
-        sidebarBox.hidden = false;
-        document.getElementById("sidebar-splitter").hidden = false;
-        sidebarCmdElem.setAttribute("checked", "true");
+    }
+
+    // Manually hook up session and global history for the first browser
+    // so that we don't have to load global history before bringing up a
+    // window.
+    // Wire up session and global history before any possible
+    // progress notifications for back/forward button updating
+    gBrowser.webNavigation.sessionHistory = Cc["@mozilla.org/browser/shistory;1"].
+                                            createInstance(Ci.nsISHistory);
+    Services.obs.addObserver(gBrowser.browsers[0], "browser:purge-session-history", false);
+
+    // remove the disablehistory attribute so the browser cleans up, as
+    // though it had done this work itself
+    gBrowser.browsers[0].removeAttribute("disablehistory");
+
+    // enable global history
+    try {
+      gBrowser.docShell.QueryInterface(Ci.nsIDocShellHistory).useGlobalHistory = true;
+    } catch(ex) {
+      Cu.reportError("Places database may be locked: " + ex);
+    }
+
+#ifdef MOZ_E10S_COMPAT
+    // Bug 666801 - WebProgress support for e10s
+#else
+    // hook up UI through progress listener
+    gBrowser.addProgressListener(window.XULBrowserWindow);
+    gBrowser.addTabsProgressListener(window.TabsProgressListener);
+#endif
+
+    // setup our common DOMLinkAdded listener
+    gBrowser.addEventListener("DOMLinkAdded", DOMLinkHandler, false);
+
+    // setup our MozApplicationManifest listener
+    gBrowser.addEventListener("MozApplicationManifest",
+                              OfflineApps, false);
+
+    // setup simple gestures support
+    gGestureSupport.init(true);
+
+
+    if (uriToLoad && uriToLoad != "about:blank") {
+      if (uriToLoad instanceof Ci.nsISupportsArray) {
+        let count = uriToLoad.Count();
+        let specs = [];
+        for (let i = 0; i < count; i++) {
+          let urisstring = uriToLoad.GetElementAt(i).QueryInterface(Ci.nsISupportsString);
+          specs.push(urisstring.data);
+        }
+
+        // This function throws for certain malformed URIs, so use exception handling
+        // so that we don't disrupt startup
+        try {
+          gBrowser.loadTabs(specs, false, true);
+        } catch (e) {}
       }
-    }
-  }
-  else {
-    let box = document.getElementById("sidebar-box");
-    if (box.hasAttribute("sidebarcommand")) {
-      let commandID = box.getAttribute("sidebarcommand");
-      if (commandID) {
-        let command = document.getElementById(commandID);
-        if (command) {
+      else if (uriToLoad instanceof XULElement) {
+        // swap the given tab with the default about:blank tab and then close
+        // the original tab in the other window.
+
+        // Stop the about:blank load
+        gBrowser.stop();
+        // make sure it has a docshell
+        gBrowser.docShell;
+
+        gBrowser.swapBrowsersAndCloseOther(gBrowser.selectedTab, uriToLoad);
+      }
+      else if (window.arguments.length >= 3) {
+        loadURI(uriToLoad, window.arguments[2], window.arguments[3] || null,
+                window.arguments[4] || false);
+        content.focus();
+      }
+      // Note: loadOneOrMoreURIs *must not* be called if window.arguments.length >= 3.
+      // Such callers expect that window.arguments[0] is handled as a single URI.
+      else
+        loadOneOrMoreURIs(uriToLoad);
+    }
+
+    if (window.opener && !window.opener.closed) {
+      let openerSidebarBox = window.opener.document.getElementById("sidebar-box");
+      // If the opener had a sidebar, open the same sidebar in our window.
+      // The opener can be the hidden window too, if we're coming from the state
+      // where no windows are open, and the hidden window has no sidebar box.
+      if (openerSidebarBox && !openerSidebarBox.hidden) {
+        let sidebarCmd = openerSidebarBox.getAttribute("sidebarcommand");
+        let sidebarCmdElem = document.getElementById(sidebarCmd);
+
+        // dynamically generated sidebars will fail this check.
+        if (sidebarCmdElem) {
+          let sidebarBox = document.getElementById("sidebar-box");
+          let sidebarTitle = document.getElementById("sidebar-title");
+
+          sidebarTitle.setAttribute(
+            "value", window.opener.document.getElementById("sidebar-title").getAttribute("value"));
+          sidebarBox.setAttribute("width", openerSidebarBox.boxObject.width);
+
+          sidebarBox.setAttribute("sidebarcommand", sidebarCmd);
+          // Note: we're setting 'src' on sidebarBox, which is a <vbox>, not on
+          // the <browser id="sidebar">. This lets us delay the actual load until
+          // delayedStartup().
+          sidebarBox.setAttribute(
+            "src", window.opener.document.getElementById("sidebar").getAttribute("src"));
           mustLoadSidebar = true;
-          box.hidden = false;
+
+          sidebarBox.hidden = false;
           document.getElementById("sidebar-splitter").hidden = false;
-          command.setAttribute("checked", "true");
+          sidebarCmdElem.setAttribute("checked", "true");
         }
-        else {
-          // Remove the |sidebarcommand| attribute, because the element it
-          // refers to no longer exists, so we should assume this sidebar
-          // panel has been uninstalled. (249883)
-          box.removeAttribute("sidebarcommand");
+      }
+    }
+    else {
+      let box = document.getElementById("sidebar-box");
+      if (box.hasAttribute("sidebarcommand")) {
+        let commandID = box.getAttribute("sidebarcommand");
+        if (commandID) {
+          let command = document.getElementById(commandID);
+          if (command) {
+            mustLoadSidebar = true;
+            box.hidden = false;
+            document.getElementById("sidebar-splitter").hidden = false;
+            command.setAttribute("checked", "true");
+          }
+          else {
+            // Remove the |sidebarcommand| attribute, because the element it
+            // refers to no longer exists, so we should assume this sidebar
+            // panel has been uninstalled. (249883)
+            box.removeAttribute("sidebarcommand");
+          }
         }
       }
     }
-  }
-
-  // Certain kinds of automigration rely on this notification to complete their
-  // tasks BEFORE the browser window is shown.
-  Services.obs.notifyObservers(null, "browser-window-before-show", "");
-
-  // Set a sane starting width/height for all resolutions on new profiles.
-  if (!document.documentElement.hasAttribute("width")) {
-    let defaultWidth = 994;
-    let defaultHeight;
-    if (screen.availHeight <= 600) {
-      document.documentElement.setAttribute("sizemode", "maximized");
-      defaultWidth = 610;
-      defaultHeight = 450;
-    }
-    else {
-      // Create a narrower window for large or wide-aspect displays, to suggest
-      // side-by-side page view.
-      if (screen.availWidth >= 1600)
-        defaultWidth = (screen.availWidth / 2) - 20;
-      defaultHeight = screen.availHeight - 10;
+
+    // Certain kinds of automigration rely on this notification to complete their
+    // tasks BEFORE the browser window is shown.
+    Services.obs.notifyObservers(null, "browser-window-before-show", "");
+
+    // Set a sane starting width/height for all resolutions on new profiles.
+    if (!document.documentElement.hasAttribute("width")) {
+      let defaultWidth = 994;
+      let defaultHeight;
+      if (screen.availHeight <= 600) {
+        document.documentElement.setAttribute("sizemode", "maximized");
+        defaultWidth = 610;
+        defaultHeight = 450;
+      }
+      else {
+        // Create a narrower window for large or wide-aspect displays, to suggest
+        // side-by-side page view.
+        if (screen.availWidth >= 1600)
+          defaultWidth = (screen.availWidth / 2) - 20;
+        defaultHeight = screen.availHeight - 10;
 #ifdef MOZ_WIDGET_GTK2
-      // On X, we're not currently able to account for the size of the window
-      // border.  Use 28px as a guess (titlebar + bottom window border)
-      defaultHeight -= 28;
+        // On X, we're not currently able to account for the size of the window
+        // border.  Use 28px as a guess (titlebar + bottom window border)
+        defaultHeight -= 28;
 #endif
-    }
-    document.documentElement.setAttribute("width", defaultWidth);
-    document.documentElement.setAttribute("height", defaultHeight);
-  }
-
-  if (!gShowPageResizers)
-    document.getElementById("status-bar").setAttribute("hideresizer", "true");
-
-  if (!window.toolbar.visible) {
-    // adjust browser UI for popups
-    if (gURLBar) {
-      gURLBar.setAttribute("readonly", "true");
-      gURLBar.setAttribute("enablehistory", "false");
-    }
-    goSetCommandEnabled("cmd_newNavigatorTab", false);
-  }
+      }
+      document.documentElement.setAttribute("width", defaultWidth);
+      document.documentElement.setAttribute("height", defaultHeight);
+    }
+
+    if (!gShowPageResizers)
+      document.getElementById("status-bar").setAttribute("hideresizer", "true");
+
+    if (!window.toolbar.visible) {
+      // adjust browser UI for popups
+      if (gURLBar) {
+        gURLBar.setAttribute("readonly", "true");
+        gURLBar.setAttribute("enablehistory", "false");
+      }
+      goSetCommandEnabled("cmd_newNavigatorTab", false);
+    }
 
 #ifdef MENUBAR_CAN_AUTOHIDE
-  updateAppButtonDisplay();
+    updateAppButtonDisplay();
+#endif
+
+    // Misc. inits.
+    CombinedStopReload.init();
+    allTabs.readPref();
+    TabsOnTop.init();
+    BookmarksMenuButton.init();
+    TabsInTitlebar.init();
+    gPrivateBrowsingUI.init();
+    DownloadsButton.initializePlaceholder();
+    retrieveToolbarIconsizesFromTheme();
+
+    gDelayedStartupTimeoutId = setTimeout(this._delayedStartup.bind(this), 0, isLoadingBlank, mustLoadSidebar);
+    gStartupRan = true;
+  },
+
+  _delayedStartup: function(isLoadingBlank, mustLoadSidebar) {
+    let tmp = {};
+    Cu.import("resource:///modules/TelemetryTimestamps.jsm", tmp);
+    let TelemetryTimestamps = tmp.TelemetryTimestamps;
+    TelemetryTimestamps.add("delayedStartupStarted");
+    gDelayedStartupTimeoutId = null;
+
+    Services.obs.addObserver(gSessionHistoryObserver, "browser:purge-session-history", false);
+    Services.obs.addObserver(gXPInstallObserver, "addon-install-disabled", false);
+    Services.obs.addObserver(gXPInstallObserver, "addon-install-started", false);
+    Services.obs.addObserver(gXPInstallObserver, "addon-install-blocked", false);
+    Services.obs.addObserver(gXPInstallObserver, "addon-install-failed", false);
+    Services.obs.addObserver(gXPInstallObserver, "addon-install-complete", false);
+    Services.obs.addObserver(gFormSubmitObserver, "invalidformsubmit", false);
+
+    BrowserOffline.init();
+    OfflineApps.init();
+    IndexedDBPromptHelper.init();
+    gFormSubmitObserver.init();
+    AddonManager.addAddonListener(AddonsMgrListener);
+
+    gBrowser.addEventListener("pageshow", function(evt) { setTimeout(pageShowEventHandlers, 0, evt); }, true);
+
+    // Ensure login manager is up and running.
+    Cc["@mozilla.org/login-manager;1"].getService(Ci.nsILoginManager);
+
+    if (mustLoadSidebar) {
+      let sidebar = document.getElementById("sidebar");
+      let sidebarBox = document.getElementById("sidebar-box");
+      sidebar.setAttribute("src", sidebarBox.getAttribute("src"));
+    }
+
+    UpdateUrlbarSearchSplitterState();
+
+    if (isLoadingBlank && gURLBar && isElementVisible(gURLBar))
+      gURLBar.focus();
+    else
+      gBrowser.selectedBrowser.focus();
+
+    gNavToolbox.customizeDone = BrowserToolboxCustomizeDone;
+    gNavToolbox.customizeChange = BrowserToolboxCustomizeChange;
+
+    // Set up Sanitize Item
+    this._initializeSanitizer();
+
+    // Enable/Disable auto-hide tabbar
+    gBrowser.tabContainer.updateVisibility();
+
+    gPrefService.addObserver(gHomeButton.prefDomain, gHomeButton, false);
+
+    var homeButton = document.getElementById("home-button");
+    gHomeButton.updateTooltip(homeButton);
+    gHomeButton.updatePersonalToolbarStyle(homeButton);
+
+    // BiDi UI
+    gBidiUI = isBidiEnabled();
+    if (gBidiUI) {
+      document.getElementById("documentDirection-separator").hidden = false;
+      document.getElementById("documentDirection-swap").hidden = false;
+      document.getElementById("textfieldDirection-separator").hidden = false;
+      document.getElementById("textfieldDirection-swap").hidden = false;
+    }
+
+    // Setup click-and-hold gestures access to the session history
+    // menus if global click-and-hold isn't turned on
+    if (!getBoolPref("ui.click_hold_context_menus", false))
+      SetClickAndHoldHandlers();
+
+    // Initialize the full zoom setting.
+    // We do this before the session restore service gets initialized so we can
+    // apply full zoom settings to tabs restored by the session restore service.
+    FullZoom.init();
+
+#ifdef MOZ_E10S_COMPAT
+    // Bug 666804 - NetworkPrioritizer support for e10s
+#else
+    let NP = {};
+    Cu.import("resource:///modules/NetworkPrioritizer.jsm", NP);
+    NP.trackBrowserWindow(window);
+#endif
+
+    // initialize the session-restore service (in case it's not already running)
+    try {
+      Cc["@mozilla.org/browser/sessionstore;1"]
+        .getService(Ci.nsISessionStore)
+        .init(window);
+    } catch (ex) {
+      dump("nsSessionStore could not be initialized: " + ex + "\n");
+    }
+
+    PlacesToolbarHelper.init();
+
+    ctrlTab.readPref();
+    gPrefService.addObserver(ctrlTab.prefName, ctrlTab, false);
+    gPrefService.addObserver(allTabs.prefName, allTabs, false);
+
+    // Initialize the download manager some time after the app starts so that
+    // auto-resume downloads begin (such as after crashing or quitting with
+    // active downloads) and speeds up the first-load of the download manager UI.
+    // If the user manually opens the download manager before the timeout, the
+    // downloads will start right away, and getting the service again won't hurt.
+    setTimeout(function() {
+      gDownloadMgr = Cc["@mozilla.org/download-manager;1"].
+                     getService(Ci.nsIDownloadManager);
+
+#ifdef XP_WIN
+      if (Win7Features) {
+        let tempScope = {};
+        Cu.import("resource://gre/modules/DownloadTaskbarProgress.jsm",
+                  tempScope);
+        tempScope.DownloadTaskbarProgress.onBrowserWindowLoad(window);
+      }
+#endif
+    }, 10000);
+
+    // The object handling the downloads indicator is also initialized here in the
+    // delayed startup function, but the actual indicator element is not loaded
+    // unless there are downloads to be displayed.
+    DownloadsButton.initializeIndicator();
+
+#ifndef XP_MACOSX
+    updateEditUIVisibility();
+    let placesContext = document.getElementById("placesContext");
+    placesContext.addEventListener("popupshowing", updateEditUIVisibility, false);
+    placesContext.addEventListener("popuphiding", updateEditUIVisibility, false);
+#endif
+
+    gBrowser.mPanelContainer.addEventListener("InstallBrowserTheme", LightWeightThemeWebInstaller, false, true);
+    gBrowser.mPanelContainer.addEventListener("PreviewBrowserTheme", LightWeightThemeWebInstaller, false, true);
+    gBrowser.mPanelContainer.addEventListener("ResetBrowserThemePreview", LightWeightThemeWebInstaller, false, true);
+
+#ifdef MOZ_E10S_COMPAT
+    // Bug 666808 - AeroPeek support for e10s
+#else
+    if (Win7Features)
+      Win7Features.onOpenWindow();
+#endif
+
+   // called when we go into full screen, even if initiated by a web page script
+    window.addEventListener("fullscreen", onFullScreen, true);
+
+    // Called when we enter DOM full-screen mode. Note we can already be in browser
+    // full-screen mode when we enter DOM full-screen mode.
+    window.addEventListener("MozEnteredDomFullscreen", onMozEnteredDomFullscreen, true);
+
+    if (window.fullScreen)
+      onFullScreen();
+    if (document.mozFullScreen)
+      onMozEnteredDomFullscreen();
+
+#ifdef MOZ_SERVICES_SYNC
+    // initialize the sync UI
+    gSyncUI.init();
+#endif
+
+    gBrowserThumbnails.init();
+    TabView.init();
+
+    setUrlAndSearchBarWidthForConditionalForwardButton();
+    window.addEventListener("resize", function resizeHandler(event) {
+      if (event.target == window)
+        setUrlAndSearchBarWidthForConditionalForwardButton();
+    });
+
+    // Enable developer toolbar?
+    let devToolbarEnabled = gPrefService.getBoolPref("devtools.toolbar.enabled");
+    if (devToolbarEnabled) {
+      document.getElementById("menu_devToolbar").hidden = false;
+      document.getElementById("Tools:DevToolbar").removeAttribute("disabled");
+#ifdef MENUBAR_CAN_AUTOHIDE
+      document.getElementById("appmenu_devToolbar").hidden = false;
+#endif
+
+      // Show the toolbar if it was previously visible
+      if (gPrefService.getBoolPref("devtools.toolbar.visible")) {
+        this.DeveloperToolbar.show();
+      }
+    }
+
+    // Enable Inspector?
+    let enabled = gPrefService.getBoolPref("devtools.inspector.enabled");
+    if (enabled) {
+      document.getElementById("menu_pageinspect").hidden = false;
+      document.getElementById("Tools:Inspect").removeAttribute("disabled");
+#ifdef MENUBAR_CAN_AUTOHIDE
+      document.getElementById("appmenu_pageInspect").hidden = false;
+#endif
+      document.getElementById("developer-toolbar-inspector").hidden = false;
+    }
+
+    // Enable Debugger?
+    let enabled = gPrefService.getBoolPref("devtools.debugger.enabled");
+    if (enabled) {
+      document.getElementById("menu_debugger").hidden = false;
+      document.getElementById("Tools:Debugger").removeAttribute("disabled");
+#ifdef MENUBAR_CAN_AUTOHIDE
+      document.getElementById("appmenu_debugger").hidden = false;
+#endif
+      document.getElementById("developer-toolbar-debugger").hidden = false;
+    }
+
+    // Enable Remote Debugger?
+    let enabled = gPrefService.getBoolPref("devtools.debugger.remote-enabled");
+    if (enabled) {
+      document.getElementById("menu_remoteDebugger").hidden = false;
+      document.getElementById("Tools:RemoteDebugger").removeAttribute("disabled");
+#ifdef MENUBAR_CAN_AUTOHIDE
+      document.getElementById("appmenu_remoteDebugger").hidden = false;
+#endif
+    }
+
+    // Enable Chrome Debugger?
+    let enabled = gPrefService.getBoolPref("devtools.chrome.enabled") &&
+                  gPrefService.getBoolPref("devtools.debugger.chrome-enabled") &&
+                  gPrefService.getBoolPref("devtools.debugger.remote-enabled");
+    if (enabled) {
+      document.getElementById("menu_chromeDebugger").hidden = false;
+      document.getElementById("Tools:ChromeDebugger").removeAttribute("disabled");
+#ifdef MENUBAR_CAN_AUTOHIDE
+      document.getElementById("appmenu_chromeDebugger").hidden = false;
+#endif
+    }
+
+    // Enable Error Console?
+    // XXX Temporarily always-enabled, see bug 601201
+    let consoleEnabled = true || gPrefService.getBoolPref("devtools.errorconsole.enabled");
+    if (consoleEnabled) {
+      document.getElementById("javascriptConsole").hidden = false;
+      document.getElementById("key_errorConsole").removeAttribute("disabled");
+#ifdef MENUBAR_CAN_AUTOHIDE
+      document.getElementById("appmenu_errorConsole").hidden = false;
+#endif
+    }
+
+    // Enable Scratchpad in the UI, if the preference allows this.
+    let scratchpadEnabled = gPrefService.getBoolPref(Scratchpad.prefEnabledName);
+    if (scratchpadEnabled) {
+      document.getElementById("menu_scratchpad").hidden = false;
+      document.getElementById("Tools:Scratchpad").removeAttribute("disabled");
+#ifdef MENUBAR_CAN_AUTOHIDE
+      document.getElementById("appmenu_scratchpad").hidden = false;
+#endif
+    }
+
+    // Enable Style Editor?
+    let styleEditorEnabled = gPrefService.getBoolPref(StyleEditor.prefEnabledName);
+    if (styleEditorEnabled) {
+      document.getElementById("menu_styleeditor").hidden = false;
+      document.getElementById("Tools:StyleEditor").removeAttribute("disabled");
+#ifdef MENUBAR_CAN_AUTOHIDE
+      document.getElementById("appmenu_styleeditor").hidden = false;
+#endif
+    }
+
+#ifdef MENUBAR_CAN_AUTOHIDE
+    // If the user (or the locale) hasn't enabled the top-level "Character
+    // Encoding" menu via the "browser.menu.showCharacterEncoding" preference,
+    // hide it.
+    if ("true" != gPrefService.getComplexValue("browser.menu.showCharacterEncoding",
+                                               Ci.nsIPrefLocalizedString).data)
+      document.getElementById("appmenu_charsetMenu").hidden = true;
 #endif
 
-  CombinedStopReload.init();
-
-  allTabs.readPref();
-
-  TabsOnTop.init();
-
-  BookmarksMenuButton.init();
-
-  TabsInTitlebar.init();
-
-  gPrivateBrowsingUI.init();
-
-  DownloadsButton.initializePlaceholder();
-
-  retrieveToolbarIconsizesFromTheme();
-
-  gDelayedStartupTimeoutId = setTimeout(delayedStartup, 0, isLoadingBlank, mustLoadSidebar);
-  gStartupRan = true;
+    // Enable Responsive UI?
+    let responsiveUIEnabled = gPrefService.getBoolPref("devtools.responsiveUI.enabled");
+    if (responsiveUIEnabled) {
+      document.getElementById("menu_responsiveUI").hidden = false;
+      document.getElementById("Tools:ResponsiveUI").removeAttribute("disabled");
+#ifdef MENUBAR_CAN_AUTOHIDE
+      document.getElementById("appmenu_responsiveUI").hidden = false;
+#endif
+      document.getElementById("developer-toolbar-responsiveui").hidden = false;
+    }
+
+    let appMenuButton = document.getElementById("appmenu-button");
+    let appMenuPopup = document.getElementById("appmenu-popup");
+    if (appMenuButton && appMenuPopup) {
+      let appMenuOpening = null;
+      appMenuButton.addEventListener("mousedown", function(event) {
+        if (event.button == 0)
+          appMenuOpening = new Date();
+      }, false);
+      appMenuPopup.addEventListener("popupshown", function(event) {
+        if (event.target != appMenuPopup || !appMenuOpening)
+          return;
+        let duration = new Date() - appMenuOpening;
+        appMenuOpening = null;
+        Services.telemetry.getHistogramById("FX_APP_MENU_OPEN_MS").add(duration);
+      }, false);
+    }
+
+    window.addEventListener("mousemove", MousePosTracker, false);
+    window.addEventListener("dragover", MousePosTracker, false);
+
+    // End startup crash tracking after a delay to catch crashes while restoring
+    // tabs and to postpone saving the pref to disk.
+    try {
+      let appStartup = Cc["@mozilla.org/toolkit/app-startup;1"].
+                       getService(Ci.nsIAppStartup);
+      const startupCrashEndDelay = 30 * 1000;
+      setTimeout(appStartup.trackStartupCrashEnd, startupCrashEndDelay);
+    } catch (ex) {
+      Cu.reportError("Could not end startup crash tracking: " + ex);
+    }
+
+    Services.obs.notifyObservers(window, "browser-delayed-startup-finished", "");
+    TelemetryTimestamps.add("delayedStartupFinished");
+  },
+
+  onUnload: function() {
+    // In certain scenarios it's possible for unload to be fired before onload,
+    // (e.g. if the window is being closed after browser.js loads but before the
+    // load completes). In that case, there's nothing to do here.
+    if (!gStartupRan)
+      return;
+
+    if (!__lookupGetter__("InspectorUI"))
+      InspectorUI.destroy();
+
+    // First clean up services initialized in gBrowserInit.onLoad (or those whose
+    // uninit methods don't depend on the services having been initialized).
+    allTabs.uninit();
+
+    CombinedStopReload.uninit();
+
+    gGestureSupport.init(false);
+
+    FullScreen.cleanup();
+
+    Services.obs.removeObserver(gPluginHandler.pluginCrashed, "plugin-crashed");
+
+    try {
+      gBrowser.removeProgressListener(window.XULBrowserWindow);
+      gBrowser.removeTabsProgressListener(window.TabsProgressListener);
+    } catch (ex) {
+    }
+
+    PlacesStarButton.uninit();
+
+    gPrivateBrowsingUI.uninit();
+
+    TabsOnTop.uninit();
+
+    TabsInTitlebar.uninit();
+
+    var enumerator = Services.wm.getEnumerator(null);
+    enumerator.getNext();
+    if (!enumerator.hasMoreElements()) {
+      document.persist("sidebar-box", "sidebarcommand");
+      document.persist("sidebar-box", "width");
+      document.persist("sidebar-box", "src");
+      document.persist("sidebar-title", "value");
+    }
+
+    // Now either cancel delayedStartup, or clean up the services initialized from
+    // it.
+    if (gDelayedStartupTimeoutId) {
+      clearTimeout(gDelayedStartupTimeoutId);
+    } else {
+      if (Win7Features)
+        Win7Features.onCloseWindow();
+
+      gPrefService.removeObserver(ctrlTab.prefName, ctrlTab);
+      gPrefService.removeObserver(allTabs.prefName, allTabs);
+      ctrlTab.uninit();
+      TabView.uninit();
+      gBrowserThumbnails.uninit();
+      FullZoom.destroy();
+
+      Services.obs.removeObserver(gSessionHistoryObserver, "browser:purge-session-history");
+      Services.obs.removeObserver(gXPInstallObserver, "addon-install-disabled");
+      Services.obs.removeObserver(gXPInstallObserver, "addon-install-started");
+      Services.obs.removeObserver(gXPInstallObserver, "addon-install-blocked");
+      Services.obs.removeObserver(gXPInstallObserver, "addon-install-failed");
+      Services.obs.removeObserver(gXPInstallObserver, "addon-install-complete");
+      Services.obs.removeObserver(gFormSubmitObserver, "invalidformsubmit");
+
+      try {
+        gPrefService.removeObserver(gHomeButton.prefDomain, gHomeButton);
+      } catch (ex) {
+        Cu.reportError(ex);
+      }
+
+      BrowserOffline.uninit();
+      OfflineApps.uninit();
+      IndexedDBPromptHelper.uninit();
+      AddonManager.removeAddonListener(AddonsMgrListener);
+    }
+
+    // Final window teardown, do this last.
+    window.XULBrowserWindow.destroy();
+    window.XULBrowserWindow = null;
+    window.QueryInterface(Ci.nsIInterfaceRequestor)
+          .getInterface(Ci.nsIWebNavigation)
+          .QueryInterface(Ci.nsIDocShellTreeItem).treeOwner
+          .QueryInterface(Ci.nsIInterfaceRequestor)
+          .getInterface(Ci.nsIXULWindow)
+          .XULBrowserWindow = null;
+    window.QueryInterface(Ci.nsIDOMChromeWindow).browserDOMWindow = null;
+  },
+
+#ifdef XP_MACOSX
+  // nonBrowserWindowStartup(), nonBrowserWindowDelayedStartup(), and
+  // nonBrowserWindowShutdown() are used for non-browser windows in
+  // macBrowserOverlay
+  nonBrowserWindowStartup: function() {
+    // Disable inappropriate commands / submenus
+    var disabledItems = ['Browser:SavePage',
+                         'Browser:SendLink', 'cmd_pageSetup', 'cmd_print', 'cmd_find', 'cmd_findAgain',
+                         'viewToolbarsMenu', 'viewSidebarMenuMenu', 'Browser:Reload',
+                         'viewFullZoomMenu', 'pageStyleMenu', 'charsetMenu', 'View:PageSource', 'View:FullScreen',
+                         'viewHistorySidebar', 'Browser:AddBookmarkAs', 'Browser:BookmarkAllTabs',
+                         'View:PageInfo', 'Tasks:InspectPage', 'Browser:ToggleTabView', 'Browser:ToggleAddonBar'];
+    var element;
+
+    for (var id in disabledItems) {
+      element = document.getElementById(disabledItems[id]);
+      if (element)
+        element.setAttribute("disabled", "true");
+    }
+
+    // If no windows are active (i.e. we're the hidden window), disable the close, minimize
+    // and zoom menu commands as well
+    if (window.location.href == "chrome://browser/content/hiddenWindow.xul") {
+      var hiddenWindowDisabledItems = ['cmd_close', 'minimizeWindow', 'zoomWindow'];
+      for (var id in hiddenWindowDisabledItems) {
+        element = document.getElementById(hiddenWindowDisabledItems[id]);
+        if (element)
+          element.setAttribute("disabled", "true");
+      }
+
+      // also hide the window-list separator
+      element = document.getElementById("sep-window-list");
+      element.setAttribute("hidden", "true");
+
+      // Setup the dock menu.
+      let dockMenuElement = document.getElementById("menu_mac_dockmenu");
+      if (dockMenuElement != null) {
+        let nativeMenu = Cc["@mozilla.org/widget/standalonenativemenu;1"]
+                         .createInstance(Ci.nsIStandaloneNativeMenu);
+
+        try {
+          nativeMenu.init(dockMenuElement);
+
+          let dockSupport = Cc["@mozilla.org/widget/macdocksupport;1"]
+                            .getService(Ci.nsIMacDockSupport);
+          dockSupport.dockMenu = nativeMenu;
+        }
+        catch (e) {
+        }
+      }
+    }
+
+    gDelayedStartupTimeoutId = setTimeout(this.nonBrowserWindowDelayedStartup.bind(this), 0);
+  },
+
+  nonBrowserWindowDelayedStartup: function() {
+    gDelayedStartupTimeoutId = null;
+
+    // initialise the offline listener
+    BrowserOffline.init();
+
+    // Set up Sanitize Item
+    this._initializeSanitizer();
+
+    // initialize the private browsing UI
+    gPrivateBrowsingUI.init();
+
+#ifdef MOZ_SERVICES_SYNC
+    // initialize the sync UI
+    gSyncUI.init();
+#endif
+
+    gStartupRan = true;
+  },
+
+  nonBrowserWindowShutdown: function() {
+    // If nonBrowserWindowDelayedStartup hasn't run yet, we have no work to do -
+    // just cancel the pending timeout and return;
+    if (gDelayedStartupTimeoutId) {
+      clearTimeout(gDelayedStartupTimeoutId);
+      return;
+    }
+
+    BrowserOffline.uninit();
+
+    gPrivateBrowsingUI.uninit();
+  },
+#endif
+
+  _initializeSanitizer: function() {
+    const kDidSanitizeDomain = "privacy.sanitize.didShutdownSanitize";
+    if (gPrefService.prefHasUserValue(kDidSanitizeDomain)) {
+      gPrefService.clearUserPref(kDidSanitizeDomain);
+      // We need to persist this preference change, since we want to
+      // check it at next app start even if the browser exits abruptly
+      gPrefService.savePrefFile(null);
+    }
+
+    /**
+     * Migrate Firefox 3.0 privacy.item prefs under one of these conditions:
+     *
+     * a) User has customized any privacy.item prefs
+     * b) privacy.sanitize.sanitizeOnShutdown is set
+     */
+    if (!gPrefService.getBoolPref("privacy.sanitize.migrateFx3Prefs")) {
+      let itemBranch = gPrefService.getBranch("privacy.item.");
+      let itemArray = itemBranch.getChildList("");
+
+      // See if any privacy.item prefs are set
+      let doMigrate = itemArray.some(function (name) itemBranch.prefHasUserValue(name));
+      // Or if sanitizeOnShutdown is set
+      if (!doMigrate)
+        doMigrate = gPrefService.getBoolPref("privacy.sanitize.sanitizeOnShutdown");
+
+      if (doMigrate) {
+        let cpdBranch = gPrefService.getBranch("privacy.cpd.");
+        let clearOnShutdownBranch = gPrefService.getBranch("privacy.clearOnShutdown.");
+        itemArray.forEach(function (name) {
+          try {
+            // don't migrate password or offlineApps clearing in the CRH dialog since
+            // there's no UI for those anymore. They default to false. bug 497656
+            if (name != "passwords" && name != "offlineApps")
+              cpdBranch.setBoolPref(name, itemBranch.getBoolPref(name));
+            clearOnShutdownBranch.setBoolPref(name, itemBranch.getBoolPref(name));
+          }
+          catch(e) {
+            Cu.reportError("Exception thrown during privacy pref migration: " + e);
+          }
+        });
+      }
+
+      gPrefService.setBoolPref("privacy.sanitize.migrateFx3Prefs", true);
+    }
+  },
 }
 
+/* Legacy global init functions */
+var BrowserStartup        = gBrowserInit.onLoad.bind(gBrowserInit);
+var BrowserShutdown       = gBrowserInit.onUnload.bind(gBrowserInit);
+#ifdef XP_MACOSX
+var nonBrowserWindowStartup        = gBrowserInit.nonBrowserWindowStartup.bind(gBrowserInit);
+var nonBrowserWindowDelayedStartup = gBrowserInit.nonBrowserWindowDelayedStartup.bind(gBrowserInit);
+var nonBrowserWindowShutdown       = gBrowserInit.nonBrowserWindowShutdown.bind(gBrowserInit);
+#endif
+
+
 function HandleAppCommandEvent(evt) {
   evt.stopPropagation();
   switch (evt.command) {
   case "Back":
     BrowserBack();
     break;
   case "Forward":
     BrowserForward();
@@ -1176,654 +1796,16 @@ function HandleAppCommandEvent(evt) {
   case "Home":
     BrowserHome();
     break;
   default:
     break;
   }
 }
 
-function prepareForStartup() {
-  gBrowser.addEventListener("DOMUpdatePageReport", gPopupBlockerObserver, false);
-
-  gBrowser.addEventListener("PluginNotFound",     gPluginHandler, true);
-  gBrowser.addEventListener("PluginCrashed",      gPluginHandler, true);
-  gBrowser.addEventListener("PluginBlocklisted",  gPluginHandler, true);
-  gBrowser.addEventListener("PluginOutdated",     gPluginHandler, true);
-  gBrowser.addEventListener("PluginDisabled",     gPluginHandler, true);
-  gBrowser.addEventListener("PluginClickToPlay",  gPluginHandler, true);
-  gBrowser.addEventListener("NewPluginInstalled", gPluginHandler.newPluginInstalled, true);
-#ifdef XP_MACOSX
-  gBrowser.addEventListener("npapi-carbon-event-model-failure", gPluginHandler, true);
-#endif
-
-  Services.obs.addObserver(gPluginHandler.pluginCrashed, "plugin-crashed", false);
-
-  window.addEventListener("AppCommand", HandleAppCommandEvent, true);
-
-  var webNavigation;
-  try {
-    webNavigation = getWebNavigation();
-    if (!webNavigation)
-      throw "no XBL binding for browser";
-  } catch (e) {
-    alert("Error launching browser window:" + e);
-    window.close(); // Give up.
-    return;
-  }
-
-  messageManager.loadFrameScript("chrome://browser/content/content.js", true);
-
-  // initialize observers and listeners
-  // and give C++ access to gBrowser
-  gBrowser.init();
-  XULBrowserWindow.init();
-  window.QueryInterface(Ci.nsIInterfaceRequestor)
-        .getInterface(nsIWebNavigation)
-        .QueryInterface(Ci.nsIDocShellTreeItem).treeOwner
-        .QueryInterface(Ci.nsIInterfaceRequestor)
-        .getInterface(Ci.nsIXULWindow)
-        .XULBrowserWindow = window.XULBrowserWindow;
-  window.QueryInterface(Ci.nsIDOMChromeWindow).browserDOMWindow =
-    new nsBrowserAccess();
-
-  // set default character set if provided
-  if ("arguments" in window && window.arguments.length > 1 && window.arguments[1]) {
-    if (window.arguments[1].indexOf("charset=") != -1) {
-      var arrayArgComponents = window.arguments[1].split("=");
-      if (arrayArgComponents) {
-        //we should "inherit" the charset menu setting in a new window
-        getMarkupDocumentViewer().defaultCharacterSet = arrayArgComponents[1];
-      }
-    }
-  }
-
-  // Manually hook up session and global history for the first browser
-  // so that we don't have to load global history before bringing up a
-  // window.
-  // Wire up session and global history before any possible
-  // progress notifications for back/forward button updating
-  webNavigation.sessionHistory = Components.classes["@mozilla.org/browser/shistory;1"]
-                                           .createInstance(Components.interfaces.nsISHistory);
-  Services.obs.addObserver(gBrowser.browsers[0], "browser:purge-session-history", false);
-
-  // remove the disablehistory attribute so the browser cleans up, as
-  // though it had done this work itself
-  gBrowser.browsers[0].removeAttribute("disablehistory");
-
-  // enable global history
-  try {
-    gBrowser.docShell.QueryInterface(Components.interfaces.nsIDocShellHistory).useGlobalHistory = true;
-  } catch(ex) {
-    Components.utils.reportError("Places database may be locked: " + ex);
-  }
-
-#ifdef MOZ_E10S_COMPAT
-  // Bug 666801 - WebProgress support for e10s
-#else
-  // hook up UI through progress listener
-  gBrowser.addProgressListener(window.XULBrowserWindow);
-  gBrowser.addTabsProgressListener(window.TabsProgressListener);
-#endif
-
-  // setup our common DOMLinkAdded listener
-  gBrowser.addEventListener("DOMLinkAdded", DOMLinkHandler, false);
-
-  // setup our MozApplicationManifest listener
-  gBrowser.addEventListener("MozApplicationManifest",
-                            OfflineApps, false);
-
-  // setup simple gestures support
-  gGestureSupport.init(true);
-}
-
-function delayedStartup(isLoadingBlank, mustLoadSidebar) {
-  let tmp = {};
-  Cu.import("resource:///modules/TelemetryTimestamps.jsm", tmp);
-  let TelemetryTimestamps = tmp.TelemetryTimestamps;
-  TelemetryTimestamps.add("delayedStartupStarted");
-  gDelayedStartupTimeoutId = null;
-
-  Services.obs.addObserver(gSessionHistoryObserver, "browser:purge-session-history", false);
-  Services.obs.addObserver(gXPInstallObserver, "addon-install-disabled", false);
-  Services.obs.addObserver(gXPInstallObserver, "addon-install-started", false);
-  Services.obs.addObserver(gXPInstallObserver, "addon-install-blocked", false);
-  Services.obs.addObserver(gXPInstallObserver, "addon-install-failed", false);
-  Services.obs.addObserver(gXPInstallObserver, "addon-install-complete", false);
-  Services.obs.addObserver(gFormSubmitObserver, "invalidformsubmit", false);
-
-  BrowserOffline.init();
-  OfflineApps.init();
-  IndexedDBPromptHelper.init();
-  gFormSubmitObserver.init();
-  AddonManager.addAddonListener(AddonsMgrListener);
-
-  gBrowser.addEventListener("pageshow", function(evt) { setTimeout(pageShowEventHandlers, 0, evt); }, true);
-
-  // Ensure login manager is up and running.
-  Cc["@mozilla.org/login-manager;1"].getService(Ci.nsILoginManager);
-
-  if (mustLoadSidebar) {
-    let sidebar = document.getElementById("sidebar");
-    let sidebarBox = document.getElementById("sidebar-box");
-    sidebar.setAttribute("src", sidebarBox.getAttribute("src"));
-  }
-
-  UpdateUrlbarSearchSplitterState();
-
-  if (isLoadingBlank && gURLBar && isElementVisible(gURLBar))
-    gURLBar.focus();
-  else
-    gBrowser.selectedBrowser.focus();
-
-  gNavToolbox.customizeDone = BrowserToolboxCustomizeDone;
-  gNavToolbox.customizeChange = BrowserToolboxCustomizeChange;
-
-  // Set up Sanitize Item
-  initializeSanitizer();
-
-  // Enable/Disable auto-hide tabbar
-  gBrowser.tabContainer.updateVisibility();
-
-  gPrefService.addObserver(gHomeButton.prefDomain, gHomeButton, false);
-
-  var homeButton = document.getElementById("home-button");
-  gHomeButton.updateTooltip(homeButton);
-  gHomeButton.updatePersonalToolbarStyle(homeButton);
-
-  // BiDi UI
-  gBidiUI = isBidiEnabled();
-  if (gBidiUI) {
-    document.getElementById("documentDirection-separator").hidden = false;
-    document.getElementById("documentDirection-swap").hidden = false;
-    document.getElementById("textfieldDirection-separator").hidden = false;
-    document.getElementById("textfieldDirection-swap").hidden = false;
-  }
-
-  // Setup click-and-hold gestures access to the session history
-  // menus if global click-and-hold isn't turned on
-  if (!getBoolPref("ui.click_hold_context_menus", false))
-    SetClickAndHoldHandlers();
-
-  // Initialize the full zoom setting.
-  // We do this before the session restore service gets initialized so we can
-  // apply full zoom settings to tabs restored by the session restore service.
-  try {
-    FullZoom.init();
-  }
-  catch(ex) {
-    Components.utils.reportError("Failed to init content pref service:\n" + ex);
-  }
-
-#ifdef MOZ_E10S_COMPAT
-  // Bug 666804 - NetworkPrioritizer support for e10s
-#else
-  let NP = {};
-  Cu.import("resource:///modules/NetworkPrioritizer.jsm", NP);
-  NP.trackBrowserWindow(window);
-#endif
-
-  // initialize the session-restore service (in case it's not already running)
-  try {
-    Cc["@mozilla.org/browser/sessionstore;1"]
-      .getService(Ci.nsISessionStore)
-      .init(window);
-  } catch (ex) {
-    dump("nsSessionStore could not be initialized: " + ex + "\n");
-  }
-
-  PlacesToolbarHelper.init();
-
-  ctrlTab.readPref();
-  gPrefService.addObserver(ctrlTab.prefName, ctrlTab, false);
-  gPrefService.addObserver(allTabs.prefName, allTabs, false);
-
-  // Initialize the download manager some time after the app starts so that
-  // auto-resume downloads begin (such as after crashing or quitting with
-  // active downloads) and speeds up the first-load of the download manager UI.
-  // If the user manually opens the download manager before the timeout, the
-  // downloads will start right away, and getting the service again won't hurt.
-  setTimeout(function() {
-    gDownloadMgr = Cc["@mozilla.org/download-manager;1"].
-                   getService(Ci.nsIDownloadManager);
-
-#ifdef XP_WIN
-    if (Win7Features) {
-      let tempScope = {};
-      Cu.import("resource://gre/modules/DownloadTaskbarProgress.jsm",
-                tempScope);
-      tempScope.DownloadTaskbarProgress.onBrowserWindowLoad(window);
-    }
-#endif
-  }, 10000);
-
-  // The object handling the downloads indicator is also initialized here in the
-  // delayed startup function, but the actual indicator element is not loaded
-  // unless there are downloads to be displayed.
-  DownloadsButton.initializeIndicator();
-
-#ifndef XP_MACOSX
-  updateEditUIVisibility();
-  let placesContext = document.getElementById("placesContext");
-  placesContext.addEventListener("popupshowing", updateEditUIVisibility, false);
-  placesContext.addEventListener("popuphiding", updateEditUIVisibility, false);
-#endif
-
-  gBrowser.mPanelContainer.addEventListener("InstallBrowserTheme", LightWeightThemeWebInstaller, false, true);
-  gBrowser.mPanelContainer.addEventListener("PreviewBrowserTheme", LightWeightThemeWebInstaller, false, true);
-  gBrowser.mPanelContainer.addEventListener("ResetBrowserThemePreview", LightWeightThemeWebInstaller, false, true);
-
-#ifdef MOZ_E10S_COMPAT
-  // Bug 666808 - AeroPeek support for e10s
-#else
-  if (Win7Features)
-    Win7Features.onOpenWindow();
-#endif
-
-  // called when we go into full screen, even if it is
-  // initiated by a web page script
-  window.addEventListener("fullscreen", onFullScreen, true);
-
-  // Called when we enter DOM full-screen mode. Note we can already be in browser
-  // full-screen mode when we enter DOM full-screen mode.
-  window.addEventListener("MozEnteredDomFullscreen", onMozEnteredDomFullscreen, true);
-
-  if (window.fullScreen)
-    onFullScreen();
-  if (document.mozFullScreen)
-    onMozEnteredDomFullscreen();
-
-#ifdef MOZ_SERVICES_SYNC
-  // initialize the sync UI
-  gSyncUI.init();
-#endif
-
-  gBrowserThumbnails.init();
-  TabView.init();
-
-  setUrlAndSearchBarWidthForConditionalForwardButton();
-  window.addEventListener("resize", function resizeHandler(event) {
-    if (event.target == window)
-      setUrlAndSearchBarWidthForConditionalForwardButton();
-  });
-
-  // Enable developer toolbar?
-  let devToolbarEnabled = gPrefService.getBoolPref("devtools.toolbar.enabled");
-  if (devToolbarEnabled) {
-    document.getElementById("menu_devToolbar").hidden = false;
-    document.getElementById("Tools:DevToolbar").removeAttribute("disabled");
-#ifdef MENUBAR_CAN_AUTOHIDE
-    document.getElementById("appmenu_devToolbar").hidden = false;
-#endif
-  }
-
-  // Enable Inspector?
-  let enabled = gPrefService.getBoolPref("devtools.inspector.enabled");
-  if (enabled) {
-    document.getElementById("menu_pageinspect").hidden = false;
-    document.getElementById("Tools:Inspect").removeAttribute("disabled");
-#ifdef MENUBAR_CAN_AUTOHIDE
-    document.getElementById("appmenu_pageInspect").hidden = false;
-#endif
-    document.getElementById("developer-toolbar-inspector").hidden = false;
-  }
-
-  // Enable Debugger?
-  let enabled = gPrefService.getBoolPref("devtools.debugger.enabled");
-  if (enabled) {
-    document.getElementById("menu_debugger").hidden = false;
-    document.getElementById("Tools:Debugger").removeAttribute("disabled");
-#ifdef MENUBAR_CAN_AUTOHIDE
-    document.getElementById("appmenu_debugger").hidden = false;
-#endif
-    document.getElementById("developer-toolbar-debugger").hidden = false;
-  }
-
-  // Enable Remote Debugger?
-  let enabled = gPrefService.getBoolPref("devtools.debugger.remote-enabled");
-  if (enabled) {
-    document.getElementById("menu_remoteDebugger").hidden = false;
-    document.getElementById("Tools:RemoteDebugger").removeAttribute("disabled");
-#ifdef MENUBAR_CAN_AUTOHIDE
-    document.getElementById("appmenu_remoteDebugger").hidden = false;
-#endif
-  }
-
-  // Enable Chrome Debugger?
-  let enabled = gPrefService.getBoolPref("devtools.chrome.enabled") &&
-                gPrefService.getBoolPref("devtools.debugger.chrome-enabled") &&
-                gPrefService.getBoolPref("devtools.debugger.remote-enabled");
-  if (enabled) {
-    document.getElementById("menu_chromeDebugger").hidden = false;
-    document.getElementById("Tools:ChromeDebugger").removeAttribute("disabled");
-#ifdef MENUBAR_CAN_AUTOHIDE
-    document.getElementById("appmenu_chromeDebugger").hidden = false;
-#endif
-  }
-
-  // Enable Error Console?
-  // XXX Temporarily always-enabled, see bug 601201
-  let consoleEnabled = true || gPrefService.getBoolPref("devtools.errorconsole.enabled");
-  if (consoleEnabled) {
-    document.getElementById("javascriptConsole").hidden = false;
-    document.getElementById("key_errorConsole").removeAttribute("disabled");
-#ifdef MENUBAR_CAN_AUTOHIDE
-    document.getElementById("appmenu_errorConsole").hidden = false;
-#endif
-  }
-
-  // Enable Scratchpad in the UI, if the preference allows this.
-  let scratchpadEnabled = gPrefService.getBoolPref(Scratchpad.prefEnabledName);
-  if (scratchpadEnabled) {
-    document.getElementById("menu_scratchpad").hidden = false;
-    document.getElementById("Tools:Scratchpad").removeAttribute("disabled");
-#ifdef MENUBAR_CAN_AUTOHIDE
-    document.getElementById("appmenu_scratchpad").hidden = false;
-#endif
-  }
-
-  // Enable Style Editor?
-  let styleEditorEnabled = gPrefService.getBoolPref(StyleEditor.prefEnabledName);
-  if (styleEditorEnabled) {
-    document.getElementById("menu_styleeditor").hidden = false;
-    document.getElementById("Tools:StyleEditor").removeAttribute("disabled");
-#ifdef MENUBAR_CAN_AUTOHIDE
-    document.getElementById("appmenu_styleeditor").hidden = false;
-#endif
-  }
-
-#ifdef MENUBAR_CAN_AUTOHIDE
-  // If the user (or the locale) hasn't enabled the top-level "Character
-  // Encoding" menu via the "browser.menu.showCharacterEncoding" preference,
-  // hide it.
-  if ("true" != gPrefService.getComplexValue("browser.menu.showCharacterEncoding",
-                                             Ci.nsIPrefLocalizedString).data)
-    document.getElementById("appmenu_charsetMenu").hidden = true;
-#endif
-
-  // Enable Responsive UI?
-  let responsiveUIEnabled = gPrefService.getBoolPref("devtools.responsiveUI.enabled");
-  if (responsiveUIEnabled) {
-    document.getElementById("menu_responsiveUI").hidden = false;
-    document.getElementById("Tools:ResponsiveUI").removeAttribute("disabled");
-#ifdef MENUBAR_CAN_AUTOHIDE
-    document.getElementById("appmenu_responsiveUI").hidden = false;
-#endif
-    document.getElementById("developer-toolbar-responsiveui").hidden = false;
-  }
-
-  let appMenuButton = document.getElementById("appmenu-button");
-  let appMenuPopup = document.getElementById("appmenu-popup");
-  if (appMenuButton && appMenuPopup) {
-    let appMenuOpening = null;
-    appMenuButton.addEventListener("mousedown", function(event) {
-      if (event.button == 0)
-        appMenuOpening = new Date();
-    }, false);
-    appMenuPopup.addEventListener("popupshown", function(event) {
-      if (event.target != appMenuPopup || !appMenuOpening)
-        return;
-      let duration = new Date() - appMenuOpening;
-      appMenuOpening = null;
-      Services.telemetry.getHistogramById("FX_APP_MENU_OPEN_MS").add(duration);
-    }, false);
-  }
-
-  window.addEventListener("mousemove", MousePosTracker, false);
-  window.addEventListener("dragover", MousePosTracker, false);
-
-  // End startup crash tracking after a delay to catch crashes while restoring
-  // tabs and to postpone saving the pref to disk.
-  try {
-    let appStartup = Cc["@mozilla.org/toolkit/app-startup;1"].
-                     getService(Ci.nsIAppStartup);
-    const startupCrashEndDelay = 30 * 1000;
-    setTimeout(appStartup.trackStartupCrashEnd, startupCrashEndDelay);
-  } catch (ex) {
-    Cu.reportError("Could not end startup crash tracking: " + ex);
-  }
-
-  Services.obs.notifyObservers(window, "browser-delayed-startup-finished", "");
-  TelemetryTimestamps.add("delayedStartupFinished");
-}
-
-function BrowserShutdown() {
-  // In certain scenarios it's possible for unload to be fired before onload,
-  // (e.g. if the window is being closed after browser.js loads but before the
-  // load completes). In that case, there's nothing to do here.
-  if (!gStartupRan)
-    return;
-
-  if (!__lookupGetter__("InspectorUI"))
-    InspectorUI.destroy();
-
-  // First clean up services initialized in BrowserStartup (or those whose
-  // uninit methods don't depend on the services having been initialized).
-  allTabs.uninit();
-
-  CombinedStopReload.uninit();
-
-  gGestureSupport.init(false);
-
-  FullScreen.cleanup();
-
-  Services.obs.removeObserver(gPluginHandler.pluginCrashed, "plugin-crashed");
-
-  try {
-    gBrowser.removeProgressListener(window.XULBrowserWindow);
-    gBrowser.removeTabsProgressListener(window.TabsProgressListener);
-  } catch (ex) {
-  }
-
-  PlacesStarButton.uninit();
-
-  gPrivateBrowsingUI.uninit();
-
-  TabsOnTop.uninit();
-
-  TabsInTitlebar.uninit();
-
-  var enumerator = Services.wm.getEnumerator(null);
-  enumerator.getNext();
-  if (!enumerator.hasMoreElements()) {
-    document.persist("sidebar-box", "sidebarcommand");
-    document.persist("sidebar-box", "width");
-    document.persist("sidebar-box", "src");
-    document.persist("sidebar-title", "value");
-  }
-
-  // Now either cancel delayedStartup, or clean up the services initialized from
-  // it.
-  if (gDelayedStartupTimeoutId) {
-    clearTimeout(gDelayedStartupTimeoutId);
-  } else {
-    if (Win7Features)
-      Win7Features.onCloseWindow();
-
-    gPrefService.removeObserver(ctrlTab.prefName, ctrlTab);
-    gPrefService.removeObserver(allTabs.prefName, allTabs);
-    ctrlTab.uninit();
-    TabView.uninit();
-    gBrowserThumbnails.uninit();
-
-    try {
-      FullZoom.destroy();
-    }
-    catch(ex) {
-      Components.utils.reportError(ex);
-    }
-
-    Services.obs.removeObserver(gSessionHistoryObserver, "browser:purge-session-history");
-    Services.obs.removeObserver(gXPInstallObserver, "addon-install-disabled");
-    Services.obs.removeObserver(gXPInstallObserver, "addon-install-started");
-    Services.obs.removeObserver(gXPInstallObserver, "addon-install-blocked");
-    Services.obs.removeObserver(gXPInstallObserver, "addon-install-failed");
-    Services.obs.removeObserver(gXPInstallObserver, "addon-install-complete");
-    Services.obs.removeObserver(gFormSubmitObserver, "invalidformsubmit");
-
-    try {
-      gPrefService.removeObserver(gHomeButton.prefDomain, gHomeButton);
-    } catch (ex) {
-      Components.utils.reportError(ex);
-    }
-
-    BrowserOffline.uninit();
-    OfflineApps.uninit();
-    IndexedDBPromptHelper.uninit();
-    AddonManager.removeAddonListener(AddonsMgrListener);
-  }
-
-  // Final window teardown, do this last.
-  window.XULBrowserWindow.destroy();
-  window.XULBrowserWindow = null;
-  window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
-        .getInterface(Components.interfaces.nsIWebNavigation)
-        .QueryInterface(Components.interfaces.nsIDocShellTreeItem).treeOwner
-        .QueryInterface(Components.interfaces.nsIInterfaceRequestor)
-        .getInterface(Components.interfaces.nsIXULWindow)
-        .XULBrowserWindow = null;
-  window.QueryInterface(Ci.nsIDOMChromeWindow).browserDOMWindow = null;
-}
-
-#ifdef XP_MACOSX
-// nonBrowserWindowStartup(), nonBrowserWindowDelayedStartup(), and
-// nonBrowserWindowShutdown() are used for non-browser windows in
-// macBrowserOverlay
-function nonBrowserWindowStartup() {
-  // Disable inappropriate commands / submenus
-  var disabledItems = ['Browser:SavePage',
-                       'Browser:SendLink', 'cmd_pageSetup', 'cmd_print', 'cmd_find', 'cmd_findAgain',
-                       'viewToolbarsMenu', 'viewSidebarMenuMenu', 'Browser:Reload',
-                       'viewFullZoomMenu', 'pageStyleMenu', 'charsetMenu', 'View:PageSource', 'View:FullScreen',
-                       'viewHistorySidebar', 'Browser:AddBookmarkAs', 'Browser:BookmarkAllTabs',
-                       'View:PageInfo', 'Tasks:InspectPage', 'Browser:ToggleTabView', 'Browser:ToggleAddonBar'];
-  var element;
-
-  for (var id in disabledItems) {
-    element = document.getElementById(disabledItems[id]);
-    if (element)
-      element.setAttribute("disabled", "true");
-  }
-
-  // If no windows are active (i.e. we're the hidden window), disable the close, minimize
-  // and zoom menu commands as well
-  if (window.location.href == "chrome://browser/content/hiddenWindow.xul") {
-    var hiddenWindowDisabledItems = ['cmd_close', 'minimizeWindow', 'zoomWindow'];
-    for (var id in hiddenWindowDisabledItems) {
-      element = document.getElementById(hiddenWindowDisabledItems[id]);
-      if (element)
-        element.setAttribute("disabled", "true");
-    }
-
-    // also hide the window-list separator
-    element = document.getElementById("sep-window-list");
-    element.setAttribute("hidden", "true");
-
-    // Setup the dock menu.
-    let dockMenuElement = document.getElementById("menu_mac_dockmenu");
-    if (dockMenuElement != null) {
-      let nativeMenu = Cc["@mozilla.org/widget/standalonenativemenu;1"]
-                       .createInstance(Ci.nsIStandaloneNativeMenu);
-
-      try {
-        nativeMenu.init(dockMenuElement);
-
-        let dockSupport = Cc["@mozilla.org/widget/macdocksupport;1"]
-                          .getService(Ci.nsIMacDockSupport);
-        dockSupport.dockMenu = nativeMenu;
-      }
-      catch (e) {
-      }
-    }
-  }
-
-  gDelayedStartupTimeoutId = setTimeout(nonBrowserWindowDelayedStartup, 0);
-}
-
-function nonBrowserWindowDelayedStartup() {
-  gDelayedStartupTimeoutId = null;
-
-  // initialise the offline listener
-  BrowserOffline.init();
-
-  // Set up Sanitize Item
-  initializeSanitizer();
-
-  // initialize the private browsing UI
-  gPrivateBrowsingUI.init();
-
-#ifdef MOZ_SERVICES_SYNC
-  // initialize the sync UI
-  gSyncUI.init();
-#endif
-
-  gStartupRan = true;
-}
-
-function nonBrowserWindowShutdown() {
-  // If nonBrowserWindowDelayedStartup hasn't run yet, we have no work to do -
-  // just cancel the pending timeout and return;
-  if (gDelayedStartupTimeoutId) {
-    clearTimeout(gDelayedStartupTimeoutId);
-    return;
-  }
-
-  BrowserOffline.uninit();
-
-  gPrivateBrowsingUI.uninit();
-}
-#endif
-
-function initializeSanitizer()
-{
-  const kDidSanitizeDomain = "privacy.sanitize.didShutdownSanitize";
-  if (gPrefService.prefHasUserValue(kDidSanitizeDomain)) {
-    gPrefService.clearUserPref(kDidSanitizeDomain);
-    // We need to persist this preference change, since we want to
-    // check it at next app start even if the browser exits abruptly
-    gPrefService.savePrefFile(null);
-  }
-
-  /**
-   * Migrate Firefox 3.0 privacy.item prefs under one of these conditions:
-   *
-   * a) User has customized any privacy.item prefs
-   * b) privacy.sanitize.sanitizeOnShutdown is set
-   */
-  if (!gPrefService.getBoolPref("privacy.sanitize.migrateFx3Prefs")) {
-    let itemBranch = gPrefService.getBranch("privacy.item.");
-    let itemArray = itemBranch.getChildList("");
-
-    // See if any privacy.item prefs are set
-    let doMigrate = itemArray.some(function (name) itemBranch.prefHasUserValue(name));
-    // Or if sanitizeOnShutdown is set
-    if (!doMigrate)
-      doMigrate = gPrefService.getBoolPref("privacy.sanitize.sanitizeOnShutdown");
-
-    if (doMigrate) {
-      let cpdBranch = gPrefService.getBranch("privacy.cpd.");
-      let clearOnShutdownBranch = gPrefService.getBranch("privacy.clearOnShutdown.");
-      itemArray.forEach(function (name) {
-        try {
-          // don't migrate password or offlineApps clearing in the CRH dialog since
-          // there's no UI for those anymore. They default to false. bug 497656
-          if (name != "passwords" && name != "offlineApps")
-            cpdBranch.setBoolPref(name, itemBranch.getBoolPref(name));
-          clearOnShutdownBranch.setBoolPref(name, itemBranch.getBoolPref(name));
-        }
-        catch(e) {
-          Cu.reportError("Exception thrown during privacy pref migration: " + e);
-        }
-      });
-    }
-
-    gPrefService.setBoolPref("privacy.sanitize.migrateFx3Prefs", true);
-  }
-}
-
 function gotoHistoryIndex(aEvent) {
   let index = aEvent.target.getAttribute("index");
   if (!index)
     return false;
 
   let where = whereToOpenLink(aEvent);
 
   if (where == "current") {
@@ -1892,24 +1874,19 @@ function BrowserHandleShiftBackspace()
     BrowserForward();
     break;
   case 1:
     goDoCommand("cmd_scrollPageDown");
     break;
   }
 }
 
-function BrowserStop()
-{
-  try {
-    const stopFlags = nsIWebNavigation.STOP_ALL;
-    getWebNavigation().stop(stopFlags);
-  }
-  catch(ex) {
-  }
+function BrowserStop() {
+  const stopFlags = nsIWebNavigation.STOP_ALL;
+  gBrowser.webNavigation.stop(stopFlags);
 }
 
 function BrowserReloadOrDuplicate(aEvent) {
   var backgroundTabModifier = aEvent.button == 1 ||
 #ifdef XP_MACOSX
     aEvent.metaKey;
 #else
     aEvent.ctrlKey;
@@ -2042,17 +2019,17 @@ function BrowserOpenTab()
    its opener to open a new window and then step completely out of the way.
    Anything less byzantine is causing horrible crashes, rather believably,
    though oddly only on Linux. */
 function delayedOpenWindow(chrome, flags, href, postData)
 {
   // The other way to use setTimeout,
   // setTimeout(openDialog, 10, chrome, "_blank", flags, url),
   // doesn't work here.  The extra "magic" extra argument setTimeout adds to
-  // the callback function would confuse prepareForStartup() by making
+  // the callback function would confuse gBrowserInit.onLoad() by making
   // window.arguments[1] be an integer instead of null.
   setTimeout(function() { openDialog(chrome, "_blank", flags, href, null, null, postData); }, 10);
 }
 
 /* Required because the tab needs time to set up its content viewers and get the load of
    the URI kicked off before becoming the active content area. */
 function delayedOpenTab(aUrl, aReferrer, aCharset, aPostData, aAllowThirdPartyFixup)
 {
@@ -2307,17 +2284,17 @@ function BrowserViewSourceOfDocument(aDo
         win = content;
       }
       ifRequestor = win.QueryInterface(Components.interfaces.nsIInterfaceRequestor);
 
       webNav = ifRequestor.getInterface(nsIWebNavigation);
   } catch(err) {
       // If nsIWebNavigation cannot be found, just get the one for the whole
       // window...
-      webNav = getWebNavigation();
+      webNav = gBrowser.webNavigation;
   }
   //
   // Get the 'PageDescriptor' for the current document. This allows the
   // view-source to access the cached copy of the content rather than
   // refetching it from the network...
   //
   try{
     var PageLoader = webNav.QueryInterface(Components.interfaces.nsIWebPageDescriptor);
@@ -2356,17 +2333,17 @@ function BrowserPageInfo(doc, initialTab
                     "chrome,toolbar,dialog=no,resizable", args);
 }
 
 function URLBarSetURI(aURI) {
   var value = gBrowser.userTypedValue;
   var valid = false;
 
   if (value == null) {
-    let uri = aURI || getWebNavigation().currentURI;
+    let uri = aURI || gBrowser.currentURI;
 
     // Replace initial page URIs with an empty string
     // only if there's no opener (bug 370555).
     if (gInitialPages.indexOf(uri.spec) != -1)
       value = content.opener ? uri.spec : "";
     else
       value = losslessDecodeURI(uri);
 
@@ -2701,31 +2678,27 @@ function onFullScreen(event) {
 }
 
 function onMozEnteredDomFullscreen(event) {
   FullScreen.enterDomFullscreen(event);
 }
 
 function getWebNavigation()
 {
-  try {
-    return gBrowser.webNavigation;
-  } catch (e) {
-    return null;
-  }
+  return gBrowser.webNavigation;
 }
 
 function BrowserReloadWithFlags(reloadFlags) {
   /* First, we'll try to use the session history object to reload so
    * that framesets are handled properly. If we're in a special
    * window (such as view-source) that has no session history, fall
    * back on using the web navigation's reload method.
    */
 
-  var webNav = getWebNavigation();
+  var webNav = gBrowser.webNavigation;
   try {
     var sh = webNav.sessionHistory;
     if (sh)
       webNav = sh.QueryInterface(nsIWebNavigation);
   } catch (e) {
   }
 
   try {
@@ -3348,17 +3321,17 @@ function FillHistoryMenu(aParent) {
 
   // Remove old entries if any
   var children = aParent.childNodes;
   for (var i = children.length - 1; i >= 0; --i) {
     if (children[i].hasAttribute("index"))
       aParent.removeChild(children[i]);
   }
 
-  var webNav = getWebNavigation();
+  var webNav = gBrowser.webNavigation;
   var sessionHistory = webNav.sessionHistory;
 
   var count = sessionHistory.count;
   if (count <= 1) // don't display the popup for a single item
     return false;
 
   const MAX_HISTORY_MENU_ITEMS = 15;
   var index = sessionHistory.index;
@@ -4517,17 +4490,17 @@ nsBrowserAccess.prototype = {
         aWhere = gPrefService.getIntPref("browser.link.open_newwindow.override.external");
       else
         aWhere = gPrefService.getIntPref("browser.link.open_newwindow");
     }
     switch (aWhere) {
       case Ci.nsIBrowserDOMWindow.OPEN_NEWWINDOW :
         // FIXME: Bug 408379. So how come this doesn't send the
         // referrer like the other loads do?
-        var url = aURI ? aURI.spec : BROWSER_NEW_TAB_URL;
+        var url = aURI ? aURI.spec : "about:blank";
         // Pass all params to openDialog to ensure that "url" isn't passed through
         // loadOneOrMoreURIs, which splits based on "|"
         newWindow = openDialog(getBrowserURL(), "_blank", "all,dialog=no", url, null, null, null);
         break;
       case Ci.nsIBrowserDOMWindow.OPEN_NEWTAB :
         let win, needToFocusWin;
 
         // try the current window.  if we're in a popup, fall back on the most recent browser window
@@ -4550,17 +4523,17 @@ nsBrowserAccess.prototype = {
           win.focus();
           newWindow = win.content;
           break;
         }
 
         let loadInBackground = gPrefService.getBoolPref("browser.tabs.loadDivertedInBackground");
         let referrer = aOpener ? makeURI(aOpener.location.href) : null;
 
-        let tab = win.gBrowser.loadOneTab(aURI ? aURI.spec : BROWSER_NEW_TAB_URL, {
+        let tab = win.gBrowser.loadOneTab(aURI ? aURI.spec : "about:blank", {
                                           referrerURI: referrer,
                                           fromExternal: isExternal,
                                           inBackground: loadInBackground});
         let browser = win.gBrowser.getBrowserForTab(tab);
 
         newWindow = browser.contentWindow;
         if (needToFocusWin || (!loadInBackground && isExternal))
           newWindow.focus();
@@ -4922,17 +4895,17 @@ function toggleSidebar(commandID, forceO
   var title = sidebarBroadcaster.getAttribute("sidebartitle");
   if (!title)
     title = sidebarBroadcaster.getAttribute("label");
   sidebar.setAttribute("src", url); // kick off async load
   sidebarBox.setAttribute("sidebarcommand", sidebarBroadcaster.id);
   sidebarTitle.value = title;
 
   // We set this attribute here in addition to setting it on the <browser>
-  // element itself, because the code in BrowserShutdown persists this
+  // element itself, because the code in gBrowserInit.onUnload persists this
   // attribute, not the "src" of the <browser id="sidebar">. The reason it
   // does that is that we want to delay sidebar load a bit when a browser
   // window opens. See delayedStartup().
   sidebarBox.setAttribute("src", url);
 
   if (sidebar.contentDocument.location.href != url)
     sidebar.addEventListener("load", sidebarOnLoad, true);
   else // older code handled this case, so we do it too
@@ -5342,17 +5315,17 @@ function SelectDetector(event, doReload)
         dump("Failed to set the intl.charset.detector preference.\n");
     }
 }
 
 function BrowserSetForcedCharacterSet(aCharset)
 {
   gBrowser.docShell.charset = aCharset;
   // Save the forced character-set
-  PlacesUtils.history.setCharsetForURI(getWebNavigation().currentURI, aCharset);
+  PlacesUtils.history.setCharsetForURI(gBrowser.currentURI, aCharset);
   BrowserCharsetReload();
 }
 
 function BrowserCharsetReload()
 {
   BrowserReloadWithFlags(nsIWebNavigation.LOAD_FLAGS_CHARSET_CHANGE);
 }
 
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -19,17 +19,17 @@
 # All DTD information is stored in a separate file so that it can be shared by
 # hiddenWindow.xul.
 #include browser-doctype.inc
 
 <window id="main-window"
         xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
         xmlns:svg="http://www.w3.org/2000/svg"
         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
-        onload="BrowserStartup()" onunload="BrowserShutdown()" onclose="return WindowIsClosing();"
+        onload="gBrowserInit.onLoad()" onunload="gBrowserInit.onUnload()" onclose="return WindowIsClosing();"
         title="&mainWindow.title;@PRE_RELEASE_SUFFIX@"
         title_normal="&mainWindow.title;@PRE_RELEASE_SUFFIX@"
 #ifdef XP_MACOSX
         title_privatebrowsing="&mainWindow.title;@PRE_RELEASE_SUFFIX@&mainWindow.titlemodifiermenuseparator;&mainWindow.titlePrivateBrowsingSuffix;"
         titledefault="&mainWindow.title;@PRE_RELEASE_SUFFIX@"
         titlemodifier=""
         titlemodifier_normal=""
         titlemodifier_privatebrowsing="&mainWindow.titlePrivateBrowsingSuffix;"
--- a/browser/base/content/macBrowserOverlay.xul
+++ b/browser/base/content/macBrowserOverlay.xul
@@ -29,18 +29,18 @@
   function OpenBrowserWindowFromDockMenu() {
     let dockSupport = Cc["@mozilla.org/widget/macdocksupport;1"]
                       .getService(Ci.nsIMacDockSupport);
     dockSupport.activateApplication(true);
 
     return OpenBrowserWindow();
   }
 
-  addEventListener("load", nonBrowserWindowStartup, false);
-  addEventListener("unload", nonBrowserWindowShutdown, false);
+  addEventListener("load",   function() { gBrowserInit.nonBrowserWindowStartup()  }, false);
+  addEventListener("unload", function() { gBrowserInit.nonBrowserWindowShutdown() }, false);
 </script>
 
 # All sets except for popupsets (commands, keys, stringbundles and broadcasters) *must* go into the 
 # browser-sets.inc file for sharing with hiddenWindow.xul.
 #include browser-sets.inc
 
 # The entire main menubar is placed into browser-menubar.inc, so that it can be shared by 
 # hiddenWindow.xul.
--- a/browser/base/content/test/browser_bug743421.js
+++ b/browser/base/content/test/browser_bug743421.js
@@ -37,36 +37,39 @@ function prepareTest(nextTest, url) {
 }
 
 // Tests that navigation within the page and the window.history API doesn't break click-to-play state.
 function test1a() {
   var popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
   ok(!popupNotification, "Test 1a, Should not have a click-to-play notification");
   var plugin = gTestBrowser.contentWindow.addPlugin();
 
-  setTimeout(test1b, 500);
+  var condition = function() PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
+  waitForCondition(condition, test1b, "Test 1a, Waited too long for plugin notification");
 }
 
 function test1b() {
   var popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
   ok(popupNotification, "Test 1b, Should have a click-to-play notification");
   var plugin = gTestBrowser.contentDocument.getElementsByTagName("embed")[0];
   var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
   ok(!objLoadingContent.activated, "Test 1b, Plugin should not be activated");
 
   popupNotification.mainAction.callback();
-  setTimeout(test1c, 500);
+  test1c();
 }
 
 function test1c() {
   var popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
   ok(!popupNotification, "Test 1c, Should not have a click-to-play notification");
   var plugin = gTestBrowser.contentWindow.addPlugin();
 
-  setTimeout(test1d, 500);
+  var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
+  var condition = function() objLoadingContent.activated;
+  waitForCondition(condition, test1d, "Test 1c, Waited too long for plugin activation");
 }
 
 function test1d() {
   var popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
   ok(!popupNotification, "Test 1d, Should not have a click-to-play notification");
   var plugin = gTestBrowser.contentDocument.getElementsByTagName("embed")[1];
   var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
   ok(objLoadingContent.activated, "Test 1d, Plugin should be activated");
@@ -77,29 +80,33 @@ function test1d() {
 }
 
 function test1e() {
   gTestBrowser.contentWindow.removeEventListener("hashchange", test1e, false);
   var popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
   ok(!popupNotification, "Test 1e, Should not have a click-to-play notification");
   var plugin = gTestBrowser.contentWindow.addPlugin();
 
-  setTimeout(test1f, 500);
+  var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
+  var condition = function() objLoadingContent.activated;
+  waitForCondition(condition, test1f, "Test 1e, Waited too long for plugin activation");
 }
 
 function test1f() {
   var popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
   ok(!popupNotification, "Test 1f, Should not have a click-to-play notification");
   var plugin = gTestBrowser.contentDocument.getElementsByTagName("embed")[2];
   var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
   ok(objLoadingContent.activated, "Test 1f, Plugin should be activated");
 
   gTestBrowser.contentWindow.history.replaceState({}, "", "replacedState");
-  gTestBrowser.contentWindow.addPlugin();
-  setTimeout(test1g, 500);
+  var plugin = gTestBrowser.contentWindow.addPlugin();
+  var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
+  var condition = function() objLoadingContent.activated;
+  waitForCondition(condition, test1g, "Test 1f, Waited too long for plugin activation");
 }
 
 function test1g() {
   var popupNotification2 = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
   ok(!popupNotification2, "Test 1g, Should not have a click-to-play notification after replaceState");
   var plugin = gTestBrowser.contentDocument.getElementsByTagName("embed")[3];
   var objLoadingContent2 = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
   ok(objLoadingContent2.activated, "Test 1g, Plugin should be activated");
--- a/browser/base/content/test/browser_pluginnotification.js
+++ b/browser/base/content/test/browser_pluginnotification.js
@@ -208,31 +208,16 @@ function test8() {
   ok(!notificationBox.getNotificationWithValue("missing-plugins"), "Test 8, Should not have displayed the missing plugin notification");
   ok(!notificationBox.getNotificationWithValue("blocked-plugins"), "Test 8, Should not have displayed the blocked plugin notification");
   ok(!gTestBrowser.missingPlugins, "Test 8, Should not be a missing plugin list");
   ok(PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser), "Test 8, Should have a click-to-play notification");
 
   prepareTest(test9a, gTestRoot + "plugin_test2.html");
 }
 
-function waitForCondition(condition, nextTest, errorMsg) {
-  var tries = 0;
-  var interval = setInterval(function() {
-    if (tries >= 500) {
-      ok(false, errorMsg);
-      moveOn();
-    }
-    if (condition()) {
-      moveOn();
-    }
-    tries++;
-  }, 10);
-  var moveOn = function() { clearInterval(interval); nextTest(); };
-}
-
 // Tests that activating one click-to-play plugin will activate only that plugin (part 1/3)
 function test9a() {
   var notificationBox = gBrowser.getNotificationBox(gTestBrowser);
   ok(!notificationBox.getNotificationWithValue("missing-plugins"), "Test 9a, Should not have displayed the missing plugin notification");
   ok(!notificationBox.getNotificationWithValue("blocked-plugins"), "Test 9a, Should not have displayed the blocked plugin notification");
   ok(!gTestBrowser.missingPlugins, "Test 9a, Should not be a missing plugin list");
   ok(PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser), "Test 9a, Should have a click-to-play notification");
 
--- a/browser/base/content/test/head.js
+++ b/browser/base/content/test/head.js
@@ -67,8 +67,23 @@ function closeToolbarCustomizationUI(aCa
     win.removeEventListener("unload", unloaded);
     executeSoon(aCallback);
   });
 
   let button = win.document.getElementById("donebutton");
   button.focus();
   button.doCommand();
 }
+
+function waitForCondition(condition, nextTest, errorMsg) {
+  var tries = 0;
+  var interval = setInterval(function() {
+    if (tries >= 30) {
+      ok(false, errorMsg);
+      moveOn();
+    }
+    if (condition()) {
+      moveOn();
+    }
+    tries++;
+  }, 100);
+  var moveOn = function() { clearInterval(interval); nextTest(); };
+}
--- a/browser/components/build/nsModule.cpp
+++ b/browser/components/build/nsModule.cpp
@@ -11,17 +11,17 @@
 #if defined(XP_WIN)
 #include "nsWindowsShellService.h"
 #elif defined(XP_MACOSX)
 #include "nsMacShellService.h"
 #elif defined(MOZ_WIDGET_GTK2)
 #include "nsGNOMEShellService.h"
 #endif
 
-#if defined(XP_WIN) && !defined(__MINGW32__)
+#if defined(XP_WIN)
 #include "nsIEHistoryEnumerator.h"
 #endif
 
 #include "rdf.h"
 #include "nsFeedSniffer.h"
 #include "AboutRedirector.h"
 #include "nsIAboutModule.h"
 
@@ -36,49 +36,49 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(Directory
 #if defined(XP_WIN)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsWindowsShellService)
 #elif defined(XP_MACOSX)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsMacShellService)
 #elif defined(MOZ_WIDGET_GTK2)
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsGNOMEShellService, Init)
 #endif
 
-#if defined(XP_WIN) && !defined(__MINGW32__)
+#if defined(XP_WIN)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsIEHistoryEnumerator)
 #endif
 
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsFeedSniffer)
 
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsPrivateBrowsingServiceWrapper, Init)
 
 NS_DEFINE_NAMED_CID(NS_BROWSERDIRECTORYPROVIDER_CID);
 #if defined(XP_WIN)
 NS_DEFINE_NAMED_CID(NS_SHELLSERVICE_CID);
 #elif defined(MOZ_WIDGET_GTK2)
 NS_DEFINE_NAMED_CID(NS_SHELLSERVICE_CID);
 #endif
 NS_DEFINE_NAMED_CID(NS_FEEDSNIFFER_CID);
 NS_DEFINE_NAMED_CID(NS_BROWSER_ABOUT_REDIRECTOR_CID);
-#if defined(XP_WIN) && !defined(__MINGW32__)
+#if defined(XP_WIN)
 NS_DEFINE_NAMED_CID(NS_WINIEHISTORYENUMERATOR_CID);
 #elif defined(XP_MACOSX)
 NS_DEFINE_NAMED_CID(NS_SHELLSERVICE_CID);
 #endif
 NS_DEFINE_NAMED_CID(NS_PRIVATE_BROWSING_SERVICE_WRAPPER_CID);
 
 static const mozilla::Module::CIDEntry kBrowserCIDs[] = {
     { &kNS_BROWSERDIRECTORYPROVIDER_CID, false, NULL, DirectoryProviderConstructor },
 #if defined(XP_WIN)
     { &kNS_SHELLSERVICE_CID, false, NULL, nsWindowsShellServiceConstructor },
 #elif defined(MOZ_WIDGET_GTK2)
     { &kNS_SHELLSERVICE_CID, false, NULL, nsGNOMEShellServiceConstructor },
 #endif
     { &kNS_FEEDSNIFFER_CID, false, NULL, nsFeedSnifferConstructor },
     { &kNS_BROWSER_ABOUT_REDIRECTOR_CID, false, NULL, AboutRedirector::Create },
-#if defined(XP_WIN) && !defined(__MINGW32__)
+#if defined(XP_WIN)
     { &kNS_WINIEHISTORYENUMERATOR_CID, false, NULL, nsIEHistoryEnumeratorConstructor },
 #elif defined(XP_MACOSX)
     { &kNS_SHELLSERVICE_CID, false, NULL, nsMacShellServiceConstructor },
 #endif
     { &kNS_PRIVATE_BROWSING_SERVICE_WRAPPER_CID, false, NULL, nsPrivateBrowsingServiceWrapperConstructor },
     { NULL }
 };
 
@@ -102,17 +102,17 @@ static const mozilla::Module::ContractID
 #ifdef MOZ_SERVICES_SYNC
     { NS_ABOUT_MODULE_CONTRACTID_PREFIX "sync-tabs", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
     { NS_ABOUT_MODULE_CONTRACTID_PREFIX "sync-progress", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
 #endif
     { NS_ABOUT_MODULE_CONTRACTID_PREFIX "home", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
     { NS_ABOUT_MODULE_CONTRACTID_PREFIX "newtab", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
     { NS_ABOUT_MODULE_CONTRACTID_PREFIX "permissions", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
     { NS_ABOUT_MODULE_CONTRACTID_PREFIX "preferences", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
-#if defined(XP_WIN) && !defined(__MINGW32__)
+#if defined(XP_WIN)
     { NS_IEHISTORYENUMERATOR_CONTRACTID, &kNS_WINIEHISTORYENUMERATOR_CID },
 #elif defined(XP_MACOSX)
     { NS_SHELLSERVICE_CONTRACTID, &kNS_SHELLSERVICE_CID },
 #endif
     { NS_PRIVATE_BROWSING_SERVICE_CONTRACTID, &kNS_PRIVATE_BROWSING_SERVICE_WRAPPER_CID },
     { NULL }
 };
 
--- a/browser/components/migration/src/Makefile.in
+++ b/browser/components/migration/src/Makefile.in
@@ -16,17 +16,17 @@ FORCE_STATIC_LIB = 1
 USE_STATIC_LIBS = 1
 
 EXTRA_PP_COMPONENTS = \
   ProfileMigrator.js \
   ChromeProfileMigrator.js \
   FirefoxProfileMigrator.js \
   $(NULL)
 
-ifeq ($(OS_ARCH)_$(GNU_CXX),WINNT_)
+ifeq ($(OS_ARCH),WINNT)
 CPPSRCS += nsIEHistoryEnumerator.cpp
 
 EXTRA_PP_COMPONENTS += IEProfileMigrator.js \
                        SafariProfileMigrator.js \
                        $(NULL)
 DEFINES += -DHAS_IE_MIGRATOR -DHAS_SAFARI_MIGRATOR
 endif
 
--- a/browser/components/nsBrowserContentHandler.js
+++ b/browser/components/nsBrowserContentHandler.js
@@ -240,17 +240,17 @@ function openWindow(parent, url, target,
       uriArray.AppendElement(sstring);
     });
     argArray.AppendElement(uriArray);
   } else {
     argArray.AppendElement(null);
   }
 
   // Pass these as null to ensure that we always trigger the "single URL"
-  // behavior in browser.js's BrowserStartup (which handles the window
+  // behavior in browser.js's gBrowserInit.onLoad (which handles the window
   // arguments)
   argArray.AppendElement(null); // charset
   argArray.AppendElement(null); // referer
   argArray.AppendElement(null); // postData
   argArray.AppendElement(null); // allowThirdPartyFixup
 
   return wwatch.openWindow(parent, url, target, features, argArray);
 }
--- a/browser/components/preferences/connection.js
+++ b/browser/components/preferences/connection.js
@@ -22,18 +22,25 @@ var gConnectionsDialog = {
       var proxyPrefs = ["ssl", "ftp", "socks"];
       for (var i = 0; i < proxyPrefs.length; ++i) {
         var proxyServerURLPref = document.getElementById("network.proxy." + proxyPrefs[i]);
         var proxyPortPref = document.getElementById("network.proxy." + proxyPrefs[i] + "_port");
         var backupServerURLPref = document.getElementById("network.proxy.backup." + proxyPrefs[i]);
         var backupPortPref = document.getElementById("network.proxy.backup." + proxyPrefs[i] + "_port");
         backupServerURLPref.value = proxyServerURLPref.value;
         backupPortPref.value = proxyPortPref.value;
-        proxyServerURLPref.value = httpProxyURLPref.value;
-        proxyPortPref.value = httpProxyPortPref.value;
+        // SOCKS: not a protocol: set value to empty/0 while shareProxies is on
+        if (proxyPrefs[i] == "socks") {
+          proxyServerURLPref.value = "";
+          proxyPortPref.value = 0;
+        } else {
+          // protocols get HTTP proxy's values 
+          proxyServerURLPref.value = httpProxyURLPref.value;
+          proxyPortPref.value = httpProxyPortPref.value;
+        }
       }
     }
     
     this.sanitizeNoProxiesPref();
     
     return true;
   },
 
@@ -129,16 +136,20 @@ var gConnectionsDialog = {
     
     return undefined;
   },
   
   readProxyProtocolPref: function (aProtocol, aIsPort)
   {
     var shareProxiesPref = document.getElementById("network.proxy.share_proxy_settings");
     if (shareProxiesPref.value) {
+      // during shareProxiesPref SOCKS values are empty
+      if (aProtocol == 'socks') {
+        return aIsPort ? 0 : "";
+      }
       var pref = document.getElementById("network.proxy.http" + (aIsPort ? "_port" : ""));    
       return pref.value;
     }
     
     var backupPref = document.getElementById("network.proxy.backup." + aProtocol + (aIsPort ? "_port" : ""));
     return backupPref.hasUserValue ? backupPref.value : undefined;
   },
 
--- a/browser/components/shell/src/Makefile.in
+++ b/browser/components/shell/src/Makefile.in
@@ -30,14 +30,15 @@ endif
 ifdef CPPSRCS
 LIBRARY_NAME = shellservice_s
 endif
 
 EXTRA_COMPONENTS = nsSetDefaultBrowser.js nsSetDefaultBrowser.manifest
 
 include $(topsrcdir)/config/rules.mk
 
-DEFINES += -DMOZ_APP_NAME=\"$(MOZ_APP_NAME)\"
+DEFINES += -DMOZ_APP_NAME=\"$(MOZ_APP_NAME)\" \
+  -DMOZ_APP_VERSION=\"$(MOZ_APP_VERSION)\"
 
 CXXFLAGS += $(TK_CFLAGS)
 
 clobber::
 	rm -f $(DIST)/lib/$(LIBRARY_NAME).lib
--- a/browser/components/shell/src/nsWindowsShellService.cpp
+++ b/browser/components/shell/src/nsWindowsShellService.cpp
@@ -196,17 +196,18 @@ static SETTING gDDESettings[] = {
 };
 
 #if defined(MOZ_MAINTENANCE_SERVICE)
 
 #define ONLY_SERVICE_LAUNCHING
 #include "updatehelper.h"
 #include "updatehelper.cpp"
 
-static const char kPrefetchClearedPref[] = "app.update.service.prefetchCleared";
+static const char *kPrefetchClearedPref =
+  "app.update.service.lastVersionPrefetchCleared";
 static nsCOMPtr<nsIThread> sThread;
 #endif
 
 nsresult
 GetHelperPath(nsAutoString& aPath)
 {
   nsresult rv;
   nsCOMPtr<nsIProperties> directoryService = 
@@ -1011,27 +1012,30 @@ nsWindowsShellService::nsWindowsShellSer
                              nsIWindowsRegKey::WOW64_64)) ||
       NS_FAILED(regKey->ReadIntValue(NS_LITERAL_STRING("Installed"), 
                 &installed)) ||
       !installed) {
     return;
   }
 
   // check to see if we have attempted to do the one time operation of clearing
-  // the prefetch.
-  bool prefetchCleared;
+  // the prefetch.  We do it once per version upgrade.
+  nsCString lastClearedVer;
   nsCOMPtr<nsIPrefBranch> prefBranch;
   nsCOMPtr<nsIPrefService> prefs =
     do_GetService(NS_PREFSERVICE_CONTRACTID);
   if (!prefs || 
       NS_FAILED(prefs->GetBranch(nsnull, getter_AddRefs(prefBranch))) ||
-      (NS_SUCCEEDED(prefBranch->GetBoolPref(kPrefetchClearedPref, 
-                                            &prefetchCleared)) &&
-       prefetchCleared)) {
-    return;
+      (NS_SUCCEEDED(prefBranch->GetCharPref(kPrefetchClearedPref, 
+                                            getter_Copies(lastClearedVer))))) {
+    // If the versions are the same, then bail out early.  We only want to clear
+    // once per version.
+    if (!strcmp(MOZ_APP_VERSION, lastClearedVer.get())) {
+      return;
+    }
   }
 
   // In a minute after startup is definitely complete, launch the
   // service command.
   mTimer = do_CreateInstance(NS_TIMER_CONTRACTID);
   if (mTimer) {
     mTimer->InitWithFuncCallback(
       nsWindowsShellService::LaunchPrefetchClearCommand, 
@@ -1092,17 +1096,17 @@ nsWindowsShellService::LaunchPrefetchCle
 {
   // Make sure we don't call this again from the application, it will be
   // called on each application update instead.
   nsCOMPtr<nsIPrefBranch> prefBranch;
   nsCOMPtr<nsIPrefService> prefs =
     do_GetService(NS_PREFSERVICE_CONTRACTID);
   if (prefs) {
     if (NS_SUCCEEDED(prefs->GetBranch(nsnull, getter_AddRefs(prefBranch)))) {
-      prefBranch->SetBoolPref(kPrefetchClearedPref, true);
+      prefBranch->SetCharPref(kPrefetchClearedPref, MOZ_APP_VERSION);
     }
   }
 
   // Starting the sevice can take a bit of time and we don't want to block the 
   // main thread, so start an event on another thread to handle the operation
   NS_NewThread(getter_AddRefs(sThread));
   if (sThread) {
     nsCOMPtr<nsIRunnable> prefetchEvent = new ClearPrefetchEvent();
--- a/browser/components/thumbnails/PageThumbs.jsm
+++ b/browser/components/thumbnails/PageThumbs.jsm
@@ -6,16 +6,18 @@
 
 let EXPORTED_SYMBOLS = ["PageThumbs", "PageThumbsStorage", "PageThumbsCache"];
 
 const Cu = Components.utils;
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 
 const HTML_NAMESPACE = "http://www.w3.org/1999/xhtml";
+const PREF_STORAGE_VERSION = "browser.pagethumbnails.storage_version";
+const LATEST_STORAGE_VERSION = 1;
 
 /**
  * Name of the directory in the profile that contains the thumbnails.
  */
 const THUMBNAIL_DIRECTORY = "thumbnails";
 
 /**
  * The default background color for page thumbnails.
@@ -74,16 +76,19 @@ let PageThumbs = {
    * The thumbnails' image type.
    */
   get contentType() "image/png",
 
   init: function PageThumbs_init() {
     if (!this._initialized) {
       this._initialized = true;
       PlacesUtils.history.addObserver(PageThumbsHistoryObserver, false);
+
+      // Migrate the underlying storage, if needed.
+      PageThumbsStorageMigrator.migrate();
     }
   },
 
   uninit: function PageThumbs_uninit() {
     if (this._initialized) {
       this._initialized = false;
       PlacesUtils.history.removeObserver(PageThumbsHistoryObserver);
     }
@@ -243,17 +248,17 @@ let PageThumbs = {
     }
   },
 };
 
 let PageThumbsStorage = {
   getFileForURL: function Storage_getFileForURL(aURL, aOptions) {
     let hash = this._calculateMD5Hash(aURL);
     let parts = [THUMBNAIL_DIRECTORY, hash[0], hash[1]];
-    let file = FileUtils.getDir("ProfD", parts, aOptions && aOptions.createPath);
+    let file = FileUtils.getDir("ProfLD", parts, aOptions && aOptions.createPath);
     file.append(hash.slice(2) + ".png");
     return file;
   },
 
   write: function Storage_write(aURL, aDataStream, aCallback) {
     let file = this.getFileForURL(aURL, {createPath: true});
     let fos = FileUtils.openSafeFileOutputStream(file);
 
@@ -279,17 +284,17 @@ let PageThumbsStorage = {
       this.getFileForURL(aURL).remove(false);
     } catch (e) {
       /* The file might not exist or we're not permitted to remove it. */
     }
   },
 
   wipe: function Storage_wipe() {
     try {
-      FileUtils.getDir("ProfD", [THUMBNAIL_DIRECTORY]).remove(true);
+      FileUtils.getDir("ProfLD", [THUMBNAIL_DIRECTORY]).remove(true);
     } catch (e) {
       /* The file might not exist or we're not permitted to remove it. */
     }
   },
 
   _calculateMD5Hash: function Storage_calculateMD5Hash(aValue) {
     let hash = gCryptoHash;
     let value = gUnicodeConverter.convertToByteArray(aValue);
@@ -303,16 +308,54 @@ let PageThumbsStorage = {
     let hex = "";
     for (let i = 0; i < aData.length; i++)
       hex += ("0" + aData.charCodeAt(i).toString(16)).slice(-2);
     return hex;
   },
 
 };
 
+let PageThumbsStorageMigrator = {
+  get currentVersion() {
+    try {
+      return Services.prefs.getIntPref(PREF_STORAGE_VERSION);
+    } catch (e) {
+      // The pref doesn't exist, yet. Return version 0.
+      return 0;
+    }
+  },
+
+  set currentVersion(aVersion) {
+    Services.prefs.setIntPref(PREF_STORAGE_VERSION, aVersion);
+  },
+
+  migrate: function Migrator_migrate() {
+    let version = this.currentVersion;
+
+    if (version < 1)
+      this.removeThumbnailsFromRoamingProfile();
+
+    this.currentVersion = LATEST_STORAGE_VERSION;
+  },
+
+  removeThumbnailsFromRoamingProfile:
+  function Migrator_removeThumbnailsFromRoamingProfile() {
+    let local = FileUtils.getDir("ProfLD", [THUMBNAIL_DIRECTORY]);
+    let roaming = FileUtils.getDir("ProfD", [THUMBNAIL_DIRECTORY]);
+
+    if (!roaming.equals(local) && roaming.exists()) {
+      try {
+        roaming.remove(true);
+      } catch (e) {
+        // The directory might not exist or we're not permitted to remove it.
+      }
+    }
+  }
+};
+
 let PageThumbsHistoryObserver = {
   onDeleteURI: function Thumbnails_onDeleteURI(aURI, aGUID) {
     PageThumbsStorage.remove(aURI.spec);
   },
 
   onClearHistory: function Thumbnails_onClearHistory() {
     PageThumbsStorage.wipe();
   },
--- a/browser/config/mozconfigs/linux32/nightly
+++ b/browser/config/mozconfigs/linux32/nightly
@@ -1,12 +1,13 @@
 ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
 ac_add_options --enable-update-packaging
 ac_add_options --enable-codesighs
 ac_add_options --enable-signmar
+ac_add_options --enable-profiling
 
 # Nightlies only since this has a cost in performance
 ac_add_options --enable-js-diagnostics
 
 . $topsrcdir/build/unix/mozconfig.linux
 
 # Avoid dependency on libstdc++ 4.5
 ac_add_options --enable-stdcxx-compat
--- a/browser/config/mozconfigs/linux64/nightly
+++ b/browser/config/mozconfigs/linux64/nightly
@@ -1,12 +1,13 @@
 ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
 ac_add_options --enable-update-packaging
 ac_add_options --enable-codesighs
 ac_add_options --enable-signmar
+ac_add_options --enable-profiling
 
 # Nightlies only since this has a cost in performance
 ac_add_options --enable-js-diagnostics
 
 . $topsrcdir/build/unix/mozconfig.linux
 
 # Avoid dependency on libstdc++ 4.5
 ac_add_options --enable-stdcxx-compat
--- a/browser/config/mozconfigs/macosx-universal/nightly
+++ b/browser/config/mozconfigs/macosx-universal/nightly
@@ -3,16 +3,17 @@
 # Universal builds override the default of browser (bug 575283 comment 29)
 ac_add_options --enable-application=browser
 
 ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
 ac_add_options --enable-update-packaging
 ac_add_options --enable-codesighs
 ac_add_options --disable-install-strip
 ac_add_options --enable-signmar
+ac_add_options --enable-profiling
 
 # Nightlies only since this has a cost in performance
 ac_add_options --enable-js-diagnostics
 
 # Needed to enable breakpad in application.ini
 export MOZILLA_OFFICIAL=1
 
 export MOZ_TELEMETRY_REPORTING=1
--- a/browser/config/mozconfigs/win32/nightly
+++ b/browser/config/mozconfigs/win32/nightly
@@ -1,15 +1,16 @@
 # for pgo
 mk_add_options PROFILE_GEN_SCRIPT='$(PYTHON) $(MOZ_OBJDIR)/_profile/pgo/profileserver.py'
 
 ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
 ac_add_options --enable-update-packaging
 ac_add_options --enable-jemalloc
 ac_add_options --enable-signmar
+ac_add_options --enable-profiling
 
 # Nightlies only since this has a cost in performance
 ac_add_options --enable-js-diagnostics
 
 # Needed to enable breakpad in application.ini
 export MOZILLA_OFFICIAL=1
 
 export MOZ_TELEMETRY_REPORTING=1
--- a/browser/config/mozconfigs/win64/nightly
+++ b/browser/config/mozconfigs/win64/nightly
@@ -3,16 +3,17 @@ ac_add_options --host=x86_64-pc-mingw32
 
 # for pgo
 mk_add_options PROFILE_GEN_SCRIPT='$(PYTHON) $(MOZ_OBJDIR)/_profile/pgo/profileserver.py'
 
 ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
 ac_add_options --enable-update-packaging
 ac_add_options --enable-jemalloc
 ac_add_options --enable-signmar
+ac_add_options --enable-profiling
 
 # Nightlies only since this has a cost in performance
 ac_add_options --enable-js-diagnostics
 
 # Needed to enable breakpad in application.ini
 export MOZILLA_OFFICIAL=1
 
 export MOZ_TELEMETRY_REPORTING=1
--- a/browser/devtools/highlighter/InsideOutBox.jsm
+++ b/browser/devtools/highlighter/InsideOutBox.jsm
@@ -123,16 +123,19 @@ InsideOutBoxView = {
  *        The view requiring the InsideOutBox.
  * @param aBox
  *        The box object containing the InsideOutBox. Required to add/remove
  *        children during box manipulation (toggling opened or closed).
  */
 
 var EXPORTED_SYMBOLS = ["InsideOutBox"];
 
+const Cu = Components.utils;
+Cu.import("resource:///modules/devtools/LayoutHelpers.jsm");
+
 function InsideOutBox(aView, aBox)
 {
   this.view = aView;
   this.box = aBox;
 
   this.rootObject = null;
 
   this.rootObjectBox = null;
@@ -207,17 +210,19 @@ InsideOutBox.prototype =
     let objectBox = this.createObjectBox(aObject);
     if (!objectBox) {
       return null;
     }
     this.selectObjectBox(objectBox, forceOpen);
     if (makeBoxVisible) {
       this.openObjectBox(objectBox);
       if (scrollIntoView) {
-        objectBox.scrollIntoView(true);
+        // We want to center the label of the element, not the whole tag
+        // (which includes all of its children, and is vertically huge).
+        LayoutHelpers.scrollIntoViewIfNeeded(objectBox.firstElementChild);
       }
     }
     return objectBox;
   },
 
   /**
    * Expands/contracts the given object, depending on its state.
    * @param aObject
--- a/browser/devtools/highlighter/highlighter.jsm
+++ b/browser/devtools/highlighter/highlighter.jsm
@@ -879,17 +879,21 @@ Highlighter.prototype = {
   /**
    * Handle mousemoves in panel.
    *
    * @param nsiDOMEvent aEvent
    *        The MouseEvent triggering the method.
    */
   handleMouseMove: function Highlighter_handleMouseMove(aEvent)
   {
-    if (aEvent.target.ownerDocument) {
+    let doc = aEvent.target.ownerDocument;
+
+    // This should never happen, but just in case, we don't let the
+    // highlighter highlight browser nodes.
+    if (doc && doc != this.chromeDoc) {
       let element = LayoutHelpers.getElementFromPoint(aEvent.target.ownerDocument,
         aEvent.clientX, aEvent.clientY);
       if (element && element != this.node) {
         this.highlight(element);
       }
     }
   },
 };
--- a/browser/devtools/highlighter/inspector.jsm
+++ b/browser/devtools/highlighter/inspector.jsm
@@ -1117,17 +1117,24 @@ InspectorUI.prototype = {
   },
 
   /**
    * Delete the selected node. Called via the Inspector:DeleteNode command.
    */
   deleteNode: function IUI_deleteNode()
   {
     let selection = this.selection;
-    let parent = this.selection.parentNode;
+
+    let root = selection.ownerDocument.documentElement;
+    if (selection === root) {
+      // We can't delete the root element.
+      return;
+    }
+
+    let parent = selection.parentNode;
 
     // remove the node from the treepanel
     if (this.treePanel.isOpen())
       this.treePanel.deleteChildBox(selection);
 
     // remove the node from content
     parent.removeChild(selection);
     this.breadcrumbs.invalidateHierarchy();
@@ -1145,16 +1152,21 @@ InspectorUI.prototype = {
    *
    * @param aNode
    *        the element in the document to inspect
    * @param aScroll
    *        force scroll?
    */
   inspectNode: function IUI_inspectNode(aNode, aScroll)
   {
+    if (aNode.ownerDocument === this.chromeDoc) {
+      // This should never happen, but just in case, we don't let the inspector
+      // inspect browser nodes.
+      return;
+    }
     this.select(aNode, true, true);
     this.highlighter.highlight(aNode, aScroll);
   },
 
   ///////////////////////////////////////////////////////////////////////////
   //// Utility functions
 
   /**
@@ -1217,17 +1229,17 @@ InspectorUI.prototype = {
    */
   getToolbarButtonId: function IUI_createButtonId(anId)
   {
     return "inspector-" + anId + "-toolbutton";
   },
 
   /**
    * Destroy the InspectorUI instance. This is called by the InspectorUI API
-   * "user", see BrowserShutdown() in browser.js.
+   * "user", see gBrowserInit.onUnload() in browser.js.
    */
   destroy: function IUI_destroy()
   {
     if (this.isInspectorOpen) {
       this.closeInspectorUI();
     }
 
     delete this.store;
--- a/browser/devtools/highlighter/test/browser_inspector_treePanel_menu.js
+++ b/browser/devtools/highlighter/test/browser_inspector_treePanel_menu.js
@@ -73,21 +73,38 @@ function test() {
 
     let commandEvent = document.createEvent("XULCommandEvent");
     commandEvent.initCommandEvent("command", true, true, window, 0, false, false,
                                   false, false, null);
     deleteNode.dispatchEvent(commandEvent);
   }
 
   function deleteTest() {
-    InspectorUI.highlighter.removeListener("nodeSelected", deleteTest);
-    Services.obs.addObserver(finishUp, InspectorUI.INSPECTOR_NOTIFICATIONS.CLOSED, false);
+    InspectorUI.highlighter.removeListener("nodeselected", deleteTest);
     is(InspectorUI.selection, div, "parent node selected");
     let p = doc.querySelector("P");
     is(p, null, "node deleted");
+
+    InspectorUI.highlighter.addListener("nodeselected", deleteRootNode);
+    InspectorUI.inspectNode(doc.documentElement, true);
+  }
+
+  function deleteRootNode() {
+    InspectorUI.highlighter.removeListener("nodeselected", deleteRootNode);
+    let deleteNode = document.getElementById("inspectorHTMLDelete");
+    let commandEvent = document.createEvent("XULCommandEvent");
+    commandEvent.initCommandEvent("command", true, true, window, 0, false, false,
+                                  false, false, null);
+    deleteNode.dispatchEvent(commandEvent);
+    executeSoon(isRootStillAlive);
+  }
+
+  function isRootStillAlive() {
+    ok(doc.documentElement, "Document element still alive.");
+    Services.obs.addObserver(finishUp, InspectorUI.INSPECTOR_NOTIFICATIONS.CLOSED, false);
     executeSoon(function() {
       InspectorUI.closeInspectorUI();
     });
   }
 
   function finishUp() {
     Services.obs.removeObserver(finishUp, InspectorUI.INSPECTOR_NOTIFICATIONS.CLOSED);
     doc = node1 = div = null;
--- a/browser/devtools/shared/DeveloperToolbar.jsm
+++ b/browser/devtools/shared/DeveloperToolbar.jsm
@@ -3,16 +3,19 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 const EXPORTED_SYMBOLS = [ "DeveloperToolbar" ];
 
 const NS_XHTML = "http://www.w3.org/1999/xhtml";
 
+const WEBCONSOLE_CONTENT_SCRIPT_URL =
+  "chrome://browser/content/devtools/HUDService-content.js";
+
 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
 Components.utils.import("resource://gre/modules/Services.jsm");
 
 XPCOMUtils.defineLazyGetter(this, "gcli", function() {
   let obj = {};
   Components.utils.import("resource:///modules/devtools/gcli.jsm", obj);
   Components.utils.import("resource:///modules/devtools/GcliCommands.jsm", {});
   return obj.gcli;
@@ -31,16 +34,20 @@ function DeveloperToolbar(aChromeWindow,
 
   this._element = aToolbarElement;
   this._element.hidden = true;
   this._doc = this._element.ownerDocument;
 
   this._lastState = NOTIFICATIONS.HIDE;
   this._pendingShowCallback = undefined;
   this._pendingHide = false;
+  this._errorsCount = {};
+  this._webConsoleButton = this._doc
+                           .getElementById("developer-toolbar-webconsole");
+  this._webConsoleButtonLabel = this._webConsoleButton.label;
 }
 
 /**
  * Inspector notifications dispatched through the nsIObserverService
  */
 const NOTIFICATIONS = {
   /** DeveloperToolbar.show() has been called, and we're working on it */
   LOAD: "developer-toolbar-load",
@@ -53,26 +60,41 @@ const NOTIFICATIONS = {
 };
 
 /**
  * Attach notification constants to the object prototype so tests etc can
  * use them without needing to import anything
  */
 DeveloperToolbar.prototype.NOTIFICATIONS = NOTIFICATIONS;
 
+DeveloperToolbar.prototype._contentMessageListeners =
+  ["WebConsole:CachedMessages", "WebConsole:PageError"];
+
 /**
  * Is the toolbar open?
  */
 Object.defineProperty(DeveloperToolbar.prototype, 'visible', {
   get: function DT_visible() {
     return !this._element.hidden;
   },
   enumerable: true
 });
 
+var _gSequenceId = 0;
+
+/**
+ * Getter for a unique ID.
+ */
+Object.defineProperty(DeveloperToolbar.prototype, 'sequenceId', {
+  get: function DT_visible() {
+    return _gSequenceId++;
+  },
+  enumerable: true
+});
+
 /**
  * Called from browser.xul in response to menu-click or keyboard shortcut to
  * toggle the toolbar
  */
 DeveloperToolbar.prototype.toggle = function DT_toggle()
 {
   if (this.visible) {
     this.hide();
@@ -95,16 +117,18 @@ DeveloperToolbar.introShownThisSession =
  * be called when the DeveloperToolbar is visible
  */
 DeveloperToolbar.prototype.show = function DT_show(aCallback)
 {
   if (this._lastState != NOTIFICATIONS.HIDE) {
     return;
   }
 
+  Services.prefs.setBoolPref("devtools.toolbar.visible", true);
+
   this._notify(NOTIFICATIONS.LOAD);
   this._pendingShowCallback = aCallback;
   this._pendingHide = false;
 
   let checkLoad = function() {
     if (this.tooltipPanel && this.tooltipPanel.loaded &&
         this.outputPanel && this.outputPanel.loaded) {
       this._onload();
@@ -147,19 +171,23 @@ DeveloperToolbar.prototype._onload = fun
     scratchpad: null
   });
 
   this.display.onVisibilityChange.add(this.outputPanel._visibilityChanged, this.outputPanel);
   this.display.onVisibilityChange.add(this.tooltipPanel._visibilityChanged, this.tooltipPanel);
   this.display.onOutput.add(this.outputPanel._outputChanged, this.outputPanel);
 
   this._chromeWindow.getBrowser().tabContainer.addEventListener("TabSelect", this, false);
+  this._chromeWindow.getBrowser().tabContainer.addEventListener("TabClose", this, false);
   this._chromeWindow.getBrowser().addEventListener("load", this, true);
+  this._chromeWindow.getBrowser().addEventListener("beforeunload", this, true);
   this._chromeWindow.addEventListener("resize", this, false);
 
+  this._initErrorsCount(this._chromeWindow.getBrowser().selectedTab);
+
   this._element.hidden = false;
   this._input.focus();
 
   this._notify(NOTIFICATIONS.SHOW);
   if (this._pendingShowCallback) {
     this._pendingShowCallback.call();
     this._pendingShowCallback = undefined;
   }
@@ -174,44 +202,112 @@ DeveloperToolbar.prototype._onload = fun
 
   if (!DeveloperToolbar.introShownThisSession) {
     this.display.maybeShowIntro();
     DeveloperToolbar.introShownThisSession = true;
   }
 };
 
 /**
+ * Initialize the listeners needed for tracking the number of errors for a given
+ * tab.
+ *
+ * @private
+ * @param nsIDOMNode aTab the xul:tab for which you want to track the number of
+ * errors.
+ */
+DeveloperToolbar.prototype._initErrorsCount = function DT__initErrorsCount(aTab)
+{
+  let tabId = aTab.linkedPanel;
+  if (tabId in this._errorsCount) {
+    this._updateErrorsCount();
+    return;
+  }
+
+  let messageManager = aTab.linkedBrowser.messageManager;
+  messageManager.loadFrameScript(WEBCONSOLE_CONTENT_SCRIPT_URL, true);
+
+  this._errorsCount[tabId] = 0;
+
+  this._contentMessageListeners.forEach(function(aName) {
+    messageManager.addMessageListener(aName, this);
+  }, this);
+
+  let message = {
+    features: ["PageError"],
+    cachedMessages: ["PageError"],
+  };
+
+  this.sendMessageToTab(aTab, "WebConsole:Init", message);
+  this._updateErrorsCount();
+};
+
+/**
+ * Stop the listeners needed for tracking the number of errors for a given
+ * tab.
+ *
+ * @private
+ * @param nsIDOMNode aTab the xul:tab for which you want to stop tracking the
+ * number of errors.
+ */
+DeveloperToolbar.prototype._stopErrorsCount = function DT__stopErrorsCount(aTab)
+{
+  let tabId = aTab.linkedPanel;
+  if (!(tabId in this._errorsCount)) {
+    this._updateErrorsCount();
+    return;
+  }
+
+  this.sendMessageToTab(aTab, "WebConsole:Destroy", {});
+
+  let messageManager = aTab.linkedBrowser.messageManager;
+  this._contentMessageListeners.forEach(function(aName) {
+    messageManager.removeMessageListener(aName, this);
+  }, this);
+
+  delete this._errorsCount[tabId];
+  this._updateErrorsCount();
+};
+
+/**
  * Hide the developer toolbar.
  */
 DeveloperToolbar.prototype.hide = function DT_hide()
 {
   if (this._lastState == NOTIFICATIONS.HIDE) {
     return;
   }
 
   if (this._lastState == NOTIFICATIONS.LOAD) {
     this._pendingHide = true;
     return;
   }
 
   this._element.hidden = true;
 
+  Services.prefs.setBoolPref("devtools.toolbar.visible", false);
+
   this._doc.getElementById("Tools:DevToolbar").setAttribute("checked", "false");
   this.destroy();
 
   this._notify(NOTIFICATIONS.HIDE);
 };
 
 /**
  * Hide the developer toolbar
  */
 DeveloperToolbar.prototype.destroy = function DT_destroy()
 {
   this._chromeWindow.getBrowser().tabContainer.removeEventListener("TabSelect", this, false);
   this._chromeWindow.getBrowser().removeEventListener("load", this, true); 
+  this._chromeWindow.getBrowser().removeEventListener("beforeunload", this, true);
+  this._chromeWindow.removeEventListener("resize", this, false);
+
+  let tabs = this._chromeWindow.getBrowser().tabs;
+  Array.prototype.forEach.call(tabs, this._stopErrorsCount, this);
 
   this.display.onVisibilityChange.remove(this.outputPanel._visibilityChanged, this.outputPanel);
   this.display.onVisibilityChange.remove(this.tooltipPanel._visibilityChanged, this.tooltipPanel);
   this.display.onOutput.remove(this.outputPanel._outputChanged, this.outputPanel);
   this.display.destroy();
   this.outputPanel.destroy();
   this.tooltipPanel.destroy();
   delete this._input;
@@ -256,21 +352,158 @@ DeveloperToolbar.prototype.handleEvent =
       this.display.reattach({
         contentDocument: contentDocument,
         chromeWindow: this._chromeWindow,
         environment: {
           chromeDocument: this._doc,
           contentDocument: contentDocument
         },
       });
+
+      if (aEvent.type == "TabSelect") {
+        this._initErrorsCount(aEvent.target);
+      }
     }
   }
   else if (aEvent.type == "resize") {
     this.outputPanel._resize();
   }
+  else if (aEvent.type == "TabClose") {
+    this._stopErrorsCount(aEvent.target);
+  }
+  else if (aEvent.type == "beforeunload") {
+    this._onPageBeforeUnload(aEvent);
+  }
+};
+
+/**
+ * The handler of messages received from the nsIMessageManager.
+ *
+ * @param object aMessage the message received from the content process.
+ */
+DeveloperToolbar.prototype.receiveMessage = function DT_receiveMessage(aMessage)
+{
+  if (!aMessage.json || !(aMessage.json.hudId in this._errorsCount)) {
+    return;
+  }
+
+  let tabId = aMessage.json.hudId;
+  let errors = this._errorsCount[tabId];
+
+  switch (aMessage.name) {
+    case "WebConsole:PageError":
+      this._onPageError(tabId, aMessage.json.pageError);
+      break;
+    case "WebConsole:CachedMessages":
+      aMessage.json.messages.forEach(this._onPageError.bind(this, tabId));
+      break;
+  }
+
+  if (errors != this._errorsCount[tabId]) {
+    this._updateErrorsCount(tabId);
+  }
+};
+
+/**
+ * Send a message to the content process using the nsIMessageManager of the
+ * given tab.
+ *
+ * @param nsIDOMNode aTab the tab you want to send a message to.
+ * @param string aName the name of the message you want to send.
+ * @param object aMessage the message to send.
+ */
+DeveloperToolbar.prototype.sendMessageToTab =
+function DT_sendMessageToTab(aTab, aName, aMessage)
+{
+  let tabId = aTab.linkedPanel;
+  aMessage.hudId = tabId;
+  if (!("id" in aMessage)) {
+    aMessage.id = "DevToolbar-" + this.sequenceId;
+  }
+
+  aTab.linkedBrowser.messageManager.sendAsyncMessage(aName, aMessage);
+};
+
+/**
+ * Process a "WebConsole:PageError" message received from the given tab. This
+ * method counts the JavaScript exceptions received.
+ *
+ * @private
+ * @param string aTabId the ID of the tab from where the page error comes.
+ * @param object aPageError the page error object received from the content
+ * process.
+ */
+DeveloperToolbar.prototype._onPageError =
+function DT__onPageError(aTabId, aPageError)
+{
+  if (aPageError.category == "CSS Parser" ||
+      aPageError.category == "CSS Loader" ||
+      (aPageError.flags & aPageError.warningFlag) ||
+      (aPageError.flags & aPageError.strictFlag)) {
+    return; // just a CSS or JS warning
+  }
+
+  this._errorsCount[aTabId]++;
+};
+
+/**
+ * The |beforeunload| event handler. This function resets the errors count when
+ * a different page starts loading.
+ *
+ * @private
+ * @param nsIDOMEvent aEvent the beforeunload DOM event.
+ */
+DeveloperToolbar.prototype._onPageBeforeUnload =
+function DT__onPageBeforeUnload(aEvent)
+{
+  let window = aEvent.target.defaultView;
+  if (window.top !== window) {
+    return;
+  }
+
+  let tabs = this._chromeWindow.getBrowser().tabs;
+  Array.prototype.some.call(tabs, function(aTab) {
+    if (aTab.linkedBrowser.contentWindow === window) {
+      let tabId = aTab.linkedPanel;
+      if (tabId in this._errorsCount) {
+        this._errorsCount[tabId] = 0;
+        this._updateErrorsCount(tabId);
+      }
+      return true;
+    }
+    return false;
+  }, this);
+};
+
+/**
+ * Update the page errors count displayed in the Web Console button for the
+ * currently selected tab.
+ *
+ * @private
+ * @param string [aChangedTabId] Optional. The tab ID that had its page errors
+ * count changed. If this is provided and it doesn't match the currently
+ * selected tab, then the button is not updated.
+ */
+DeveloperToolbar.prototype._updateErrorsCount =
+function DT__updateErrorsCount(aChangedTabId)
+{
+  let tabId = this._chromeWindow.getBrowser().selectedTab.linkedPanel;
+  if (aChangedTabId && tabId != aChangedTabId) {
+    return;
+  }
+
+  let errors = this._errorsCount[tabId];
+
+  if (errors) {
+    this._webConsoleButton.label =
+      this._webConsoleButtonLabel + " (" + errors + ")";
+  }
+  else {
+    this._webConsoleButton.label = this._webConsoleButtonLabel;
+  }
 };
 
 /**
  * Panel to handle command line output.
  * @param aChromeDoc document from which we can pull the parts we need.
  * @param aInput the input element that should get focus.
  * @param aLoadCallback called when the panel is loaded properly.
  */
--- a/browser/devtools/shared/LayoutHelpers.jsm
+++ b/browser/devtools/shared/LayoutHelpers.jsm
@@ -181,18 +181,17 @@ LayoutHelpers = {
    * Find an element from the given coordinates. This method descends through
    * frames to find the element the user clicked inside frames.
    *
    * @param DOMDocument aDocument the document to look into.
    * @param integer aX
    * @param integer aY
    * @returns Node|null the element node found at the given coordinates.
    */
-  getElementFromPoint: function LH_elementFromPoint(aDocument, aX, aY)
-  {
+  getElementFromPoint: function LH_elementFromPoint(aDocument, aX, aY) {
     let node = aDocument.elementFromPoint(aX, aY);
     if (node && node.contentDocument) {
       if (node instanceof Ci.nsIDOMHTMLIFrameElement) {
         let rect = node.getBoundingClientRect();
 
         // Gap between the iframe and its content window.
         let [offsetTop, offsetLeft] = LayoutHelpers.getIframeContentOffset(node);
 
@@ -209,9 +208,87 @@ LayoutHelpers = {
         let subnode = this.getElementFromPoint(node.contentDocument, aX, aY);
         if (subnode) {
           node = subnode;
         }
       }
     }
     return node;
   },
+
+  /**
+   * Scroll the document so that the element "elem" appears in the viewport.
+   *
+   * @param Element elem the element that needs to appear in the viewport.
+   * @param bool centered true if you want it centered, false if you want it to
+   * appear on the top of the viewport. It is true by default, and that is
+   * usually what you want.
+   */
+  scrollIntoViewIfNeeded:
+  function LH_scrollIntoViewIfNeeded(elem, centered) {
+    // We want to default to centering the element in the page,
+    // so as to keep the context of the element.
+    centered = centered === undefined? true: !!centered;
+
+    let win = elem.ownerDocument.defaultView;
+    let clientRect = elem.getBoundingClientRect();
+
+    // The following are always from the {top, bottom, left, right}
+    // of the viewport, to the {top, …} of the box.
+    // Think of them as geometrical vectors, it helps.
+    // The origin is at the top left.
+
+    let topToBottom = clientRect.bottom;
+    let bottomToTop = clientRect.top - win.innerHeight;
+    let leftToRight = clientRect.right;
+    let rightToLeft = clientRect.left - win.innerWidth;
+    let xAllowed = true;  // We allow one translation on the x axis,
+    let yAllowed = true;  // and one on the y axis.
+
+    // Whatever `centered` is, the behavior is the same if the box is
+    // (even partially) visible.
+
+    if ((topToBottom > 0 || !centered) && topToBottom <= elem.offsetHeight) {
+      win.scrollBy(0, topToBottom - elem.offsetHeight);
+      yAllowed = false;
+    } else
+    if ((bottomToTop < 0 || !centered) && bottomToTop >= -elem.offsetHeight) {
+      win.scrollBy(0, bottomToTop + elem.offsetHeight);
+      yAllowed = false;
+    }
+
+    if ((leftToRight > 0 || !centered) && leftToRight <= elem.offsetWidth) {
+      if (xAllowed) {
+        win.scrollBy(leftToRight - elem.offsetWidth, 0);
+        xAllowed = false;
+      }
+    } else
+    if ((rightToLeft < 0 || !centered) && rightToLeft >= -elem.offsetWidth) {
+      if (xAllowed) {
+        win.scrollBy(rightToLeft + elem.offsetWidth, 0);
+        xAllowed = false;
+      }
+    }
+
+    // If we want it centered, and the box is completely hidden,
+    // then we center it explicitly.
+
+    if (centered) {
+
+      if (yAllowed && (topToBottom <= 0 || bottomToTop >= 0)) {
+        win.scroll(win.scrollX,
+                   win.scrollY + clientRect.top
+                   - (win.innerHeight - elem.offsetHeight) / 2);
+      }
+
+      if (xAllowed && (leftToRight <= 0 || rightToLeft <= 0)) {
+        win.scroll(win.scrollX + clientRect.left
+                   - (win.innerWidth - elem.offsetWidth) / 2,
+                   win.scrollY);
+      }
+    }
+
+    if (win.parent !== win) {
+      // We are inside an iframe.
+      LH_scrollIntoViewIfNeeded(win.frameElement, centered);
+    }
+  },
 };
--- a/browser/devtools/shared/test/Makefile.in
+++ b/browser/devtools/shared/test/Makefile.in
@@ -14,21 +14,26 @@ include $(topsrcdir)/config/rules.mk
 
 _BROWSER_TEST_FILES = \
   browser_browser_basic.js \
   browser_promise_basic.js \
   browser_require_basic.js \
   browser_templater_basic.js \
   browser_toolbar_basic.js \
   browser_toolbar_tooltip.js \
+  browser_toolbar_webconsole_errors_count.js \
+  browser_layoutHelpers.js \
   head.js \
   $(NULL)
 
 _BROWSER_TEST_PAGES = \
   browser_templater_basic.html \
   browser_toolbar_basic.html \
+  browser_toolbar_webconsole_errors_count.html \
+  browser_layoutHelpers.html \
+  browser_layoutHelpers_iframe.html \
   $(NULL)
 
 libs:: $(_BROWSER_TEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/browser/$(relativesrcdir)
 
 libs:: $(_BROWSER_TEST_PAGES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/browser/$(relativesrcdir)
new file mode 100644
--- /dev/null
+++ b/browser/devtools/shared/test/browser_layoutHelpers.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<meta charset=utf-8>
+<title> Layout Helpers </title>
+
+<style>
+  html {
+    height: 300%;
+    width: 300%;
+  }
+  div#some {
+    position: absolute;
+    background: black;
+    width: 2px;
+    height: 2px;
+  }
+  iframe {
+    position: absolute;
+    width: 40px;
+    height: 40px;
+    border: 0;
+  }
+</style>
+
+<div id=some></div>
+<iframe id=frame src='./browser_layoutHelpers_iframe.html'></iframe>
new file mode 100644
--- /dev/null
+++ b/browser/devtools/shared/test/browser_layoutHelpers.js
@@ -0,0 +1,99 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+// Tests that scrollIntoViewIfNeeded works properly.
+
+let imported = {};
+Components.utils.import("resource:///modules/devtools/LayoutHelpers.jsm",
+    imported);
+registerCleanupFunction(function () {
+  imported = {};
+});
+
+let LayoutHelpers = imported.LayoutHelpers;
+
+const TEST_URI = "http://example.com/browser/browser/devtools/shared/test/browser_layoutHelpers.html";
+
+function test() {
+  addTab(TEST_URI, function(browser, tab) {
+    info("Starting browser_layoutHelpers.js");
+    let doc = browser.contentDocument;
+    runTest(doc.defaultView, doc.getElementById('some'));
+    gBrowser.removeCurrentTab();
+    finish();
+  });
+}
+
+function runTest(win, some) {
+  some.style.top = win.innerHeight + 'px';
+  some.style.left = win.innerWidth + 'px';
+  // The tests start with a black 2x2 pixels square below bottom right.
+  // Do not resize the window during the tests.
+
+  win.scroll(win.innerWidth / 2, win.innerHeight + 2);  // Above the viewport.
+  LayoutHelpers.scrollIntoViewIfNeeded(some);
+  is(win.scrollY, Math.floor(win.innerHeight / 2) + 1,
+     'Element completely hidden above should appear centered.');
+
+  win.scroll(win.innerWidth / 2, win.innerHeight + 1);  // On the top edge.
+  LayoutHelpers.scrollIntoViewIfNeeded(some);
+  is(win.scrollY, win.innerHeight,
+     'Element partially visible above should appear above.');
+
+  win.scroll(win.innerWidth / 2, 0);  // Just below the viewport.
+  LayoutHelpers.scrollIntoViewIfNeeded(some);
+  is(win.scrollY, Math.floor(win.innerHeight / 2) + 1,
+     'Element completely hidden below should appear centered.');
+
+  win.scroll(win.innerWidth / 2, 1);  // On the bottom edge.
+  LayoutHelpers.scrollIntoViewIfNeeded(some);
+  is(win.scrollY, 2,
+     'Element partially visible below should appear below.');
+
+
+  win.scroll(win.innerWidth / 2, win.innerHeight + 2);  // Above the viewport.
+  LayoutHelpers.scrollIntoViewIfNeeded(some, false);
+  is(win.scrollY, win.innerHeight,
+     'Element completely hidden above should appear above ' +
+     'if parameter is false.');
+
+  win.scroll(win.innerWidth / 2, win.innerHeight + 1);  // On the top edge.
+  LayoutHelpers.scrollIntoViewIfNeeded(some, false);
+  is(win.scrollY, win.innerHeight,
+     'Element partially visible above should appear above ' +
+     'if parameter is false.');
+
+  win.scroll(win.innerWidth / 2, 0);  // Below the viewport.
+  LayoutHelpers.scrollIntoViewIfNeeded(some, false);
+  is(win.scrollY, 2,
+     'Element completely hidden below should appear below ' +
+     'if parameter is false.');
+
+  win.scroll(win.innerWidth / 2, 1);  // On the bottom edge.
+  LayoutHelpers.scrollIntoViewIfNeeded(some, false);
+  is(win.scrollY, 2,
+     'Element partially visible below should appear below ' +
+     'if parameter is false.');
+
+  // The case of iframes.
+  win.scroll(0, 0);
+
+  let frame = win.document.getElementById('frame');
+  let fwin = frame.contentWindow;
+
+  frame.style.top = win.innerHeight + 'px';
+  frame.style.left = win.innerWidth + 'px';
+
+  fwin.addEventListener('load', function frameLoad() {
+    let some = fwin.document.getElementById('some');
+    LayoutHelpers.scrollIntoViewIfNeeded(some);
+    is(win.scrollX, Math.floor(win.innerWidth / 2) + 20,
+       'Scrolling from an iframe should center the iframe vertically.');
+    is(win.scrollY, Math.floor(win.innerHeight / 2) + 20,
+       'Scrolling from an iframe should center the iframe horizontally.');
+    is(fwin.scrollX, Math.floor(fwin.innerWidth / 2) + 1,
+       'Scrolling from an iframe should center the element vertically.');
+    is(fwin.scrollY, Math.floor(fwin.innerHeight / 2) + 1,
+       'Scrolling from an iframe should center the element horizontally.');
+  }, false);
+}
new file mode 100644
--- /dev/null
+++ b/browser/devtools/shared/test/browser_layoutHelpers_iframe.html
@@ -0,0 +1,19 @@
+<!doctype html>
+<meta charset=utf-8>
+<title> Layout Helpers </title>
+
+<style>
+  html {
+    height: 300%;
+    width: 300%;
+  }
+  div#some {
+    position: absolute;
+    background: black;
+    width: 2px;
+    height: 2px;
+  }
+</style>
+
+<div id=some></div>
+
new file mode 100644
--- /dev/null
+++ b/browser/devtools/shared/test/browser_toolbar_webconsole_errors_count.html
@@ -0,0 +1,29 @@
+<!DOCTYPE HTML>
+<!-- Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/ -->
+<html>
+<head>
+  <meta charset="UTF-8">
+  <title>Developer Toolbar Tests - errors count in the Web Console button</title>
+  <script type="text/javascript">
+    console.log("foobarBug762996consoleLog");
+    window.onload = function() {
+      window.foobarBug762996load();
+    };
+    window.foobarBug762996a();
+  </script>
+  <script type="text/javascript">
+    window.foobarBug762996b();
+  </script>
+</head>
+<body>
+  <p>Hello world! Test for errors count in the Web Console button (developer
+  toolbar).</p>
+  <p style="color: foobarBug762996css"><button>click me</button></p>
+  <script type="text/javascript">
+    document.querySelector("button").onclick = function() {
+      window.foobarBug762996click();
+    };
+  </script>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/browser/devtools/shared/test/browser_toolbar_webconsole_errors_count.js
@@ -0,0 +1,208 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+// Tests that the developer toolbar errors count works properly.
+
+function test() {
+  const TEST_URI = "http://example.com/browser/browser/devtools/shared/test/browser_toolbar_webconsole_errors_count.html";
+
+  let imported = {};
+  Components.utils.import("resource:///modules/HUDService.jsm", imported);
+  let HUDService = imported.HUDService;
+
+  let webconsole = document.getElementById("developer-toolbar-webconsole");
+  let toolbar = document.getElementById("Tools:DevToolbar");
+  let tab1, tab2;
+
+  function openToolbar(browser, tab) {
+    tab1 = tab;
+    ignoreAllUncaughtExceptions(false);
+
+    ok(!DeveloperToolbar.visible, "DeveloperToolbar is not visible");
+
+    expectUncaughtException();
+    oneTimeObserve(DeveloperToolbar.NOTIFICATIONS.SHOW, onOpenToolbar);
+    toolbar.doCommand();
+  }
+
+  ignoreAllUncaughtExceptions();
+  addTab(TEST_URI, openToolbar);
+
+  function getErrorsCount() {
+    let match = webconsole.label.match(/\((\d+)\)$/);
+    return (match || [])[1];
+  }
+
+  function onOpenToolbar() {
+    ok(DeveloperToolbar.visible, "DeveloperToolbar is visible");
+
+    waitForValue({
+      name: "web console button shows page errors",
+      validator: getErrorsCount,
+      value: 3,
+      success: addErrors,
+      failure: finish,
+    });
+  }
+
+  function addErrors() {
+    expectUncaughtException();
+    let button = content.document.querySelector("button");
+    EventUtils.synthesizeMouse(button, 2, 2, {}, content);
+
+    waitForValue({
+      name: "button shows one more error after click in page",
+      validator: getErrorsCount,
+      value: 4,
+      success: function() {
+        ignoreAllUncaughtExceptions();
+        addTab(TEST_URI, onOpenSecondTab);
+      },
+      failure: finish,
+    });
+  }
+
+  function onOpenSecondTab(browser, tab) {
+    tab2 = tab;
+
+    ignoreAllUncaughtExceptions(false);
+    expectUncaughtException();
+
+    waitForValue({
+      name: "button shows correct number of errors after new tab is open",
+      validator: getErrorsCount,
+      value: 3,
+      success: switchToTab1,
+      failure: finish,
+    });
+  }
+
+  function switchToTab1() {
+    gBrowser.selectedTab = tab1;
+    waitForValue({
+      name: "button shows the page errors from tab 1",
+      validator: getErrorsCount,
+      value: 4,
+      success: function() {
+        openWebConsole(tab1, onWebConsoleOpen);
+      },
+      failure: finish,
+    });
+  }
+
+  function openWebConsole(tab, callback)
+  {
+    function _onWebConsoleOpen(subject)
+    {
+      subject.QueryInterface(Ci.nsISupportsString);
+      let hud = HUDService.getHudReferenceById(subject.data);
+      executeSoon(callback.bind(null, hud));
+    }
+
+    oneTimeObserve("web-console-created", _onWebConsoleOpen);
+
+    HUDService.activateHUDForContext(tab);
+  }
+
+  function onWebConsoleOpen(hud) {
+    waitForValue({
+      name: "web console shows the page errors",
+      validator: function() {
+        return hud.outputNode.querySelectorAll(".hud-exception").length;
+      },
+      value: 4,
+      success: checkConsoleOutput.bind(null, hud),
+      failure: finish,
+    });
+  }
+
+  function checkConsoleOutput(hud) {
+    let errors = ["foobarBug762996a", "foobarBug762996b", "foobarBug762996load",
+                  "foobarBug762996click", "foobarBug762996consoleLog",
+                  "foobarBug762996css"];
+    errors.forEach(function(error) {
+      isnot(hud.outputNode.textContent.indexOf(error), -1,
+            error + " found in the Web Console output");
+    });
+
+    hud.jsterm.clearOutput();
+
+    is(hud.outputNode.textContent.indexOf("foobarBug762996color"), -1,
+       "clearOutput() worked");
+
+    expectUncaughtException();
+    let button = content.document.querySelector("button");
+    EventUtils.synthesizeMouse(button, 2, 2, {}, content);
+
+    waitForValue({
+      name: "button shows one more error after another click in page",
+      validator: getErrorsCount,
+      value: 5,
+      success: function() {
+        waitForValue(waitForNewError);
+      },
+      failure: finish,
+    });
+
+    let waitForNewError = {
+      name: "the Web Console displays the new error",
+      validator: function() {
+        return hud.outputNode.textContent.indexOf("foobarBug762996click") > -1;
+      },
+      success: doPageReload.bind(null, hud),
+      failure: finish,
+    };
+  }
+
+  function doPageReload(hud) {
+    tab1.linkedBrowser.addEventListener("load", function _onReload() {
+      tab1.linkedBrowser.removeEventListener("load", _onReload, true);
+      ignoreAllUncaughtExceptions(false);
+      expectUncaughtException();
+    }, true);
+
+    ignoreAllUncaughtExceptions();
+    content.location.reload();
+
+    waitForValue({
+      name: "the Web Console button count has been reset after page reload",
+      validator: getErrorsCount,
+      value: 3,
+      success: function() {
+        waitForValue(waitForConsoleOutputAfterReload);
+      },
+      failure: finish,
+    });
+
+    let waitForConsoleOutputAfterReload = {
+      name: "the Web Console displays the correct number of errors after reload",
+      validator: function() {
+        return hud.outputNode.querySelectorAll(".hud-exception").length;
+      },
+      value: 4,
+      success: function() {
+        isnot(hud.outputNode.textContent.indexOf("foobarBug762996load"), -1,
+              "foobarBug762996load found in console output after page reload");
+        testEnd();
+      },
+      failure: testEnd,
+    };
+  }
+
+  function testEnd() {
+    document.getElementById("developer-toolbar-closebutton").doCommand();
+    HUDService.deactivateHUDForContext(tab1);
+    gBrowser.removeTab(tab1);
+    gBrowser.removeTab(tab2);
+    finish();
+  }
+
+  function oneTimeObserve(name, callback) {
+    function _onObserve(aSubject, aTopic, aData) {
+      Services.obs.removeObserver(_onObserve, name);
+      callback(aSubject, aTopic, aData);
+    };
+    Services.obs.addObserver(_onObserve, name, false);
+  }
+}
+
--- a/browser/devtools/shared/test/head.js
+++ b/browser/devtools/shared/test/head.js
@@ -126,8 +126,72 @@ function catchFail(func) {
     catch (ex) {
       ok(false, ex);
       console.error(ex);
       finish();
       throw ex;
     }
   };
 }
+
+/**
+ * Polls a given function waiting for the given value.
+ *
+ * @param object aOptions
+ *        Options object with the following properties:
+ *        - validator
+ *        A validator function that should return the expected value. This is
+ *        called every few milliseconds to check if the result is the expected
+ *        one. When the returned result is the expected one, then the |success|
+ *        function is called and polling stops. If |validator| never returns
+ *        the expected value, then polling timeouts after several tries and
+ *        a failure is recorded - the given |failure| function is invoked.
+ *        - success
+ *        A function called when the validator function returns the expected
+ *        value.
+ *        - failure
+ *        A function called if the validator function timeouts - fails to return
+ *        the expected value in the given time.
+ *        - name
+ *        Name of test. This is used to generate the success and failure
+ *        messages.
+ *        - timeout
+ *        Timeout for validator function, in milliseconds. Default is 5000 ms.
+ *        - value
+ *        The expected value. If this option is omitted then the |validator|
+ *        function must return a trueish value.
+ *        Each of the provided callback functions will receive two arguments:
+ *        the |aOptions| object and the last value returned by |validator|.
+ */
+function waitForValue(aOptions)
+{
+  let start = Date.now();
+  let timeout = aOptions.timeout || 5000;
+  let lastValue;
+
+  function wait(validatorFn, successFn, failureFn)
+  {
+    if ((Date.now() - start) > timeout) {
+      // Log the failure.
+      ok(false, "Timed out while waiting for: " + aOptions.name);
+      let expected = "value" in aOptions ?
+                     "'" + aOptions.value + "'" :
+                     "a trueish value";
+      info("timeout info :: got '" + lastValue + "', expected " + expected);
+      failureFn(aOptions, lastValue);
+      return;
+    }
+
+    lastValue = validatorFn(aOptions, lastValue);
+    let successful = "value" in aOptions ?
+                      lastValue == aOptions.value :
+                      lastValue;
+    if (successful) {
+      ok(true, aOptions.name);
+      successFn(aOptions, lastValue);
+    }
+    else {
+      setTimeout(function() wait(validatorFn, successFn, failureFn), 100);
+    }
+  }
+
+  wait(aOptions.validator, aOptions.success, aOptions.failure);
+}
--- a/browser/devtools/sourceeditor/source-editor-orion.jsm
+++ b/browser/devtools/sourceeditor/source-editor-orion.jsm
@@ -126,16 +126,25 @@ const DEFAULT_KEYBINDINGS = [
   },
   {
     action: "Move to Bracket Closing",
     code: Ci.nsIDOMKeyEvent.DOM_VK_CLOSE_BRACKET,
     accel: true,
   },
 ];
 
+if (Services.appinfo.OS == "WINNT" ||
+    Services.appinfo.OS == "Linux") {
+  DEFAULT_KEYBINDINGS.push({
+    action: "redo",
+    code: Ci.nsIDOMKeyEvent.DOM_VK_Y,
+    accel: true,
+  });
+}
+
 var EXPORTED_SYMBOLS = ["SourceEditor"];
 
 /**
  * The SourceEditor object constructor. The SourceEditor component allows you to
  * provide users with an editor tailored to the specific needs of editing source
  * code, aimed primarily at web developers.
  *
  * The editor used here is Eclipse Orion (see http://www.eclipse.org/orion).
--- a/browser/devtools/sourceeditor/test/browser_sourceeditor_initialization.js
+++ b/browser/devtools/sourceeditor/test/browser_sourceeditor_initialization.js
@@ -93,16 +93,29 @@ function editorLoaded()
   EventUtils.synthesizeKey("VK_Z", {accelKey: true}, testWin);
 
   is(editor.getText(), "source-editor", "Ctrl-Z (undo) works");
 
   EventUtils.synthesizeKey("VK_Z", {accelKey: true, shiftKey: true}, testWin);
 
   is(editor.getText(), "code-editor", "Ctrl-Shift-Z (redo) works");
 
+  editor.undo();
+
+  EventUtils.synthesizeKey("VK_Y", {accelKey: true}, testWin);
+  if (Services.appinfo.OS == "WINNT" ||
+      Services.appinfo.OS == "Linux") {
+    is(editor.getText(), "code-editor",
+       "CTRL+Y does redo on Linux and Windows");
+  } else {
+    is(editor.getText(), "source-editor",
+       "CTRL+Y doesn't redo on machines other than Linux and Windows");
+    editor.setText("code-editor");
+  }
+
   // Test selection methods.
 
   editor.setSelection(0, 4);
 
   is(editor.getSelectedText(), "code", "getSelectedText() works");
 
   let selection = editor.getSelection();
   ok(selection.start == 0 && selection.end == 4, "getSelection() works");
--- a/browser/devtools/webconsole/HUDService-content.js
+++ b/browser/devtools/webconsole/HUDService-content.js
@@ -83,31 +83,29 @@ let Manager = {
   },
 
   /**
    * The message handler. This method forwards all the remote messages to the
    * appropriate code.
    */
   receiveMessage: function Manager_receiveMessage(aMessage)
   {
-    if (!_alive) {
+    if (!_alive || !aMessage.json) {
       return;
     }
 
-    if (!aMessage.json || (aMessage.name != "WebConsole:Init" &&
-                           aMessage.json.hudId != this.hudId)) {
-      Cu.reportError("Web Console content script: received message " +
-                     aMessage.name + " from wrong hudId!");
+    if (aMessage.name == "WebConsole:Init" && !this.hudId) {
+      this._onInit(aMessage.json);
+      return;
+    }
+    if (aMessage.json.hudId != this.hudId) {
       return;
     }
 
     switch (aMessage.name) {
-      case "WebConsole:Init":
-        this._onInit(aMessage.json);
-        break;
       case "WebConsole:EnableFeature":
         this.enableFeature(aMessage.json.feature, aMessage.json);
         break;
       case "WebConsole:DisableFeature":
         this.disableFeature(aMessage.json.feature);
         break;
       case "WebConsole:GetPreferences":
         this.handleGetPreferences(aMessage.json);
@@ -1281,39 +1279,57 @@ let ConsoleListener = {
    */
   observe: function CL_observe(aScriptError)
   {
     if (!_alive || !(aScriptError instanceof Ci.nsIScriptError) ||
         !aScriptError.outerWindowID) {
       return;
     }
 
-    switch (aScriptError.category) {
-      // We ignore chrome-originating errors as we only care about content.
-      case "XPConnect JavaScript":
-      case "component javascript":
-      case "chrome javascript":
-      case "chrome registration":
-      case "XBL":
-      case "XBL Prototype Handler":
-      case "XBL Content Sink":
-      case "xbl javascript":
-        return;
+    if (!this.isCategoryAllowed(aScriptError.category)) {
+      return;
     }
 
     let errorWindow =
       WebConsoleUtils.getWindowByOuterId(aScriptError.outerWindowID,
                                          Manager.window);
     if (!errorWindow || errorWindow.top != Manager.window) {
       return;
     }
 
     Manager.sendMessage("WebConsole:PageError", { pageError: aScriptError });
   },
 
+
+  /**
+   * Check if the given script error category is allowed to be tracked or not.
+   * We ignore chrome-originating errors as we only care about content.
+   *
+   * @param string aCategory
+   *        The nsIScriptError category you want to check.
+   * @return boolean
+   *         True if the category is allowed to be logged, false otherwise.
+   */
+  isCategoryAllowed: function CL_isCategoryAllowed(aCategory)
+  {
+    switch (aCategory) {
+      case "XPConnect JavaScript":
+      case "component javascript":
+      case "chrome javascript":
+      case "chrome registration":
+      case "XBL":
+      case "XBL Prototype Handler":
+      c