Merge from mozilla-central.
authorDavid Anderson <danderson@mozilla.com>
Wed, 20 Jun 2012 17:36:56 -0700
changeset 109946 881c4b8e74045a4033f68ec402c245f5939481f8
parent 109945 a0c81536dd0b3278bb92a174696f51f6c0d71f6b (current diff)
parent 99834 e240d6e43c9a675ecbaea450d96cf55601ea0119 (diff)
child 109947 57adfe34193eb24d16b80276dc464eadff3c8535
push id2248
push userakeybl@mozilla.com
push dateMon, 08 Oct 2012 19:23:44 +0000
treeherdermozilla-aurora@118a3b748323 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone16.0a1
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") {