Merge from mozilla-central.
authorDavid Anderson <danderson@mozilla.com>
Fri, 30 Mar 2012 18:40:08 -0700
changeset 112935 c95bd17c4ae77baa34324a9e790b5684254830eb
parent 112934 66aed5264e79ecf48eba64d793a15723c0e37778 (current diff)
parent 94459 4c43cfe73516df0b3ec7686fc12a920ab85dc1f8 (diff)
child 112936 196cd36978ba034263f3efcc1a6e78c2aed800fd
push id239
push userakeybl@mozilla.com
push dateThu, 03 Jan 2013 21:54:43 +0000
treeherdermozilla-release@3a7b66445659 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone14.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge from mozilla-central.
accessible/public/nsIAccessibilityService.h
accessible/src/base/nsAccessNode.cpp
accessible/src/base/nsAccessNode.h
accessible/src/base/nsAccessibilityService.h
accessible/src/base/nsAccessible.cpp
accessible/src/base/nsAccessible.h
accessible/src/base/nsApplicationAccessible.cpp
accessible/src/base/nsApplicationAccessible.h
accessible/src/base/nsDocAccessible.cpp
accessible/src/base/nsDocAccessible.h
accessible/src/msaa/nsAccessNodeWrap.cpp
accessible/src/msaa/nsAccessibleWrap.cpp
accessible/src/xforms/nsXFormsAccessible.cpp
accessible/src/xul/nsXULTreeAccessible.cpp
accessible/src/xul/nsXULTreeAccessible.h
accessible/src/xul/nsXULTreeGridAccessible.cpp
accessible/src/xul/nsXULTreeGridAccessible.h
b2g/installer/package-manifest.in
browser/app/profile/extensions/Extensions.rdf
browser/app/profile/extensions/installed-extensions.txt
browser/base/content/browser.js
browser/base/content/sync/addDevice.js
browser/base/content/sync/setup.js
browser/base/content/tabbrowser.xml
browser/components/nsBrowserContentHandler.js
browser/components/nsBrowserGlue.js
browser/components/preferences/sync.js
browser/components/sessionstore/src/nsSessionStore.js
browser/components/sessionstore/test/Makefile.in
browser/components/tabview/tabitems.js
browser/components/tabview/test/Makefile.in
browser/components/tabview/test/head.js
browser/components/tabview/ui.js
browser/devtools/styleinspector/CssHtmlTree.jsm
content/base/public/nsContentUtils.h
content/base/public/nsIAttribute.h
content/base/public/nsIContent.h
content/base/public/nsIDocument.h
content/base/public/nsINode.h
content/base/public/nsINodeInfo.h
content/base/public/nsIXMLHttpRequest.idl
content/base/src/Makefile.in
content/base/src/nsAttrAndChildArray.cpp
content/base/src/nsAttrAndChildArray.h
content/base/src/nsAttrName.h
content/base/src/nsCommentNode.cpp
content/base/src/nsContentList.cpp
content/base/src/nsContentSink.cpp
content/base/src/nsContentUtils.cpp
content/base/src/nsDOMAttribute.cpp
content/base/src/nsDOMAttribute.h
content/base/src/nsDOMAttributeMap.cpp
content/base/src/nsDOMAttributeMap.h
content/base/src/nsDOMDocumentType.cpp
content/base/src/nsDOMDocumentType.h
content/base/src/nsDocument.cpp
content/base/src/nsDocument.h
content/base/src/nsDocumentEncoder.cpp
content/base/src/nsDocumentFragment.cpp
content/base/src/nsEventSource.cpp
content/base/src/nsFrameMessageManager.cpp
content/base/src/nsGenericDOMDataNode.cpp
content/base/src/nsGenericDOMDataNode.h
content/base/src/nsGenericElement.cpp
content/base/src/nsGenericElement.h
content/base/src/nsGkAtomList.h
content/base/src/nsMappedAttributeElement.h
content/base/src/nsNameSpaceManager.cpp
content/base/src/nsNodeInfo.cpp
content/base/src/nsNodeInfo.h
content/base/src/nsNodeInfoManager.cpp
content/base/src/nsNodeUtils.cpp
content/base/src/nsObjectLoadingContent.cpp
content/base/src/nsObjectLoadingContent.h
content/base/src/nsRange.cpp
content/base/src/nsScriptLoader.cpp
content/base/src/nsStyledElement.h
content/base/src/nsTextNode.cpp
content/base/src/nsTextNode.h
content/base/src/nsTreeSanitizer.cpp
content/base/src/nsXMLHttpRequest.cpp
content/base/src/nsXMLHttpRequest.h
content/events/public/nsEventNameList.h
content/events/src/nsDOMEvent.cpp
content/events/src/nsDOMEvent.h
content/events/src/nsDOMEventTargetHelper.h
content/events/src/nsDOMMouseEvent.cpp
content/events/src/nsDOMUIEvent.cpp
content/events/src/nsDOMUIEvent.h
content/events/src/nsEventListenerManager.cpp
content/events/src/nsEventListenerManager.h
content/events/src/nsEventStateManager.cpp
content/events/src/nsEventStateManager.h
content/events/src/nsXMLEventsElement.cpp
content/events/src/nsXMLEventsManager.cpp
content/html/content/public/nsHTMLCanvasElement.h
content/html/content/public/nsHTMLMediaElement.h
content/html/content/public/nsHTMLVideoElement.h
content/html/content/src/nsGenericHTMLElement.cpp
content/html/content/src/nsGenericHTMLElement.h
content/html/content/src/nsHTMLAnchorElement.cpp
content/html/content/src/nsHTMLAreaElement.cpp
content/html/content/src/nsHTMLAudioElement.cpp
content/html/content/src/nsHTMLBRElement.cpp
content/html/content/src/nsHTMLBodyElement.cpp
content/html/content/src/nsHTMLButtonElement.cpp
content/html/content/src/nsHTMLCanvasElement.cpp
content/html/content/src/nsHTMLDataListElement.cpp
content/html/content/src/nsHTMLDivElement.cpp
content/html/content/src/nsHTMLFieldSetElement.cpp
content/html/content/src/nsHTMLFieldSetElement.h
content/html/content/src/nsHTMLFontElement.cpp
content/html/content/src/nsHTMLFormElement.cpp
content/html/content/src/nsHTMLFormElement.h
content/html/content/src/nsHTMLFrameElement.cpp
content/html/content/src/nsHTMLFrameSetElement.cpp
content/html/content/src/nsHTMLFrameSetElement.h
content/html/content/src/nsHTMLHRElement.cpp
content/html/content/src/nsHTMLHeadingElement.cpp
content/html/content/src/nsHTMLIFrameElement.cpp
content/html/content/src/nsHTMLImageElement.cpp
content/html/content/src/nsHTMLInputElement.cpp
content/html/content/src/nsHTMLInputElement.h
content/html/content/src/nsHTMLLIElement.cpp
content/html/content/src/nsHTMLLabelElement.cpp
content/html/content/src/nsHTMLLabelElement.h
content/html/content/src/nsHTMLLegendElement.cpp
content/html/content/src/nsHTMLLegendElement.h
content/html/content/src/nsHTMLLinkElement.cpp
content/html/content/src/nsHTMLMediaElement.cpp
content/html/content/src/nsHTMLMenuElement.cpp
content/html/content/src/nsHTMLMenuElement.h
content/html/content/src/nsHTMLMenuItemElement.cpp
content/html/content/src/nsHTMLMenuItemElement.h
content/html/content/src/nsHTMLMetaElement.cpp
content/html/content/src/nsHTMLOListElement.cpp
content/html/content/src/nsHTMLObjectElement.cpp
content/html/content/src/nsHTMLOptGroupElement.cpp
content/html/content/src/nsHTMLOptionElement.cpp
content/html/content/src/nsHTMLOptionElement.h
content/html/content/src/nsHTMLOutputElement.cpp
content/html/content/src/nsHTMLParagraphElement.cpp
content/html/content/src/nsHTMLPreElement.cpp
content/html/content/src/nsHTMLProgressElement.cpp
content/html/content/src/nsHTMLScriptElement.cpp
content/html/content/src/nsHTMLSelectElement.cpp
content/html/content/src/nsHTMLSelectElement.h
content/html/content/src/nsHTMLSharedElement.cpp
content/html/content/src/nsHTMLSharedObjectElement.cpp
content/html/content/src/nsHTMLSourceElement.cpp
content/html/content/src/nsHTMLStyleElement.cpp
content/html/content/src/nsHTMLTableCaptionElement.cpp
content/html/content/src/nsHTMLTableCellElement.cpp
content/html/content/src/nsHTMLTableColElement.cpp
content/html/content/src/nsHTMLTableElement.cpp
content/html/content/src/nsHTMLTableElement.h
content/html/content/src/nsHTMLTableRowElement.cpp
content/html/content/src/nsHTMLTableSectionElement.cpp
content/html/content/src/nsHTMLTextAreaElement.cpp
content/html/content/src/nsHTMLTitleElement.cpp
content/html/content/src/nsHTMLVideoElement.cpp
content/html/content/src/nsTextEditorState.cpp
content/html/document/src/ImageDocument.cpp
content/html/document/src/MediaDocument.cpp
content/html/document/src/PluginDocument.cpp
content/html/document/src/VideoDocument.cpp
content/html/document/src/nsHTMLContentSink.cpp
content/html/document/src/nsHTMLDocument.cpp
content/html/document/src/nsHTMLDocument.h
content/mathml/content/src/nsMathMLElement.h
content/media/MediaResource.cpp
content/media/VideoUtils.h
content/media/nsBuiltinDecoderStateMachine.cpp
content/media/nsMediaCache.cpp
content/media/ogg/nsOggReader.cpp
content/svg/content/src/nsSVGAElement.cpp
content/svg/content/src/nsSVGAElement.h
content/svg/content/src/nsSVGAltGlyphElement.cpp
content/svg/content/src/nsSVGAnimateMotionElement.cpp
content/svg/content/src/nsSVGAnimateMotionElement.h
content/svg/content/src/nsSVGAnimateTransformElement.cpp
content/svg/content/src/nsSVGAnimationElement.cpp
content/svg/content/src/nsSVGAnimationElement.h
content/svg/content/src/nsSVGDefsElement.cpp
content/svg/content/src/nsSVGElement.cpp
content/svg/content/src/nsSVGElement.h
content/svg/content/src/nsSVGFilterElement.cpp
content/svg/content/src/nsSVGFilterElement.h
content/svg/content/src/nsSVGFilters.cpp
content/svg/content/src/nsSVGFilters.h
content/svg/content/src/nsSVGForeignObjectElement.cpp
content/svg/content/src/nsSVGForeignObjectElement.h
content/svg/content/src/nsSVGGElement.cpp
content/svg/content/src/nsSVGGradientElement.cpp
content/svg/content/src/nsSVGGradientElement.h
content/svg/content/src/nsSVGGraphicElement.cpp
content/svg/content/src/nsSVGGraphicElement.h
content/svg/content/src/nsSVGImageElement.cpp
content/svg/content/src/nsSVGImageElement.h
content/svg/content/src/nsSVGLineElement.cpp
content/svg/content/src/nsSVGMarkerElement.cpp
content/svg/content/src/nsSVGMarkerElement.h
content/svg/content/src/nsSVGMaskElement.cpp
content/svg/content/src/nsSVGMaskElement.h
content/svg/content/src/nsSVGMpathElement.cpp
content/svg/content/src/nsSVGMpathElement.h
content/svg/content/src/nsSVGPathElement.cpp
content/svg/content/src/nsSVGPathElement.h
content/svg/content/src/nsSVGPathGeometryElement.cpp
content/svg/content/src/nsSVGPathGeometryElement.h
content/svg/content/src/nsSVGPatternElement.cpp
content/svg/content/src/nsSVGPatternElement.h
content/svg/content/src/nsSVGPolyElement.cpp
content/svg/content/src/nsSVGPolyElement.h
content/svg/content/src/nsSVGRectElement.cpp
content/svg/content/src/nsSVGSVGElement.cpp
content/svg/content/src/nsSVGSVGElement.h
content/svg/content/src/nsSVGScriptElement.cpp
content/svg/content/src/nsSVGStopElement.cpp
content/svg/content/src/nsSVGStyleElement.cpp
content/svg/content/src/nsSVGSwitchElement.cpp
content/svg/content/src/nsSVGSwitchElement.h
content/svg/content/src/nsSVGSymbolElement.cpp
content/svg/content/src/nsSVGTSpanElement.cpp
content/svg/content/src/nsSVGTextElement.cpp
content/svg/content/src/nsSVGTextPathElement.cpp
content/svg/content/src/nsSVGTextPathElement.h
content/svg/content/src/nsSVGTitleElement.cpp
content/svg/content/src/nsSVGUseElement.cpp
content/svg/content/src/nsSVGUseElement.h
content/xbl/src/nsXBLBinding.cpp
content/xbl/src/nsXBLContentSink.cpp
content/xbl/src/nsXBLContentSink.h
content/xbl/src/nsXBLDocumentInfo.cpp
content/xbl/src/nsXBLPrototypeBinding.cpp
content/xbl/src/nsXBLService.cpp
content/xml/content/src/nsXMLCDATASection.cpp
content/xml/content/src/nsXMLElement.cpp
content/xml/content/src/nsXMLElement.h
content/xml/content/src/nsXMLProcessingInstruction.cpp
content/xml/content/src/nsXMLProcessingInstruction.h
content/xml/content/src/nsXMLStylesheetPI.cpp
content/xml/document/src/nsXMLContentSink.cpp
content/xml/document/src/nsXMLContentSink.h
content/xml/document/src/nsXMLDocument.cpp
content/xml/document/src/nsXMLDocument.h
content/xml/document/src/nsXMLFragmentContentSink.cpp
content/xslt/src/xml/txXMLUtils.h
content/xslt/src/xpath/txMozillaXPathTreeWalker.cpp
content/xslt/src/xpath/txXPathTreeWalker.h
content/xslt/src/xslt/txMozillaStylesheetCompiler.cpp
content/xslt/src/xslt/txMozillaTextOutput.cpp
content/xslt/src/xslt/txMozillaXMLOutput.cpp
content/xtf/src/nsXTFElementWrapper.cpp
content/xtf/src/nsXTFElementWrapper.h
content/xul/content/src/nsXULContextMenuBuilder.cpp
content/xul/content/src/nsXULElement.cpp
content/xul/content/src/nsXULElement.h
content/xul/document/src/nsXULContentSink.cpp
content/xul/document/src/nsXULContentSink.h
content/xul/document/src/nsXULDocument.cpp
content/xul/document/src/nsXULPrototypeCache.cpp
content/xul/document/src/nsXULPrototypeDocument.cpp
content/xul/templates/src/nsXULContentBuilder.cpp
content/xul/templates/src/nsXULContentUtils.cpp
content/xul/templates/src/nsXULSortService.cpp
content/xul/templates/src/nsXULTemplateBuilder.cpp
content/xul/templates/src/nsXULTreeBuilder.cpp
docshell/base/nsDocShell.cpp
docshell/base/nsDocShell.h
dom/base/nsDOMClassInfo.cpp
dom/base/nsDOMScriptObjectFactory.cpp
dom/base/nsDOMWindowUtils.cpp
dom/base/nsGlobalWindow.cpp
dom/base/nsGlobalWindow.h
dom/base/nsIScriptContext.h
dom/base/nsJSEnvironment.cpp
dom/base/nsJSEnvironment.h
dom/base/nsJSTimeoutHandler.cpp
dom/base/nsScriptNameSpaceManager.cpp
dom/base/nsScriptNameSpaceManager.h
dom/interfaces/base/nsIDOMWindowUtils.idl
dom/interfaces/core/nsIDOMDocument.idl
dom/plugins/base/nsPluginHost.cpp
dom/src/events/nsJSEventListener.cpp
dom/src/jsurl/nsJSProtocolHandler.cpp
dom/src/storage/nsDOMStorage.cpp
dom/tests/mochitest/general/browserFrameHelpers.js
dom/tests/mochitest/general/test_browserFrame1.html
dom/tests/mochitest/general/test_browserFrame2.html
dom/tests/mochitest/general/test_browserFrame3.html
dom/tests/mochitest/general/test_browserFrame4.html
dom/tests/mochitest/general/test_browserFrame5.html
dom/tests/mochitest/general/test_browserFrame6.html
dom/tests/mochitest/general/test_browserFrame7.html
dom/workers/XMLHttpRequestPrivate.cpp
editor/libeditor/base/nsEditor.cpp
embedding/android/GeckoAppShell.java
gfx/gl/GLContext.cpp
gfx/gl/GLContext.h
gfx/gl/GLContextProviderEGL.cpp
gfx/layers/Layers.cpp
gfx/thebes/gfxAtomList.h
gfx/thebes/gfxAtoms.cpp
gfx/thebes/gfxAtoms.h
gfx/thebes/gfxContext.cpp
gfx/thebes/gfxContext.h
gfx/thebes/gfxFT2Fonts.cpp
gfx/thebes/gfxFont.cpp
gfx/thebes/gfxFontUtils.cpp
gfx/thebes/gfxFontconfigUtils.cpp
gfx/thebes/gfxGDIFontList.h
gfx/thebes/gfxOS2Fonts.cpp
gfx/thebes/gfxPangoFonts.cpp
gfx/thebes/gfxPattern.cpp
gfx/thebes/gfxPattern.h
gfx/thebes/gfxPlatform.cpp
gfx/thebes/gfxUniscribeShaper.cpp
gfx/thebes/gfxUtils.cpp
gfx/thebes/gfxUtils.h
js/src/frontend/BytecodeEmitter.cpp
js/src/frontend/Parser.cpp
js/src/jsanalyze.cpp
js/src/jsanalyze.h
js/src/jsapi.cpp
js/src/jsapi.h
js/src/jscntxt.h
js/src/jsdbgapi.cpp
js/src/jsexn.cpp
js/src/jsfun.cpp
js/src/jsgc.h
js/src/jsinfer.cpp
js/src/jsinterp.cpp
js/src/jsnum.cpp
js/src/jsnum.h
js/src/jsobj.cpp
js/src/jsobjinlines.h
js/src/jsopcode.cpp
js/src/jsopcode.tbl
js/src/jsscope.cpp
js/src/methodjit/Compiler.cpp
js/src/methodjit/LoopState.cpp
js/xpconnect/src/XPCJSRuntime.cpp
js/xpconnect/src/XPCMaps.cpp
js/xpconnect/src/XPCMaps.h
js/xpconnect/src/nsXPConnect.cpp
js/xpconnect/src/xpcpublic.h
js/xpconnect/wrappers/WrapperFactory.cpp
layout/base/nsCSSFrameConstructor.cpp
layout/base/nsCSSFrameConstructor.h
layout/base/nsIPresShell.h
layout/base/nsLayoutUtils.cpp
layout/base/nsPresShell.cpp
layout/build/nsContentDLF.cpp
layout/build/nsLayoutModule.cpp
layout/forms/nsComboboxControlFrame.cpp
layout/forms/nsFileControlFrame.cpp
layout/forms/nsListControlFrame.cpp
layout/forms/nsProgressFrame.cpp
layout/forms/nsTextControlFrame.cpp
layout/generic/nsFrameSetFrame.cpp
layout/generic/nsGfxScrollFrame.cpp
layout/generic/nsImageFrame.cpp
layout/generic/nsObjectFrame.cpp
layout/generic/nsTextRunTransformations.cpp
layout/generic/nsVideoFrame.cpp
layout/mathml/nsMathMLmactionFrame.cpp
layout/reftests/svg/reftest.list
layout/style/nsCSSProps.h
layout/style/nsCSSRuleProcessor.cpp
layout/style/nsCSSRuleProcessor.h
layout/style/nsHTMLStyleSheet.cpp
layout/style/nsRuleProcessorData.h
layout/style/nsStyleSet.cpp
layout/svg/base/src/nsSVGFilterFrame.cpp
layout/xul/base/src/nsDocElementBoxFrame.cpp
layout/xul/base/src/nsListBoxBodyFrame.cpp
layout/xul/base/src/nsMenuPopupFrame.cpp
layout/xul/base/src/tree/src/nsTreeBodyFrame.cpp
layout/xul/base/src/tree/src/nsTreeBoxObject.cpp
layout/xul/base/src/tree/src/nsTreeColumns.cpp
layout/xul/base/src/tree/src/nsTreeContentView.cpp
mobile/android/base/GeckoApp.java
mobile/android/base/GeckoAppShell.java
mobile/android/locales/en-US/chrome/webapps.dtd
mobile/xul/chrome/content/sync.js
mobile/xul/installer/package-manifest.in
modules/libpref/src/init/all.js
netwerk/cache/nsDiskCacheDevice.cpp
netwerk/cache/nsDiskCacheEntry.cpp
netwerk/cache/nsDiskCacheMap.cpp
netwerk/protocol/http/nsHttpTransaction.cpp
parser/html/nsHtml5TreeOperation.cpp
parser/htmlparser/public/nsIParserService.h
parser/htmlparser/src/nsExpatDriver.cpp
parser/htmlparser/src/nsParserService.cpp
parser/htmlparser/src/nsParserService.h
services/sync/modules/main.js
services/sync/modules/policies.js
services/sync/modules/resource.js
services/sync/modules/rest.js
services/sync/modules/service.js
services/sync/tests/unit/head_http_server.js
services/sync/tests/unit/test_auth_manager.js
services/sync/tests/unit/test_bookmark_engine.js
services/sync/tests/unit/test_bookmark_smart_bookmarks.js
services/sync/tests/unit/test_clients_engine.js
services/sync/tests/unit/test_corrupt_keys.js
services/sync/tests/unit/test_engine_abort.js
services/sync/tests/unit/test_history_engine.js
services/sync/tests/unit/test_hmac_error.js
services/sync/tests/unit/test_interval_triggers.js
services/sync/tests/unit/test_jpakeclient.js
services/sync/tests/unit/test_records_crypto_generateEntry.js
services/sync/tests/unit/test_syncengine_sync.js
services/sync/tests/unit/test_syncscheduler.js
services/sync/tests/unit/test_utils_ensureOneOpen.js
services/sync/tests/unit/xpcshell.ini
services/sync/version.txt
testing/peptest/tests/firefox/server/mozilla.org/index.html.orig
toolkit/components/places/History.cpp
toolkit/components/viewsource/content/viewPartialSource.js
toolkit/xre/nsAppRunner.cpp
widget/android/AndroidBridge.cpp
widget/android/AndroidBridge.h
widget/android/nsAppShell.cpp
widget/android/nsWindow.cpp
widget/android/nsWindow.h
widget/cocoa/TextInputHandler.h
widget/cocoa/TextInputHandler.mm
widget/cocoa/nsChildView.h
widget/cocoa/nsCocoaWindow.h
widget/cocoa/nsCocoaWindow.mm
widget/gtk2/nsWindow.cpp
widget/gtk2/nsWindow.h
widget/nsGUIEvent.h
widget/nsIWidget.h
widget/windows/nsWindow.h
widget/xpwidgets/nsBaseWidget.cpp
widget/xpwidgets/nsBaseWidget.h
xpcom/ds/nsVariant.h
xpcom/glue/nsCycleCollectionParticipant.h
xpcom/glue/nsISupportsImpl.h
xulrunner/app/profile/extensions/Extensions.rdf
xulrunner/app/profile/extensions/Makefile.in
xulrunner/app/profile/extensions/installed-extensions.txt
--- a/accessible/public/nsIAccessibilityService.h
+++ b/accessible/public/nsIAccessibilityService.h
@@ -80,60 +80,17 @@ public:
    *
    * @param aPresShell  [in] the presshell
    * @param aCanCreate  [in] points whether the root document accessible
    *                        should be returned from the cache or can be created
    */
   virtual nsAccessible* GetRootDocumentAccessible(nsIPresShell* aPresShell,
                                                   bool aCanCreate) = 0;
 
-  /**
-   * Creates accessible for the given DOM node or frame.
-   */
-  virtual already_AddRefed<nsAccessible>
-    CreateHTMLBRAccessible(nsIContent* aContent, nsIPresShell* aPresShell) = 0;
-  virtual already_AddRefed<nsAccessible>
-    CreateHTMLCaptionAccessible(nsIContent* aContent, nsIPresShell* aPresShell) = 0;
-  virtual already_AddRefed<nsAccessible>
-    CreateHTMLCheckboxAccessible(nsIContent* aContent, nsIPresShell* aPresShell) = 0;
-  virtual already_AddRefed<nsAccessible>
-    CreateHTMLComboboxAccessible(nsIContent* aContent, nsIPresShell* aPresShell) = 0;
-  virtual already_AddRefed<nsAccessible>
-    CreateHTMLGroupboxAccessible(nsIContent* aContent, nsIPresShell* aPresShell) = 0;
-  virtual already_AddRefed<nsAccessible>
-    CreateHTMLHRAccessible(nsIContent* aContent, nsIPresShell* aPresShell) = 0;
-  virtual already_AddRefed<nsAccessible>
-    CreateHTMLImageAccessible(nsIContent* aContent, nsIPresShell* aPresShell) = 0;
-  virtual already_AddRefed<nsAccessible>
-    CreateHTMLLabelAccessible(nsIContent* aContent, nsIPresShell* aPresShell) = 0;
-  virtual already_AddRefed<nsAccessible>
-    CreateHTMLLIAccessible(nsIContent* aContent, nsIPresShell* aPresShell) = 0;
-  virtual already_AddRefed<nsAccessible>
-    CreateHTMLListboxAccessible(nsIContent* aContent, nsIPresShell* aPresShell) = 0;
-  virtual already_AddRefed<nsAccessible>
-    CreateHTMLMediaAccessible(nsIContent* aContent, nsIPresShell* aPresShell) = 0;
-  virtual already_AddRefed<nsAccessible>
-    CreateHTMLObjectFrameAccessible(nsObjectFrame* aFrame, nsIContent* aContent,
-                                    nsIPresShell* aPresShell) = 0;
-  virtual already_AddRefed<nsAccessible>
-    CreateHTMLRadioButtonAccessible(nsIContent* aContent, nsIPresShell* aPresShell) = 0;
-  virtual already_AddRefed<nsAccessible>
-    CreateHTMLTableAccessible(nsIContent* aContent, nsIPresShell* aPresShell) = 0;
-  virtual already_AddRefed<nsAccessible>
-    CreateHTMLTableCellAccessible(nsIContent* aContent, nsIPresShell* aPresShell) = 0;
-  virtual already_AddRefed<nsAccessible>
-    CreateHTMLTextAccessible(nsIContent* aContent, nsIPresShell* aPresShell) = 0;
-  virtual already_AddRefed<nsAccessible>
-    CreateHTMLTextFieldAccessible(nsIContent* aContent, nsIPresShell* aPresShell) = 0;
-  virtual already_AddRefed<nsAccessible>
-    CreateHyperTextAccessible(nsIContent* aContent, nsIPresShell* aPresShell) = 0;
-  virtual already_AddRefed<nsAccessible>
-    CreateOuterDocAccessible(nsIContent* aContent, nsIPresShell* aPresShell) = 0;
-
-  /**
+   /**
    * Adds/remove ATK root accessible for gtk+ native window to/from children
    * of the application accessible.
    */
   virtual nsAccessible* AddNativeRootAccessible(void* aAtkAccessible) = 0;
   virtual void RemoveNativeRootAccessible(nsAccessible* aRootAccessible) = 0;
 
   /**
    * Notification used to update the accessible tree when new content is
--- a/accessible/src/base/nsAccessNode.cpp
+++ b/accessible/src/base/nsAccessNode.cpp
@@ -112,22 +112,16 @@ void nsAccessNode::LastRelease()
   // ... then die.
   delete this;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccessNode public
 
 bool
-nsAccessNode::IsDefunct() const
-{
-  return !mContent;
-}
-
-bool
 nsAccessNode::Init()
 {
   return true;
 }
 
 
 void
 nsAccessNode::Shutdown()
@@ -213,17 +207,17 @@ void nsAccessNode::ShutdownXPAccessibili
   }
 
   NotifyA11yInitOrShutdown(false);
 }
 
 // nsAccessNode protected
 nsPresContext* nsAccessNode::GetPresContext()
 {
-  if (IsDefunct())
+  if (!mDoc)
     return nsnull;
 
   nsIPresShell* presShell(mDoc->PresShell());
 
   return presShell ? presShell->GetPresContext() : nsnull;
 }
 
 nsRootAccessible*
@@ -257,17 +251,17 @@ nsAccessNode::IsPrimaryForNode() const
 {
   return true;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 void
 nsAccessNode::ScrollTo(PRUint32 aScrollType)
 {
-  if (IsDefunct())
+  if (!mDoc)
     return;
 
   nsIPresShell* shell = mDoc->PresShell();
   if (!shell)
     return;
 
   nsIFrame *frame = GetFrame();
   if (!frame)
@@ -283,17 +277,17 @@ nsAccessNode::ScrollTo(PRUint32 aScrollT
                                nsIPresShell::SCROLL_OVERFLOW_HIDDEN);
 }
 
 void
 nsAccessNode::Language(nsAString& aLanguage)
 {
   aLanguage.Truncate();
 
-  if (IsDefunct())
+  if (!mDoc)
     return;
 
   nsCoreUtils::GetLanguageFor(mContent, nsnull, aLanguage);
   if (aLanguage.IsEmpty()) { // Nothing found, so use document's language
     mContent->OwnerDoc()->GetHeaderData(nsGkAtoms::headerContentLanguage,
                                         aLanguage);
   }
 }
--- a/accessible/src/base/nsAccessNode.h
+++ b/accessible/src/base/nsAccessNode.h
@@ -101,21 +101,16 @@ public:
   virtual bool Init();
 
   /**
    * Shutdown the access node object.
    */
   virtual void Shutdown();
 
   /**
-   * Returns true when the accessible is defunct.
-   */
-  virtual bool IsDefunct() const;
-
-  /**
    * Return frame for the given access node object.
    */
   virtual nsIFrame* GetFrame() const;
   /**
    * Return DOM node associated with the accessible.
    */
   virtual nsINode* GetNode() const { return mContent; }
   nsIContent* GetContent() const { return mContent; }
--- a/accessible/src/base/nsAccessibilityService.h
+++ b/accessible/src/base/nsAccessibilityService.h
@@ -88,60 +88,60 @@ public:
   NS_DECL_NSIACCESSIBLERETRIEVAL
   NS_DECL_NSIOBSERVER
 
   // nsIAccessibilityService
   virtual nsAccessible* GetRootDocumentAccessible(nsIPresShell* aPresShell,
                                                   bool aCanCreate);
   already_AddRefed<nsAccessible>
     CreateHTMLButtonAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
-  virtual already_AddRefed<nsAccessible>
+  already_AddRefed<nsAccessible>
     CreateHTMLBRAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
   already_AddRefed<nsAccessible>
     CreateHTMLCanvasAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
-  virtual already_AddRefed<nsAccessible>
+  already_AddRefed<nsAccessible>
     CreateHTMLCaptionAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
-  virtual already_AddRefed<nsAccessible>
+  already_AddRefed<nsAccessible>
     CreateHTMLCheckboxAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
-  virtual already_AddRefed<nsAccessible>
+  already_AddRefed<nsAccessible>
     CreateHTMLComboboxAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
   already_AddRefed<nsAccessible>
     CreateHTMLFileInputAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
-  virtual already_AddRefed<nsAccessible>
+  already_AddRefed<nsAccessible>
     CreateHTMLGroupboxAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
-  virtual already_AddRefed<nsAccessible>
+  already_AddRefed<nsAccessible>
     CreateHTMLHRAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
-  virtual already_AddRefed<nsAccessible>
+  already_AddRefed<nsAccessible>
     CreateHTMLImageAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
   already_AddRefed<nsAccessible>
     CreateHTMLImageMapAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
-  virtual already_AddRefed<nsAccessible>
+  already_AddRefed<nsAccessible>
     CreateHTMLLabelAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
-  virtual already_AddRefed<nsAccessible>
+  already_AddRefed<nsAccessible>
     CreateHTMLLIAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
-  virtual already_AddRefed<nsAccessible>
+  already_AddRefed<nsAccessible>
     CreateHTMLListboxAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
-  virtual already_AddRefed<nsAccessible>
+  already_AddRefed<nsAccessible>
     CreateHTMLMediaAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
-  virtual already_AddRefed<nsAccessible>
+  already_AddRefed<nsAccessible>
     CreateHTMLObjectFrameAccessible(nsObjectFrame* aFrame, nsIContent* aContent,
                                     nsIPresShell* aPresShell);
-  virtual already_AddRefed<nsAccessible>
+  already_AddRefed<nsAccessible>
     CreateHTMLRadioButtonAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
-  virtual already_AddRefed<nsAccessible>
+  already_AddRefed<nsAccessible>
     CreateHTMLTableAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
-  virtual already_AddRefed<nsAccessible>
+  already_AddRefed<nsAccessible>
     CreateHTMLTableCellAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
-  virtual already_AddRefed<nsAccessible>
+  already_AddRefed<nsAccessible>
     CreateHTMLTextAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
-  virtual already_AddRefed<nsAccessible>
+  already_AddRefed<nsAccessible>
     CreateHTMLTextFieldAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
-  virtual already_AddRefed<nsAccessible>
+  already_AddRefed<nsAccessible>
     CreateHyperTextAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
-  virtual already_AddRefed<nsAccessible>
+  already_AddRefed<nsAccessible>
     CreateOuterDocAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
 
   virtual nsAccessible* AddNativeRootAccessible(void* aAtkAccessible);
   virtual void RemoveNativeRootAccessible(nsAccessible* aRootAccessible);
 
   virtual void ContentRangeInserted(nsIPresShell* aPresShell,
                                     nsIContent* aContainer,
                                     nsIContent* aStartChild,
--- a/accessible/src/base/nsAccessible.cpp
+++ b/accessible/src/base/nsAccessible.cpp
@@ -1799,57 +1799,54 @@ nsAccessible::GetKeyBindings(PRUint8 aAc
   if (!defaultKey.IsEmpty())
     keyBindings->Add(defaultKey);
 
   NS_ADDREF(*aKeyBindings = keyBindings);
   return NS_OK;
 }
 
 role
-nsAccessible::ARIARoleInternal()
+nsAccessible::ARIATransformRole(role aRole)
 {
-  NS_PRECONDITION(mRoleMapEntry && mRoleMapEntry->roleRule == kUseMapRole,
-                  "ARIARoleInternal should only be called when ARIA role overrides!");
-
   // XXX: these unfortunate exceptions don't fit into the ARIA table. This is
   // where the accessible role depends on both the role and ARIA state.
-  if (mRoleMapEntry->role == roles::PUSHBUTTON) {
+  if (aRole == roles::PUSHBUTTON) {
     if (nsAccUtils::HasDefinedARIAToken(mContent, nsGkAtoms::aria_pressed)) {
       // For simplicity, any existing pressed attribute except "" or "undefined"
       // indicates a toggle.
       return roles::TOGGLE_BUTTON;
     }
 
     if (mContent->AttrValueIs(kNameSpaceID_None,
                               nsGkAtoms::aria_haspopup,
                               nsGkAtoms::_true,
                               eCaseMatters)) {
       // For button with aria-haspopup="true".
       return roles::BUTTONMENU;
     }
 
-  } else if (mRoleMapEntry->role == roles::LISTBOX) {
+  } else if (aRole == roles::LISTBOX) {
     // A listbox inside of a combobox needs a special role because of ATK
     // mapping to menu.
     if (mParent && mParent->Role() == roles::COMBOBOX) {
       return roles::COMBOBOX_LIST;
 
       Relation rel = RelationByType(nsIAccessibleRelation::RELATION_NODE_CHILD_OF);
       nsAccessible* targetAcc = nsnull;
       while ((targetAcc = rel.Next()))
         if (targetAcc->Role() == roles::COMBOBOX)
           return roles::COMBOBOX_LIST;
     }
 
-  } else if (mRoleMapEntry->role == roles::OPTION) {
+  } else if (aRole == roles::OPTION) {
     if (mParent && mParent->Role() == roles::COMBOBOX_LIST)
       return roles::COMBOBOX_OPTION;
   }
 
-  return mRoleMapEntry->role;
+  return aRole;
 }
 
 role
 nsAccessible::NativeRole()
 {
   return nsCoreUtils::IsXLink(mContent) ? roles::LINK : roles::NOTHING;
 }
 
@@ -2514,18 +2511,20 @@ nsAccessible::AppendTextTo(nsAString& aT
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccessNode public methods
 
 void
 nsAccessible::Shutdown()
 {
-  // Invalidate the child count and pointers to other accessibles, also make
-  // sure none of its children point to this parent
+  // Mark the accessible as defunct, invalidate the child count and pointers to 
+  // other accessibles, also make sure none of its children point to this parent
+  mFlags |= eIsDefunct;
+
   InvalidateChildren();
   if (mParent)
     mParent->RemoveChild(this);
 
   nsAccessNodeWrap::Shutdown();
 }
 
 ////////////////////////////////////////////////////////////////////////////////
--- a/accessible/src/base/nsAccessible.h
+++ b/accessible/src/base/nsAccessible.h
@@ -173,19 +173,19 @@ public:
   virtual nsresult GetNameInternal(nsAString& aName);
 
   /**
    * Return enumerated accessible role (see constants in Role.h).
    */
   inline mozilla::a11y::role Role()
   {
     if (!mRoleMapEntry || mRoleMapEntry->roleRule != kUseMapRole)
-      return NativeRole();
+      return ARIATransformRole(NativeRole());
 
-    return ARIARoleInternal();
+    return ARIATransformRole(mRoleMapEntry->role);
   }
 
   /**
    * Return true if ARIA role is specified on the element.
    */
   inline bool HasARIARole() const
   {
     return mRoleMapEntry;
@@ -195,17 +195,17 @@ public:
    * Return accessible role specified by ARIA (see constants in
    * roles).
    */
   inline mozilla::a11y::role ARIARole()
   {
     if (!mRoleMapEntry || mRoleMapEntry->roleRule != kUseMapRole)
       return mozilla::a11y::roles::NOTHING;
 
-    return ARIARoleInternal();
+    return ARIATransformRole(mRoleMapEntry->role);
   }
 
   /**
    * Returns enumerated accessible role from native markup (see constants in
    * Role.h). Doesn't take into account ARIA roles.
    */
   virtual mozilla::a11y::role NativeRole();
 
@@ -638,16 +638,21 @@ public:
    */
   virtual nsAccessible* ContainerWidget() const;
 
   /**
    * Return the localized string for the given key.
    */
   static void TranslateString(const nsAString& aKey, nsAString& aStringOut);
 
+  /**
+   * Return true if the accessible is defunct.
+   */
+  bool IsDefunct() const { return mFlags & eIsDefunct; }
+
 protected:
 
   //////////////////////////////////////////////////////////////////////////////
   // Initializing, cache and tree traverse methods
 
   /**
    * Cache accessible children.
    */
@@ -682,44 +687,52 @@ protected:
 
   /**
    * Set children flag.
    */
   inline void SetChildrenFlag(ChildrenFlags aFlag)
     { mFlags = (mFlags & ~kChildrenFlagsMask) | aFlag; }
 
   /**
-   * Flags describing the accessible itself.
+   * Flags used to describe the state of this accessible.
    * @note keep these flags in sync with ChildrenFlags
    */
+  enum StateFlags {
+    eIsDefunct = 1 << 2 // accessible is defunct
+  };
+
+  /**
+   * Flags describing the type of this accessible.
+   * @note keep these flags in sync with ChildrenFlags and StateFlags
+   */
   enum AccessibleTypes {
-    eApplicationAccessible = 1 << 2,
-    eAutoCompleteAccessible = 1 << 3,
-    eAutoCompletePopupAccessible = 1 << 4,
-    eComboboxAccessible = 1 << 5,
-    eDocAccessible = 1 << 6,
-    eHyperTextAccessible = 1 << 7,
-    eHTMLFileInputAccessible = 1 << 8,
-    eHTMLListItemAccessible = 1 << 9,
-    eImageAccessible = 1 << 10,
-    eImageMapAccessible = 1 << 11,
-    eListControlAccessible = 1 << 12,
-    eMenuButtonAccessible = 1 << 13,
-    eMenuPopupAccessible = 1 << 14,
-    eRootAccessible = 1 << 15,
-    eTextLeafAccessible = 1 << 16
+    eApplicationAccessible = 1 << 3,
+    eAutoCompleteAccessible = 1 << 4,
+    eAutoCompletePopupAccessible = 1 << 5,
+    eComboboxAccessible = 1 << 6,
+    eDocAccessible = 1 << 7,
+    eHyperTextAccessible = 1 << 8,
+    eHTMLFileInputAccessible = 1 << 9,
+    eHTMLListItemAccessible = 1 << 10,
+    eImageAccessible = 1 << 11,
+    eImageMapAccessible = 1 << 12,
+    eListControlAccessible = 1 << 13,
+    eMenuButtonAccessible = 1 << 14,
+    eMenuPopupAccessible = 1 << 15,
+    eRootAccessible = 1 << 16,
+    eTextLeafAccessible = 1 << 17
   };
 
   //////////////////////////////////////////////////////////////////////////////
   // Miscellaneous helpers
 
   /**
    * Return ARIA role (helper method).
    */
-  mozilla::a11y::role ARIARoleInternal();
+  mozilla::a11y::role ARIATransformRole(mozilla::a11y::role aRole);
 
   virtual nsIFrame* GetBoundsFrame();
   virtual void GetBoundsRect(nsRect& aRect, nsIFrame** aRelativeFrame);
 
   //////////////////////////////////////////////////////////////////////////////
   // Name helpers
 
   /**
--- a/accessible/src/base/nsApplicationAccessible.cpp
+++ b/accessible/src/base/nsApplicationAccessible.cpp
@@ -305,22 +305,16 @@ nsApplicationAccessible::GetPlatformVers
   AppendUTF8toUTF16(cversion, aVersion);
   return NS_OK;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccessNode public methods
 
 bool
-nsApplicationAccessible::IsDefunct() const
-{
-  return nsAccessibilityService::IsShutdown();
-}
-
-bool
 nsApplicationAccessible::Init()
 {
   mAppInfo = do_GetService("@mozilla.org/xre/app-info;1");
   return true;
 }
 
 void
 nsApplicationAccessible::Shutdown()
--- a/accessible/src/base/nsApplicationAccessible.h
+++ b/accessible/src/base/nsApplicationAccessible.h
@@ -93,17 +93,16 @@ public:
   NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString &aName);
   NS_IMETHOD GetActionDescription(PRUint8 aIndex, nsAString &aDescription);
   NS_IMETHOD DoAction(PRUint8 aIndex);
 
   // nsIAccessibleApplication
   NS_DECL_NSIACCESSIBLEAPPLICATION
 
   // nsAccessNode
-  virtual bool IsDefunct() const;
   virtual bool Init();
   virtual void Shutdown();
   virtual bool IsPrimaryForNode() const;
 
   // nsAccessible
   virtual void ApplyARIAState(PRUint64* aState);
   virtual void Description(nsString& aDescription);
   virtual mozilla::a11y::role NativeRole();
--- a/accessible/src/base/nsDocAccessible.cpp
+++ b/accessible/src/base/nsDocAccessible.cpp
@@ -688,22 +688,16 @@ nsDocAccessible::GetFrame() const
 {
   nsIFrame* root = nsnull;
   if (mPresShell)
     root = mPresShell->GetRootFrame();
 
   return root;
 }
 
-bool
-nsDocAccessible::IsDefunct() const
-{
-  return nsHyperTextAccessibleWrap::IsDefunct() || !mDocument;
-}
-
 // nsDocAccessible protected member
 void nsDocAccessible::GetBoundsRect(nsRect& aBounds, nsIFrame** aRelativeFrame)
 {
   *aRelativeFrame = GetFrame();
 
   nsIDocument *document = mDocument;
   nsIDocument *parentDoc = nsnull;
 
--- a/accessible/src/base/nsDocAccessible.h
+++ b/accessible/src/base/nsDocAccessible.h
@@ -111,17 +111,16 @@ public:
 
   // nsIDocumentObserver
   NS_DECL_NSIDOCUMENTOBSERVER
 
   // nsAccessNode
   virtual bool Init();
   virtual void Shutdown();
   virtual nsIFrame* GetFrame() const;
-  virtual bool IsDefunct() const;
   virtual nsINode* GetNode() const { return mDocument; }
   virtual nsIDocument* GetDocumentNode() const { return mDocument; }
 
   // nsAccessible
   virtual void Description(nsString& aDescription);
   virtual nsAccessible* FocusedChild();
   virtual mozilla::a11y::role NativeRole();
   virtual PRUint64 NativeState();
--- a/accessible/src/msaa/nsAccessNodeWrap.cpp
+++ b/accessible/src/msaa/nsAccessNodeWrap.cpp
@@ -210,20 +210,21 @@ STDMETHODIMP nsAccessNodeWrap::get_nodeI
     /* [out] */ unsigned int __RPC_FAR *aNumChildren,
     /* [out] */ unsigned int __RPC_FAR *aUniqueID,
     /* [out] */ unsigned short __RPC_FAR *aNodeType)
 {
 __try{
   *aNodeName = nsnull;
   *aNodeValue = nsnull;
 
-  if (IsDefunct())
+  nsINode* node = GetNode();
+  if (!node)
     return E_FAIL;
 
-  nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(GetNode()));
+  nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(node));
 
   PRUint16 nodeType = 0;
   DOMNode->GetNodeType(&nodeType);
   *aNodeType=static_cast<unsigned short>(nodeType);
 
   if (*aNodeType !=  NODETYPE_TEXT) {
     nsAutoString nodeName;
     DOMNode->GetNodeName(nodeName);
@@ -239,17 +240,17 @@ STDMETHODIMP nsAccessNodeWrap::get_nodeI
     static_cast<short>(mContent->GetNameSpaceID()) : 0;
 
   // This is a unique ID for every content node.  The 3rd party
   // accessibility application can compare this to the childID we
   // return for events such as focus events, to correlate back to
   // data nodes in their internal object model.
   *aUniqueID = - NS_PTR_TO_INT32(UniqueID());
 
-  *aNumChildren = GetNode()->GetChildCount();
+  *aNumChildren = node->GetChildCount();
 
 } __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return S_OK;
 }
 
 
        
 STDMETHODIMP nsAccessNodeWrap::get_attributes( 
@@ -257,17 +258,17 @@ STDMETHODIMP nsAccessNodeWrap::get_attri
     /* [length_is][size_is][out] */ BSTR __RPC_FAR *aAttribNames,
     /* [length_is][size_is][out] */ short __RPC_FAR *aNameSpaceIDs,
     /* [length_is][size_is][out] */ BSTR __RPC_FAR *aAttribValues,
     /* [out] */ unsigned short __RPC_FAR *aNumAttribs)
 {
 __try{
   *aNumAttribs = 0;
 
-  if (IsDefunct() || IsDocumentNode())
+  if (!mContent || IsDocumentNode())
     return E_FAIL;
 
   PRUint32 numAttribs = mContent->GetAttrCount();
   if (numAttribs > aMaxAttribs)
     numAttribs = aMaxAttribs;
   *aNumAttribs = static_cast<unsigned short>(numAttribs);
 
   for (PRUint32 index = 0; index < numAttribs; index++) {
@@ -288,17 +289,17 @@ STDMETHODIMP nsAccessNodeWrap::get_attri
 
 STDMETHODIMP nsAccessNodeWrap::get_attributesForNames( 
     /* [in] */ unsigned short aNumAttribs,
     /* [length_is][size_is][in] */ BSTR __RPC_FAR *aAttribNames,
     /* [length_is][size_is][in] */ short __RPC_FAR *aNameSpaceID,
     /* [length_is][size_is][retval] */ BSTR __RPC_FAR *aAttribValues)
 {
 __try {
-  if (IsDefunct() || !IsElement())
+  if (!mContent || !IsElement())
     return E_FAIL;
 
   nsCOMPtr<nsIDOMElement> domElement(do_QueryInterface(mContent));
   nsCOMPtr<nsINameSpaceManager> nameSpaceManager =
     do_GetService(NS_NAMESPACEMANAGER_CONTRACTID);
 
   PRInt32 index;
 
@@ -330,17 +331,17 @@ STDMETHODIMP nsAccessNodeWrap::get_compu
     /* [in] */ boolean aUseAlternateView,
     /* [length_is][size_is][out] */ BSTR __RPC_FAR *aStyleProperties,
     /* [length_is][size_is][out] */ BSTR __RPC_FAR *aStyleValues,
     /* [out] */ unsigned short __RPC_FAR *aNumStyleProperties)
 {
 __try{
   *aNumStyleProperties = 0;
 
-  if (IsDefunct() || IsDocumentNode())
+  if (!mContent || IsDocumentNode())
     return E_FAIL;
 
   nsCOMPtr<nsIDOMCSSStyleDeclaration> cssDecl =
     nsWinUtils::GetComputedStyleDeclaration(mContent);
   NS_ENSURE_TRUE(cssDecl, E_FAIL);
 
   PRUint32 length;
   cssDecl->GetLength(&length);
@@ -365,17 +366,17 @@ STDMETHODIMP nsAccessNodeWrap::get_compu
 
 STDMETHODIMP nsAccessNodeWrap::get_computedStyleForProperties( 
     /* [in] */ unsigned short aNumStyleProperties,
     /* [in] */ boolean aUseAlternateView,
     /* [length_is][size_is][in] */ BSTR __RPC_FAR *aStyleProperties,
     /* [length_is][size_is][out] */ BSTR __RPC_FAR *aStyleValues)
 {
 __try {
-  if (IsDefunct() || IsDocumentNode())
+  if (!mContent || IsDocumentNode())
     return E_FAIL;
  
   nsCOMPtr<nsIDOMCSSStyleDeclaration> cssDecl =
     nsWinUtils::GetComputedStyleDeclaration(mContent);
   NS_ENSURE_TRUE(cssDecl, E_FAIL);
 
   PRUint32 index;
   for (index = 0; index < aNumStyleProperties; index ++) {
@@ -437,89 +438,95 @@ nsAccessNodeWrap::MakeAccessNode(nsINode
 
   return iNode;
 }
 
 
 STDMETHODIMP nsAccessNodeWrap::get_parentNode(ISimpleDOMNode __RPC_FAR *__RPC_FAR *aNode)
 {
 __try {
-  if (IsDefunct())
+  nsINode* node = GetNode();
+  if (!node)
     return E_FAIL;
 
-  *aNode = MakeAccessNode(GetNode()->GetNodeParent());
+  *aNode = MakeAccessNode(node->GetNodeParent());
 
 } __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
 
   return S_OK;
 }
 
 STDMETHODIMP nsAccessNodeWrap::get_firstChild(ISimpleDOMNode __RPC_FAR *__RPC_FAR *aNode)
 {
 __try {
-  if (IsDefunct())
+  nsINode* node = GetNode();
+  if (!node)
     return E_FAIL;
 
-  *aNode = MakeAccessNode(GetNode()->GetFirstChild());
+  *aNode = MakeAccessNode(node->GetFirstChild());
 
 } __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
 
   return S_OK;
 }
 
 STDMETHODIMP nsAccessNodeWrap::get_lastChild(ISimpleDOMNode __RPC_FAR *__RPC_FAR *aNode)
 {
 __try {
-  if (IsDefunct())
+  nsINode* node = GetNode();
+  if (!node)
     return E_FAIL;
 
-  *aNode = MakeAccessNode(GetNode()->GetLastChild());
+  *aNode = MakeAccessNode(node->GetLastChild());
 
 } __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
 
   return S_OK;
 }
 
 STDMETHODIMP nsAccessNodeWrap::get_previousSibling(ISimpleDOMNode __RPC_FAR *__RPC_FAR *aNode)
 {
 __try {
-  if (IsDefunct())
+  nsINode* node = GetNode();
+  if (!node)
     return E_FAIL;
 
-  *aNode = MakeAccessNode(GetNode()->GetPreviousSibling());
+  *aNode = MakeAccessNode(node->GetPreviousSibling());
 
 } __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
 
   return S_OK;
 }
 
 STDMETHODIMP nsAccessNodeWrap::get_nextSibling(ISimpleDOMNode __RPC_FAR *__RPC_FAR *aNode)
 {
 __try {
-  if (IsDefunct())
+  nsINode* node = GetNode();
+  if (!node)
     return E_FAIL;
 
-  *aNode = MakeAccessNode(GetNode()->GetNextSibling());
+  *aNode = MakeAccessNode(node->GetNextSibling());
 
 } __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
 
   return S_OK;
 }
 
 STDMETHODIMP 
 nsAccessNodeWrap::get_childAt(unsigned aChildIndex,
                               ISimpleDOMNode __RPC_FAR *__RPC_FAR *aNode)
 {
 __try {
   *aNode = nsnull;
 
-  if (IsDefunct())
+  nsINode* node = GetNode();
+  if (!node)
     return E_FAIL;
 
-  *aNode = MakeAccessNode(GetNode()->GetChildAt(aChildIndex));
+  *aNode = MakeAccessNode(node->GetChildAt(aChildIndex));
 
 } __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
 
   return S_OK;
 }
 
 STDMETHODIMP 
 nsAccessNodeWrap::get_innerHTML(BSTR __RPC_FAR *aInnerHTML)
--- a/accessible/src/xul/nsXULTreeAccessible.cpp
+++ b/accessible/src/xul/nsXULTreeAccessible.cpp
@@ -119,16 +119,19 @@ nsXULTreeAccessible::NativeState()
 {
   // Get focus status from base class.
   PRUint64 state = nsAccessible::NativeState();
 
   // readonly state
   state |= states::READONLY;
 
   // multiselectable state.
+  if (!mTreeView)
+    return state;
+
   nsCOMPtr<nsITreeSelection> selection;
   mTreeView->GetSelection(getter_AddRefs(selection));
   NS_ENSURE_TRUE(selection, state);
 
   bool isSingle = false;
   nsresult rv = selection->GetSingle(&isSingle);
   NS_ENSURE_SUCCESS(rv, state);
 
@@ -140,17 +143,17 @@ nsXULTreeAccessible::NativeState()
 
 NS_IMETHODIMP
 nsXULTreeAccessible::GetValue(nsAString& aValue)
 {
   // Return the value is the first selected child.
 
   aValue.Truncate();
 
-  if (IsDefunct())
+  if (IsDefunct() || !mTreeView)
     return NS_ERROR_FAILURE;
 
   nsCOMPtr<nsITreeSelection> selection;
   mTreeView->GetSelection(getter_AddRefs(selection));
   if (!selection)
     return NS_ERROR_FAILURE;
 
   PRInt32 currentIndex;
@@ -168,22 +171,16 @@ nsXULTreeAccessible::GetValue(nsAString&
   }
 
   return NS_OK;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsXULTreeAccessible: nsAccessNode implementation
 
-bool
-nsXULTreeAccessible::IsDefunct() const
-{
-  return nsAccessibleWrap::IsDefunct() || !mTree || !mTreeView;
-}
-
 void
 nsXULTreeAccessible::Shutdown()
 {
   // XXX: we don't remove accessible from document cache if shutdown wasn't
   // initiated by document destroying. Note, we can't remove accessible from
   // document cache here while document is going to be shutdown. Note, this is
   // not unique place where we have similar problem.
   ClearCache(mAccessibleCache);
@@ -265,16 +262,19 @@ bool
 nsXULTreeAccessible::IsSelect()
 {
   return true;
 }
 
 nsAccessible*
 nsXULTreeAccessible::CurrentItem()
 {
+  if (!mTreeView)
+    return nsnull;
+
   nsCOMPtr<nsITreeSelection> selection;
   mTreeView->GetSelection(getter_AddRefs(selection));
   if (selection) {
     PRInt32 currentIndex = -1;
     selection->GetCurrentIndex(&currentIndex);
     if (currentIndex >= 0)
       return GetTreeItemAccessible(currentIndex);
   }
@@ -286,16 +286,19 @@ void
 nsXULTreeAccessible::SetCurrentItem(nsAccessible* aItem)
 {
   NS_ERROR("nsXULTreeAccessible::SetCurrentItem not implemented");
 }
 
 already_AddRefed<nsIArray>
 nsXULTreeAccessible::SelectedItems()
 {
+  if (!mTreeView)
+    return nsnull;
+
   nsCOMPtr<nsITreeSelection> selection;
   mTreeView->GetSelection(getter_AddRefs(selection));
   if (!selection)
     return nsnull;
 
   nsCOMPtr<nsIMutableArray> selectedItems =
     do_CreateInstance(NS_ARRAY_CONTRACTID);
   if (!selectedItems)
@@ -316,87 +319,105 @@ nsXULTreeAccessible::SelectedItems()
   nsIMutableArray* items = nsnull;
   selectedItems.forget(&items);
   return items;
 }
 
 PRUint32
 nsXULTreeAccessible::SelectedItemCount()
 {
+  if (!mTreeView)
+    return 0;
+
   nsCOMPtr<nsITreeSelection> selection;
   mTreeView->GetSelection(getter_AddRefs(selection));
   if (selection) {
     PRInt32 count = 0;
     selection->GetCount(&count);
     return count;
   }
 
   return 0;
 }
 
 bool
 nsXULTreeAccessible::AddItemToSelection(PRUint32 aIndex)
 {
+  if (!mTreeView)
+    return false;
+
   nsCOMPtr<nsITreeSelection> selection;
   mTreeView->GetSelection(getter_AddRefs(selection));
   if (selection) {
     bool isSelected = false;
     selection->IsSelected(aIndex, &isSelected);
     if (!isSelected)
       selection->ToggleSelect(aIndex);
 
     return true;
   }
   return false;
 }
 
 bool
 nsXULTreeAccessible::RemoveItemFromSelection(PRUint32 aIndex)
 {
+  if (!mTreeView)
+    return false;
+
   nsCOMPtr<nsITreeSelection> selection;
   mTreeView->GetSelection(getter_AddRefs(selection));
   if (selection) {
     bool isSelected = false;
     selection->IsSelected(aIndex, &isSelected);
     if (isSelected)
       selection->ToggleSelect(aIndex);
 
     return true;
   }
   return false;
 }
 
 bool
 nsXULTreeAccessible::IsItemSelected(PRUint32 aIndex)
 {
+  if (!mTreeView)
+    return false;
+
   nsCOMPtr<nsITreeSelection> selection;
   mTreeView->GetSelection(getter_AddRefs(selection));
   if (selection) {
     bool isSelected = false;
     selection->IsSelected(aIndex, &isSelected);
     return isSelected;
   }
   return false;
 }
 
 bool
 nsXULTreeAccessible::UnselectAll()
 {
+  if (!mTreeView)
+    return false;
+
   nsCOMPtr<nsITreeSelection> selection;
   mTreeView->GetSelection(getter_AddRefs(selection));
   if (!selection)
     return false;
 
   selection->ClearSelection();
   return true;
 }
 
 nsAccessible*
 nsXULTreeAccessible::GetSelectedItem(PRUint32 aIndex)
 {
+  if (!mTreeView)
+    return nsnull;
+
   nsCOMPtr<nsITreeSelection> selection;
   mTreeView->GetSelection(getter_AddRefs(selection));
   if (!selection)
     return nsnull;
 
   PRUint32 selCount = 0;
   PRInt32 rangeCount = 0;
   selection->GetRangeCount(&rangeCount);
@@ -413,16 +434,19 @@ nsXULTreeAccessible::GetSelectedItem(PRU
 
   return nsnull;
 }
 
 bool
 nsXULTreeAccessible::SelectAll()
 {
   // see if we are multiple select if so set ourselves as such
+  if (!mTreeView)
+    return false;
+
   nsCOMPtr<nsITreeSelection> selection;
   mTreeView->GetSelection(getter_AddRefs(selection));
   if (selection) {
     bool single = false;
     selection->GetSingle(&single);
     if (!single) {
       selection->SelectAll();
       return true;
@@ -448,18 +472,18 @@ nsXULTreeAccessible::GetChildAt(PRUint32
   return GetTreeItemAccessible(aIndex - childCount);
 }
 
 PRInt32
 nsXULTreeAccessible::GetChildCount()
 {
   // tree's children count is row count + treecols count.
   PRInt32 childCount = nsAccessible::GetChildCount();
-  if (childCount == -1)
-    return -1;
+  if (childCount == -1 || !mTreeView)
+    return childCount;
 
   PRInt32 rowCount = 0;
   mTreeView->GetRowCount(&rowCount);
   childCount += rowCount;
 
   return childCount;
 }
 
@@ -531,17 +555,17 @@ nsXULTreeAccessible::ContainerWidget() c
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsXULTreeAccessible: public implementation
 
 nsAccessible*
 nsXULTreeAccessible::GetTreeItemAccessible(PRInt32 aRow)
 {
-  if (aRow < 0 || IsDefunct())
+  if (aRow < 0 || IsDefunct() || !mTreeView)
     return nsnull;
 
   PRInt32 rowCount = 0;
   nsresult rv = mTreeView->GetRowCount(&rowCount);
   if (NS_FAILED(rv) || aRow >= rowCount)
     return nsnull;
 
   void *key = reinterpret_cast<void*>(aRow);
@@ -788,17 +812,17 @@ nsXULTreeItemAccessibleBase::GetBounds(P
   *aHeight = presContext->CSSPixelsToDevPixels(height);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXULTreeItemAccessibleBase::SetSelected(bool aSelect)
 {
-  if (IsDefunct())
+  if (IsDefunct() || !mTreeView)
     return NS_ERROR_FAILURE;
 
   nsCOMPtr<nsITreeSelection> selection;
   mTreeView->GetSelection(getter_AddRefs(selection));
   if (selection) {
     bool isSelected;
     selection->IsSelected(mRow, &isSelected);
     if (isSelected != aSelect)
@@ -806,35 +830,38 @@ nsXULTreeItemAccessibleBase::SetSelected
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXULTreeItemAccessibleBase::TakeFocus()
 {
-  if (IsDefunct())
+  if (IsDefunct() || !mTreeView)
     return NS_ERROR_FAILURE;
 
   nsCOMPtr<nsITreeSelection> selection;
   mTreeView->GetSelection(getter_AddRefs(selection));
   if (selection)
     selection->SetCurrentIndex(mRow);
 
   // focus event will be fired here
   return nsAccessible::TakeFocus();
 }
 
 Relation
 nsXULTreeItemAccessibleBase::RelationByType(PRUint32 aType)
 {
+  if (!mTreeView)
+    return Relation();
+
   if (aType != nsIAccessibleRelation::RELATION_NODE_CHILD_OF)
     return Relation();
 
-    PRInt32 parentIndex;
+  PRInt32 parentIndex = -1;
   if (!NS_SUCCEEDED(mTreeView->GetParentIndex(mRow, &parentIndex)))
     return Relation();
 
   if (parentIndex == -1)
     return Relation(mParent);
 
   nsRefPtr<nsXULTreeAccessible> treeAcc = do_QueryObject(mParent);
   return Relation(treeAcc->GetTreeItemAccessible(parentIndex));
@@ -885,22 +912,16 @@ nsXULTreeItemAccessibleBase::DoAction(PR
 
   DoCommand(nsnull, aIndex);
   return NS_OK;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsXULTreeItemAccessibleBase: nsAccessNode implementation
 
-bool
-nsXULTreeItemAccessibleBase::IsDefunct() const
-{
-  return nsAccessibleWrap::IsDefunct() || !mTree || !mTreeView || mRow < 0;
-}
-
 void
 nsXULTreeItemAccessibleBase::Shutdown()
 {
   mTree = nsnull;
   mTreeView = nsnull;
   mRow = -1;
 
   nsAccessibleWrap::Shutdown();
@@ -925,17 +946,17 @@ nsXULTreeItemAccessibleBase::GroupPositi
   *aGroupLevel = 0;
 
   NS_ENSURE_ARG_POINTER(aSimilarItemsInGroup);
   *aSimilarItemsInGroup = 0;
 
   NS_ENSURE_ARG_POINTER(aPositionInGroup);
   *aPositionInGroup = 0;
 
-  if (IsDefunct())
+  if (IsDefunct() || !mTreeView)
     return NS_ERROR_FAILURE;
 
   PRInt32 level;
   nsresult rv = mTreeView->GetLevel(mRow, &level);
   NS_ENSURE_SUCCESS(rv, rv);
 
   PRInt32 topCount = 1;
   for (PRInt32 index = mRow - 1; index >= 0; index--) {
@@ -973,16 +994,19 @@ nsXULTreeItemAccessibleBase::GroupPositi
   *aPositionInGroup = posInSet;
 
   return NS_OK;
 }
 
 PRUint64
 nsXULTreeItemAccessibleBase::NativeState()
 {
+  if (!mTreeView)
+    return states::DEFUNCT;
+
   // focusable and selectable states
   PRUint64 state = states::FOCUSABLE | states::SELECTABLE;
 
   // expanded/collapsed state
   if (IsExpandable()) {
     bool isContainerOpen;
     mTreeView->IsContainerOpen(mRow, &isContainerOpen);
     state |= isContainerOpen ? states::EXPANDED : states::COLLAPSED;
@@ -1070,16 +1094,19 @@ nsXULTreeItemAccessibleBase::GetSiblingA
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsXULTreeItemAccessibleBase: protected implementation
 
 bool
 nsXULTreeItemAccessibleBase::IsExpandable()
 {
+  if (!mTreeView)
+    return false;
+
   bool isContainer = false;
   mTreeView->IsContainer(mRow, &isContainer);
   if (isContainer) {
     bool isEmpty = false;
     mTreeView->IsContainerEmpty(mRow, &isEmpty);
     if (!isEmpty) {
       nsCOMPtr<nsITreeColumns> columns;
       mTree->GetColumns(getter_AddRefs(columns));
@@ -1095,16 +1122,19 @@ nsXULTreeItemAccessibleBase::IsExpandabl
 
   return false;
 }
 
 void
 nsXULTreeItemAccessibleBase::GetCellName(nsITreeColumn* aColumn,
                                          nsAString& aName)
 {
+  if (!mTreeView)
+    return;
+
   mTreeView->GetCellText(mRow, aColumn, aName);
 
   // If there is still no name try the cell value:
   // This is for graphical cells. We need tree/table view implementors to
   // implement FooView::GetCellValue to return a meaningful string for cases
   // where there is something shown in the cell (non-text) such as a star icon;
   // in which case GetCellValue for that cell would return "starred" or
   // "flagged" for example.
@@ -1160,22 +1190,16 @@ nsXULTreeItemAccessible::GetName(nsAStri
   GetCellName(mColumn, aName);
   return NS_OK;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsXULTreeItemAccessible: nsAccessNode implementation
 
 bool
-nsXULTreeItemAccessible::IsDefunct() const
-{
-  return nsXULTreeItemAccessibleBase::IsDefunct() || !mColumn;
-}
-
-bool
 nsXULTreeItemAccessible::Init()
 {
   if (!nsXULTreeItemAccessibleBase::Init())
     return false;
 
   GetName(mCachedName);
   return true;
 }
--- a/accessible/src/xul/nsXULTreeAccessible.h
+++ b/accessible/src/xul/nsXULTreeAccessible.h
@@ -73,17 +73,16 @@ public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsXULTreeAccessible,
                                            nsAccessible)
 
   // nsIAccessible
   NS_IMETHOD GetValue(nsAString& aValue);
 
   // nsAccessNode
-  virtual bool IsDefunct() const;
   virtual void Shutdown();
 
   // nsAccessible
   virtual mozilla::a11y::role NativeRole();
   virtual PRUint64 NativeState();
   virtual nsAccessible* ChildAtPoint(PRInt32 aX, PRInt32 aY,
                                      EWhichChildAtPoint aWhichChild);
 
@@ -199,17 +198,16 @@ public:
   NS_IMETHOD GroupPosition(PRInt32 *aGroupLevel,
                            PRInt32 *aSimilarItemsInGroup,
                            PRInt32 *aPositionInGroup);
 
   NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
   NS_IMETHOD DoAction(PRUint8 aIndex);
 
   // nsAccessNode
-  virtual bool IsDefunct() const;
   virtual void Shutdown();
   virtual bool IsPrimaryForNode() const;
 
   // nsAccessible
   virtual PRUint64 NativeState();
   virtual PRInt32 IndexInParent() const;
   virtual Relation RelationByType(PRUint32 aType);
   virtual nsAccessible* FocusedChild();
@@ -282,17 +280,16 @@ public:
   // nsISupports and cycle collection
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsXULTreeItemAccessible,
                                            nsXULTreeItemAccessibleBase)
 
   NS_IMETHOD GetName(nsAString& aName);
 
   // nsAccessNode
-  virtual bool IsDefunct() const;
   virtual bool Init();
   virtual void Shutdown();
 
   // nsAccessible
   virtual mozilla::a11y::role NativeRole();
 
   // nsXULTreeItemAccessibleBase
   virtual void RowInvalidated(PRInt32 aStartColIdx, PRInt32 aEndColIdx);
--- a/accessible/src/xul/nsXULTreeGridAccessible.cpp
+++ b/accessible/src/xul/nsXULTreeGridAccessible.cpp
@@ -88,25 +88,28 @@ nsXULTreeGridAccessible::GetColumnCount(
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
   *aColumnCount = nsCoreUtils::GetSensibleColumnCount(mTree);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsXULTreeGridAccessible::GetRowCount(PRInt32 *arowCount)
+nsXULTreeGridAccessible::GetRowCount(PRInt32* aRowCount)
 {
-  NS_ENSURE_ARG_POINTER(arowCount);
-  *arowCount = nsnull;
+  NS_ENSURE_ARG_POINTER(aRowCount);
+  *aRowCount = 0;
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
-  return mTreeView->GetRowCount(arowCount);
+  if (!mTreeView)
+    return NS_OK;
+
+  return mTreeView->GetRowCount(aRowCount);
 }
 
 NS_IMETHODIMP
 nsXULTreeGridAccessible::GetSelectedCellCount(PRUint32* aCount)
 {
   NS_ENSURE_ARG_POINTER(aCount);
   *aCount = 0;
 
@@ -171,16 +174,19 @@ nsXULTreeGridAccessible::GetSelectedRowC
 }
 
 NS_IMETHODIMP
 nsXULTreeGridAccessible::GetSelectedCells(nsIArray **aCells)
 {
   NS_ENSURE_ARG_POINTER(aCells);
   *aCells = nsnull;
 
+  if (!mTreeView)
+    return NS_OK;
+
   nsCOMPtr<nsIMutableArray> selCells = do_CreateInstance(NS_ARRAY_CONTRACTID);
   NS_ENSURE_TRUE(selCells, NS_ERROR_FAILURE);
 
   PRInt32 selectedrowCount = 0;
   nsresult rv = GetSelectionCount(&selectedrowCount);
   NS_ENSURE_SUCCESS(rv, rv);
 
   PRInt32 columnCount = 0;
@@ -215,16 +221,19 @@ NS_IMETHODIMP
 nsXULTreeGridAccessible::GetSelectedCellIndices(PRUint32 *aCellsCount,
                                                 PRInt32 **aCells)
 {
   NS_ENSURE_ARG_POINTER(aCellsCount);
   *aCellsCount = 0;
   NS_ENSURE_ARG_POINTER(aCells);
   *aCells = nsnull;
 
+  if (!mTreeView)
+    return NS_OK;
+
   PRInt32 selectedrowCount = 0;
   nsresult rv = GetSelectionCount(&selectedrowCount);
   NS_ENSURE_SUCCESS(rv, rv);
 
   PRInt32 columnCount = 0;
   rv = GetColumnCount(&columnCount);
   NS_ENSURE_SUCCESS(rv, rv);
 
@@ -304,16 +313,19 @@ nsXULTreeGridAccessible::GetSelectedRowI
   NS_ENSURE_ARG_POINTER(arowCount);
   *arowCount = 0;
   NS_ENSURE_ARG_POINTER(aRows);
   *aRows = nsnull;
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
+  if (!mTreeView)
+    return NS_OK;
+
   PRInt32 selectedrowCount = 0;
   nsresult rv = GetSelectionCount(&selectedrowCount);
   NS_ENSURE_SUCCESS(rv, rv);
 
   PRInt32* outArray = static_cast<PRInt32*>(
     nsMemory::Alloc(selectedrowCount * sizeof(PRInt32)));
   NS_ENSURE_TRUE(outArray, NS_ERROR_OUT_OF_MEMORY);
 
@@ -510,16 +522,19 @@ NS_IMETHODIMP
 nsXULTreeGridAccessible::IsRowSelected(PRInt32 aRowIndex, bool *aIsSelected)
 {
   NS_ENSURE_ARG_POINTER(aIsSelected);
   *aIsSelected = false;
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
+  if (!mTreeView)
+    return NS_ERROR_INVALID_ARG;
+
   nsCOMPtr<nsITreeSelection> selection;
   nsresult rv = mTreeView->GetSelection(getter_AddRefs(selection));
   NS_ENSURE_SUCCESS(rv, rv);
   
   return selection->IsSelected(aRowIndex, aIsSelected);
 }
 
 NS_IMETHODIMP
@@ -527,32 +542,38 @@ nsXULTreeGridAccessible::IsCellSelected(
                                         bool *aIsSelected)
 {
   return IsRowSelected(aRowIndex, aIsSelected);
 }
 
 NS_IMETHODIMP
 nsXULTreeGridAccessible::SelectRow(PRInt32 aRowIndex)
 {
+  if (!mTreeView)
+    return NS_ERROR_INVALID_ARG;
+
   nsCOMPtr<nsITreeSelection> selection;
   mTreeView->GetSelection(getter_AddRefs(selection));
   NS_ENSURE_STATE(selection);
 
   return selection->Select(aRowIndex);
 }
 
 NS_IMETHODIMP
 nsXULTreeGridAccessible::SelectColumn(PRInt32 aColumnIndex)
 {
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXULTreeGridAccessible::UnselectRow(PRInt32 aRowIndex)
 {
+  if (!mTreeView)
+    return NS_ERROR_INVALID_ARG;
+
   nsCOMPtr<nsITreeSelection> selection;
   mTreeView->GetSelection(getter_AddRefs(selection));
   NS_ENSURE_STATE(selection);
 
   return selection->ClearRange(aRowIndex, aRowIndex);
 }
 
 NS_IMETHODIMP
@@ -849,17 +870,17 @@ nsXULTreeGridCellAccessible::FocusedChil
   return nsnull;
 }
 
 NS_IMETHODIMP
 nsXULTreeGridCellAccessible::GetName(nsAString& aName)
 {
   aName.Truncate();
 
-  if (IsDefunct())
+  if (IsDefunct() || !mTreeView)
     return NS_ERROR_FAILURE;
 
   mTreeView->GetCellText(mRow, mColumn, aName);
 
   // If there is still no name try the cell value:
   // This is for graphical cells. We need tree/table view implementors to implement
   // FooView::GetCellValue to return a meaningful string for cases where there is
   // something shown in the cell (non-text) such as a star icon; in which case
@@ -931,17 +952,17 @@ nsXULTreeGridCellAccessible::ActionCount
 NS_IMETHODIMP
 nsXULTreeGridCellAccessible::GetActionName(PRUint8 aIndex, nsAString& aName)
 {
   aName.Truncate();
 
   if (aIndex != eAction_Click)
     return NS_ERROR_INVALID_ARG;
 
-  if (IsDefunct())
+  if (IsDefunct() || !mTreeView)
     return NS_ERROR_FAILURE;
 
   bool isCycler = false;
   mColumn->GetCycler(&isCycler);
   if (isCycler) {
     aName.AssignLiteral("cycle");
     return NS_OK;
   }
@@ -1098,40 +1119,33 @@ nsXULTreeGridCellAccessible::GetRowHeade
 }
 
 NS_IMETHODIMP
 nsXULTreeGridCellAccessible::IsSelected(bool *aIsSelected)
 {
   NS_ENSURE_ARG_POINTER(aIsSelected);
   *aIsSelected = false;
 
-  if (IsDefunct())
+  if (IsDefunct() || !mTreeView)
     return NS_ERROR_FAILURE;
 
   nsCOMPtr<nsITreeSelection> selection;
   nsresult rv = mTreeView->GetSelection(getter_AddRefs(selection));
   NS_ENSURE_SUCCESS(rv, rv);
 
   return selection->IsSelected(mRow, aIsSelected);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsXULTreeGridCellAccessible: nsAccessNode implementation
 
 bool
-nsXULTreeGridCellAccessible::IsDefunct() const
-{
-  return nsLeafAccessible::IsDefunct() || !mParent || !mTree || !mTreeView ||
-    !mColumn;
-}
-
-bool
 nsXULTreeGridCellAccessible::Init()
 {
-  if (!nsLeafAccessible::Init())
+  if (!nsLeafAccessible::Init() || !mTreeView)
     return false;
 
   PRInt16 type;
   mColumn->GetType(&type);
   if (type == nsITreeColumn::TYPE_CHECKBOX)
     mTreeView->GetCellValue(mRow, mColumn, mCachedTextEquiv);
   else
     mTreeView->GetCellText(mRow, mColumn, mCachedTextEquiv);
@@ -1191,16 +1205,19 @@ role
 nsXULTreeGridCellAccessible::NativeRole()
 {
   return roles::GRID_CELL;
 }
 
 PRUint64
 nsXULTreeGridCellAccessible::NativeState()
 {
+  if (!mTreeView)
+    return states::DEFUNCT;
+
   // selectable/selected state
   PRUint64 states = states::SELECTABLE;
 
   nsCOMPtr<nsITreeSelection> selection;
   mTreeView->GetSelection(getter_AddRefs(selection));
   if (selection) {
     bool isSelected = false;
     selection->IsSelected(mRow, &isSelected);
@@ -1250,16 +1267,19 @@ nsXULTreeGridCellAccessible::GetColumnIn
   }
 
   return index;
 }
 
 void
 nsXULTreeGridCellAccessible::CellInvalidated()
 {
+  if (!mTreeView)
+    return;
+
   nsAutoString textEquiv;
 
   PRInt16 type;
   mColumn->GetType(&type);
   if (type == nsITreeColumn::TYPE_CHECKBOX) {
     mTreeView->GetCellValue(mRow, mColumn, textEquiv);
     if (mCachedTextEquiv != textEquiv) {
       bool isEnabled = textEquiv.EqualsLiteral("true");
@@ -1321,16 +1341,19 @@ nsXULTreeGridCellAccessible::DispatchCli
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsXULTreeGridCellAccessible: protected implementation
 
 bool
 nsXULTreeGridCellAccessible::IsEditable() const
 {
+  if (!mTreeView)
+    return false;
+
   // XXX: logic corresponds to tree.xml, it's preferable to have interface
   // method to check it.
   bool isEditable = false;
   nsresult rv = mTreeView->IsEditable(mRow, mColumn, &isEditable);
   if (NS_FAILED(rv) || !isEditable)
     return false;
 
   nsCOMPtr<nsIDOMElement> columnElm;
--- a/accessible/src/xul/nsXULTreeGridAccessible.h
+++ b/accessible/src/xul/nsXULTreeGridAccessible.h
@@ -156,17 +156,16 @@ public:
 
   NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
   NS_IMETHOD DoAction(PRUint8 aIndex);
 
   // nsIAccessibleTableCell
   NS_DECL_NSIACCESSIBLETABLECELL
 
   // nsAccessNode
-  virtual bool IsDefunct() const;
   virtual bool Init();
   virtual bool IsPrimaryForNode() const;
 
   // nsAccessible
   virtual nsAccessible* FocusedChild();
   virtual nsresult GetAttributesInternal(nsIPersistentProperties *aAttributes);
   virtual PRInt32 IndexInParent() const;
   virtual Relation RelationByType(PRUint32 aType);
--- a/accessible/tests/mochitest/test_aria_roles.html
+++ b/accessible/tests/mochitest/test_aria_roles.html
@@ -63,16 +63,20 @@ https://bugzilla.mozilla.org/show_bug.cg
       // abstract roles
       var abstract_roles = ["composite", "landmark", "structure", "widget",
                             "window", "input", "range", "select", "section",
                             "sectionhead"];
       for (a in abstract_roles)
         testRole(abstract_roles[a], ROLE_SECTION);
 
       //////////////////////////////////////////////////////////////////////////
+      // roles transformed by ARIA state attributes
+      testRole("togglebutton", ROLE_TOGGLE_BUTTON);
+
+      //////////////////////////////////////////////////////////////////////////
       // misc roles
       testRole("note", ROLE_NOTE);
       testRole("scrollbar", ROLE_SCROLLBAR);
       testRole("dir", ROLE_LIST);
 
       //////////////////////////////////////////////////////////////////////////
       // test document role map update
       var testDoc = getAccessible(document, [nsIAccessibleDocument]);
@@ -90,16 +94,21 @@ https://bugzilla.mozilla.org/show_bug.cg
 <body>
 
   <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=481114">Mozilla Bug 481114</a>
   <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=469688">Mozilla Bug 469688</a>
   <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=469688">Mozilla Bug 520188</a>
   <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=529289">Mozilla Bug 529289</a>
   <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=529289">Mozilla Bug 607219</a>
   <a target="_blank"
+     title="HTML buttons with aria-pressed not exposing IA2 TOGGLE_BUTTON role"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=725432">
+    Bug 725432
+  </a>
+  <a target="_blank"
      title="Map ARIA role FORM"
      href="https://bugzilla.mozilla.org/show_bug.cgi?id=735645">
     Bug 735645
   </a>
   <p id="display"></p>
   <div id="content" style="display: none"></div>
   <pre id="test">
   </pre>
@@ -157,16 +166,19 @@ https://bugzilla.mozilla.org/show_bug.cg
   <!-- test abstract input roles -->
   <div role="input" id="input">input</div>
   <div role="range" id="range">range</div>
   <div role="select" id="select">select</div>
   <!-- test abstract structure roles -->
   <div role="section" id="section">section</div>
   <div role="sectionhead" id="sectionhead">sectionhead</div>
 
+  <!-- roles transformed by ARIA state attributes -->
+  <button aria-pressed="true" id="togglebutton">
+
   <!-- misc roles -->
   <div role="note" id="note">note</div>
   <div role="scrollbar" id="scrollbar">scrollbar</div>
 
   <div id="dir" role="directory">
     <div role="listitem">A</div>
     <div role="listitem">B</div>
     <div role="listitem">C</div>
--- a/b2g/installer/package-manifest.in
+++ b/b2g/installer/package-manifest.in
@@ -292,16 +292,18 @@
 @BINPATH@/components/xul.xpt
 @BINPATH@/components/xuldoc.xpt
 @BINPATH@/components/xultmpl.xpt
 @BINPATH@/components/zipwriter.xpt
 
 ; JavaScript components
 @BINPATH@/components/ConsoleAPI.manifest
 @BINPATH@/components/ConsoleAPI.js
+@BINPATH@/components/BrowserElementAPI.manifest
+@BINPATH@/components/BrowserElementAPI.js
 @BINPATH@/components/ContactManager.js
 @BINPATH@/components/ContactManager.manifest
 @BINPATH@/components/FeedProcessor.manifest
 @BINPATH@/components/FeedProcessor.js
 @BINPATH@/components/BrowserFeeds.manifest
 @BINPATH@/components/FeedConverter.js
 @BINPATH@/components/FeedWriter.js
 @BINPATH@/components/fuelApplication.manifest
deleted file mode 100644
--- a/browser/app/profile/extensions/Extensions.rdf
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0"?>
-
-<RDF xmlns:em="http://www.mozilla.org/2004/em-rdf#"
-     xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
-
-  <Seq about="urn:mozilla:item:root"/>
-
-</RDF>
deleted file mode 100644
--- a/browser/app/profile/extensions/installed-extensions.txt
+++ /dev/null
@@ -1,1 +0,0 @@
-theme,{972ce4c6-7e08-4474-a285-3208198ce6fd}
--- a/browser/base/content/abouthome/aboutHome.css
+++ b/browser/base/content/abouthome/aboutHome.css
@@ -42,17 +42,16 @@
 %endif
 
 html {
   font: message-box;
   font-size: 100%;
   background-color: hsl(0,0%,90%);
   background-image: url(chrome://browser/content/abouthome/noise.png),
                     -moz-linear-gradient(hsla(0,0%,100%,.7), hsla(0,0%,100%,.4));
-  background-attachment: fixed;
   color: #000;
   height: 100%;
 }
 
 body {
   margin: 0;
   display: -moz-box;
   -moz-box-orient: vertical;
--- a/browser/base/content/abouthome/aboutHome.xhtml
+++ b/browser/base/content/abouthome/aboutHome.xhtml
@@ -92,17 +92,17 @@
     <div class="spacer"/>
 
     <div id="launcher" session="true">
       <button class="launchButton" id="downloads">&abouthome.downloadsButton.label;</button>
       <button class="launchButton" id="bookmarks">&abouthome.bookmarksButton.label;</button>
       <button class="launchButton" id="history">&abouthome.historyButton.label;</button>
       <button class="launchButton" id="apps" hidden="true">&abouthome.appsButton.label;</button>
       <button class="launchButton" id="addons">&abouthome.addonsButton.label;</button>
-      <button class="launchButton" id="sync">&syncBrand.shortName.label;</button>
+      <button class="launchButton" id="sync">&abouthome.syncButton.label;</button>
       <button class="launchButton" id="settings">&abouthome.settingsButton.label;</button>
       <div id="restorePreviousSessionSeparator"/>
       <button class="launchButton" id="restorePreviousSession">&historyRestoreLastSession.label;</button>
     </div>
 
     <a id="aboutMozilla" href="http://www.mozilla.org/about/"/>
   </body>
 </html>
--- a/browser/base/content/browser-tabview.js
+++ b/browser/base/content/browser-tabview.js
@@ -96,19 +96,16 @@ let TabView = {
     goSetCommandEnabled("Browser:ToggleTabView", window.toolbar.visible);
     if (!window.toolbar.visible)
       return;
 
     if (this._initialized)
       return;
 
     if (this.firstUseExperienced) {
-      if ((gBrowser.tabs.length - gBrowser.visibleTabs.length) > 0)
-        this._setBrowserKeyHandlers();
-
       // ___ visibility
       let sessionstore =
         Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);
 
       let data = sessionstore.getWindowValue(window, this.VISIBILITY_IDENTIFIER);
       if (data && data == "true") {
         this.show();
       } else {
@@ -136,16 +133,28 @@ let TabView = {
         this._tabCloseEventListener = function(event) {
           if (!self._window && gBrowser.visibleTabs.length == 0)
             self._closedLastVisibleTabBeforeFrameInitialized = true;
         };
         gBrowser.tabContainer.addEventListener(
           "TabShow", this._tabShowEventListener, false);
         gBrowser.tabContainer.addEventListener(
           "TabClose", this._tabCloseEventListener, false);
+
+       if (this._tabBrowserHasHiddenTabs()) {
+         this._setBrowserKeyHandlers();
+       } else {
+         // for restoring last session and undoing recently closed window
+         this._SSWindowStateReadyListener = function (event) {
+           if (this._tabBrowserHasHiddenTabs())
+             this._setBrowserKeyHandlers();
+         }.bind(this);
+         window.addEventListener(
+           "SSWindowStateReady", this._SSWindowStateReadyListener, false);
+        }
       }
     }
 
     Services.prefs.addObserver(this.PREF_BRANCH, this, false);
 
     this._initialized = true;
   },
 
@@ -169,16 +178,20 @@ let TabView = {
     if (this._tabShowEventListener)
       gBrowser.tabContainer.removeEventListener(
         "TabShow", this._tabShowEventListener, false);
 
     if (this._tabCloseEventListener)
       gBrowser.tabContainer.removeEventListener(
         "TabClose", this._tabCloseEventListener, false);
 
+    if (this._SSWindowStateReadyListener)
+      window.removeEventListener(
+        "SSWindowStateReady", this._SSWindowStateReadyListener, false);
+
     this._initialized = false;
   },
 
   // ----------
   // Creates the frame and calls the callback once it's loaded. 
   // If the frame already exists, calls the callback immediately. 
   _initFrame: function TabView__initFrame(callback) {
     let hasCallback = typeof callback == "function";
@@ -225,16 +238,22 @@ let TabView = {
           "TabShow", self._tabShowEventListener, false);
         self._tabShowEventListener = null;
       }
       if (self._tabCloseEventListener) {
         gBrowser.tabContainer.removeEventListener(
           "TabClose", self._tabCloseEventListener, false);
         self._tabCloseEventListener = null;
       }
+      if (self._SSWindowStateReadyListener) {
+        window.removeEventListener(
+          "SSWindowStateReady", self._SSWindowStateReadyListener, false);
+        self._SSWindowStateReadyListener = null;
+      }
+
       self._initFrameCallbacks.forEach(function (cb) cb());
       self._initFrameCallbacks = [];
     }, false);
 
     this._iframe.setAttribute("src", "chrome://browser/content/tabview.html");
     this._deck.appendChild(this._iframe);
 
     // ___ create tooltip
@@ -277,16 +296,21 @@ let TabView = {
   toggle: function TabView_toggle() {
     if (this.isVisible())
       this.hide();
     else 
       this.show();
   },
 
   // ----------
+  _tabBrowserHasHiddenTabs: function TabView_tabBrowserHasHiddenTabs() {
+    return (gBrowser.tabs.length - gBrowser.visibleTabs.length) > 0;
+  },
+
+  // ----------
   updateContextMenu: function TabView_updateContextMenu(tab, popup) {
     let separator = document.getElementById("context_tabViewNamedGroups");
     let isEmpty = true;
 
     while (popup.firstChild && popup.firstChild != separator)
       popup.removeChild(popup.firstChild);
 
     let self = this;
@@ -338,18 +362,17 @@ let TabView = {
   _setBrowserKeyHandlers: function TabView__setBrowserKeyHandlers() {
     if (this._browserKeyHandlerInitialized)
       return;
 
     this._browserKeyHandlerInitialized = true;
 
     let self = this;
     window.addEventListener("keypress", function(event) {
-      if (self.isVisible() ||
-          (gBrowser.tabs.length - gBrowser.visibleTabs.length) == 0)
+      if (self.isVisible() || !self._tabBrowserHasHiddenTabs())
         return;
 
       let charCode = event.charCode;
       // Control (+ Shift) + `
       if (event.ctrlKey && !event.metaKey && !event.altKey &&
           (charCode == 96 || charCode == 126)) {
         event.stopPropagation();
         event.preventDefault();
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -2301,17 +2301,17 @@ function BrowserOpenFileWindow()
     fp.displayDirectory = gLastOpenDirectory.path;
 
     if (fp.show() == nsIFilePicker.returnOK) {
       try {
         if (fp.file)
           gLastOpenDirectory.path = fp.file.parent.QueryInterface(Ci.nsILocalFile);
       } catch(e) {
       }
-      openTopWin(fp.fileURL.spec);
+      openUILinkIn(fp.fileURL.spec, "current");
     }
   } catch (ex) {
   }
 }
 
 function BrowserCloseTabOrWindow() {
 #ifdef XP_MACOSX
   // If we're not a browser window, just close the window
@@ -5410,16 +5410,17 @@ var TabsOnTop = {
     let enabled = userEnabled && gBrowser.tabContainer.visible;
 
     document.getElementById("cmd_ToggleTabsOnTop")
             .setAttribute("checked", userEnabled);
 
     document.documentElement.setAttribute("tabsontop", enabled);
     document.getElementById("navigator-toolbox").setAttribute("tabsontop", enabled);
     document.getElementById("TabsToolbar").setAttribute("tabsontop", enabled);
+    document.getElementById("nav-bar").setAttribute("tabsontop", enabled);
     gBrowser.tabContainer.setAttribute("tabsontop", enabled);
     TabsInTitlebar.allowedBy("tabs-on-top", enabled);
   },
 
   get enabled () {
     return gNavToolbox.getAttribute("tabsontop") == "true";
   },
 
@@ -7819,23 +7820,30 @@ function undoCloseWindow(aIndex) {
   return window;
 }
 
 /*
  * Determines if a tab is "empty", usually used in the context of determining
  * if it's ok to close the tab.
  */
 function isTabEmpty(aTab) {
+  if (aTab.hasAttribute("busy"))
+    return false;
+
   let browser = aTab.linkedBrowser;
-  let uri = browser.currentURI.spec;
-  let body = browser.contentDocument.body;
-  return browser.sessionHistory.count < 2 &&
-         isBlankPageURL(uri) &&
-         (!body || !body.hasChildNodes()) &&
-         !aTab.hasAttribute("busy");
+  if (!isBlankPageURL(browser.currentURI.spec))
+    return false;
+
+  if (browser.contentWindow.opener)
+    return false;
+
+  if (browser.sessionHistory && browser.sessionHistory.count >= 2)
+    return false;
+
+  return true;
 }
 
 #ifdef MOZ_SERVICES_SYNC
 function BrowserOpenSyncTabs() {
   switchToTabHavingURI("about:sync-tabs", true);
 }
 #endif
 
--- a/browser/base/content/sync/addDevice.js
+++ b/browser/base/content/sync/addDevice.js
@@ -78,17 +78,17 @@ let gSyncAddDevice = {
         this.pin1.focus();
         break;
       case SYNC_KEY_PAGE:
         this.wizard.canAdvance = false;
         this.wizard.canRewind = true;
         this.wizard.getButton("back").hidden = false;
         this.wizard.getButton("next").hidden = true;
         document.getElementById("weavePassphrase").value =
-          Weave.Utils.hyphenatePassphrase(Weave.Service.passphrase);
+          Weave.Utils.hyphenatePassphrase(Weave.Identity.syncKey);
         break;
       case DEVICE_CONNECTED_PAGE:
         this.wizard.canAdvance = true;
         this.wizard.canRewind = false;
         this.wizard.getButton("cancel").hidden = true;
         break;
     }
   },
@@ -108,19 +108,19 @@ let gSyncAddDevice = {
   startTransfer: function startTransfer() {
     this.errorRow.hidden = true;
     // When onAbort is called, Weave may already be gone.
     const JPAKE_ERROR_USERABORT = Weave.JPAKE_ERROR_USERABORT;
 
     let self = this;
     let jpakeclient = this._jpakeclient = new Weave.JPAKEClient({
       onPaired: function onPaired() {
-        let credentials = {account:   Weave.Service.account,
-                           password:  Weave.Service.password,
-                           synckey:   Weave.Service.passphrase,
+        let credentials = {account:   Weave.Identity.account,
+                           password:  Weave.Identity.basicPassword,
+                           synckey:   Weave.Identity.syncKey,
                            serverURL: Weave.Service.serverURL};
         jpakeclient.sendAndComplete(credentials);
       },
       onComplete: function onComplete() {
         delete self._jpakeclient;
         self.wizard.pageIndex = DEVICE_CONNECTED_PAGE;
 
         // Schedule a Sync for soonish to fetch the data uploaded by the
--- a/browser/base/content/sync/genericChange.js
+++ b/browser/base/content/sync/genericChange.js
@@ -101,17 +101,17 @@ let Change = {
           introText.textContent = this._str("new.recoverykey.introText");
           this._dialog.getButton("finish").label
             = this._str("new.recoverykey.acceptButton");
         }
         else {
           document.getElementById("generatePassphraseButton").hidden = false;
           document.getElementById("passphraseBackupButtons").hidden = false;
           this._passphraseBox.setAttribute("readonly", "true");
-          let pp = Weave.Service.passphrase;
+          let pp = Weave.Identity.syncKey;
           if (Weave.Utils.isPassphrase(pp))
              pp = Weave.Utils.hyphenatePassphrase(pp);
           this._passphraseBox.value = pp;
           this._passphraseBox.focus();
           document.title = this._str("change.recoverykey.title");
           introText.textContent = this._str("change.synckey.introText2");
           warningText.textContent = this._str("change.recoverykey.warningText");
           this._dialog.getButton("finish").label
@@ -188,17 +188,17 @@ let Change = {
     let passphrase = Weave.Utils.generatePassphrase();
     this._passphraseBox.value = Weave.Utils.hyphenatePassphrase(passphrase);
     this._dialog.getButton("finish").disabled = false;
   },
 
   doChangePassphrase: function Change_doChangePassphrase() {
     let pp = Weave.Utils.normalizePassphrase(this._passphraseBox.value);
     if (this._updatingPassphrase) {
-      Weave.Service.passphrase = pp;
+      Weave.Identity.syncKey = pp;
       if (Weave.Service.login()) {
         this._updateStatus("change.recoverykey.success", "success");
         Weave.Service.persistLogin();
         Weave.SyncScheduler.delayedAutoConnect(0);
       }
       else {
         this._updateStatus("new.passphrase.status.incorrect", "error");
       }
@@ -212,17 +212,17 @@ let Change = {
         this._updateStatus("change.recoverykey.error", "error");
     }
 
     return false;
   },
 
   doChangePassword: function Change_doChangePassword() {
     if (this._currentPasswordInvalid) {
-      Weave.Service.password = this._firstBox.value;
+      Weave.Identity.basicPassword = this._firstBox.value;
       if (Weave.Service.login()) {
         this._updateStatus("change.password.status.success", "success");
         Weave.Service.persistLogin();
       }
       else {
         this._updateStatus("new.password.status.incorrect", "error");
       }
     }
--- a/browser/base/content/sync/setup.js
+++ b/browser/base/content/sync/setup.js
@@ -174,23 +174,23 @@ var gSyncSetup = {
     } else {
       this.wizard.pageIndex = EXISTING_ACCOUNT_CONNECT_PAGE;
     }
   },
 
   resetPassphrase: function resetPassphrase() {
     // Apply the existing form fields so that
     // Weave.Service.changePassphrase() has the necessary credentials.
-    Weave.Service.account = document.getElementById("existingAccountName").value;
-    Weave.Service.password = document.getElementById("existingPassword").value;
+    Weave.Identity.account = document.getElementById("existingAccountName").value;
+    Weave.Identity.basicPassword = document.getElementById("existingPassword").value;
 
     // Generate a new passphrase so that Weave.Service.login() will
     // actually do something.
     let passphrase = Weave.Utils.generatePassphrase();
-    Weave.Service.passphrase = passphrase;
+    Weave.Identity.syncKey = passphrase;
 
     // Only open the dialog if username + password are actually correct.
     Weave.Service.login();
     if ([Weave.LOGIN_FAILED_INVALID_PASSPHRASE,
          Weave.LOGIN_FAILED_NO_PASSPHRASE,
          Weave.LOGIN_SUCCEEDED].indexOf(Weave.Status.login) == -1) {
       return;
     }
@@ -204,37 +204,37 @@ var gSyncSetup = {
     // changePassphrase() will sync, make sure we set the "firstSync" pref
     // according to the user's pref.
     Weave.Svc.Prefs.reset("firstSync");
     this.setupInitialSync();
     gSyncUtils.resetPassphrase(true);
   },
 
   onResetPassphrase: function () {
-    document.getElementById("existingPassphrase").value = 
-      Weave.Utils.hyphenatePassphrase(Weave.Service.passphrase);
+    document.getElementById("existingPassphrase").value =
+      Weave.Utils.hyphenatePassphrase(Weave.Identity.syncKey);
     this.checkFields();
     this.wizard.advance();
   },
 
   onLoginStart: function () {
     this.toggleLoginFeedback(false);
   },
 
   onLoginEnd: function () {
     this.toggleLoginFeedback(true);
   },
 
   sendCredentialsAfterSync: function () {
     let send = function() {
       Services.obs.removeObserver("weave:service:sync:finish", send);
       Services.obs.removeObserver("weave:service:sync:error", send);
-      let credentials = {account:   Weave.Service.account,
-                         password:  Weave.Service.password,
-                         synckey:   Weave.Service.passphrase,
+      let credentials = {account:   Weave.Identity.account,
+                         password:  Weave.Identity.basicPassword,
+                         synckey:   Weave.Identity.syncKey,
                          serverURL: Weave.Service.serverURL};
       this._jpakeclient.sendAndComplete(credentials);
     }.bind(this);
     Services.obs.addObserver("weave:service:sync:finish", send, false);
     Services.obs.addObserver("weave:service:sync:error", send, false);
   },
 
   toggleLoginFeedback: function (stop) {
@@ -363,17 +363,17 @@ var gSyncSetup = {
         else
           str = availCheck;
       }
     }
 
     this._setFeedbackMessage(feedback, valid, str);
     this.status.email = valid;
     if (valid)
-      Weave.Service.account = value;
+      Weave.Identity.account = value;
     this.checkFields();
   },
 
   onPasswordChange: function () {
     let password = document.getElementById("weavePassword");
     let pwconfirm = document.getElementById("weavePasswordConfirm");
     let [valid, errorString] = gSyncUtils.validatePassword(password, pwconfirm);
 
@@ -499,34 +499,35 @@ var gSyncSetup = {
           document.getElementById("weaveEmail").value);
         let challenge = getField("challenge");
         let response = getField("response");
 
         let error = Weave.Service.createAccount(email, password,
                                                 challenge, response);
 
         if (error == null) {
-          Weave.Service.account = email;
-          Weave.Service.password = password;
-          Weave.Service.passphrase = Weave.Utils.generatePassphrase();
+          Weave.Identity.account = email;
+          Weave.Identity.basicPassword = password;
+          Weave.Identity.syncKey = Weave.Utils.generatePassphrase();
           this._handleNoScript(false);
           Weave.Svc.Prefs.set("firstSync", "newAccount");
           this.wizardFinish();
           return false;
         }
 
         image.setAttribute("status", "error");
         label.value = Weave.Utils.getErrorString(error);
         return false;
       case EXISTING_ACCOUNT_LOGIN_PAGE:
-        Weave.Service.account = Weave.Utils.normalizeAccount(
+        Weave.Identity.account = Weave.Utils.normalizeAccount(
           document.getElementById("existingAccountName").value);
-        Weave.Service.password = document.getElementById("existingPassword").value;
+        Weave.Identity.basicPassword =
+          document.getElementById("existingPassword").value;
         let pp = document.getElementById("existingPassphrase").value;
-        Weave.Service.passphrase = Weave.Utils.normalizePassphrase(pp);
+        Weave.Identity.syncKey = Weave.Utils.normalizePassphrase(pp);
         if (Weave.Service.login()) {
           this.wizardFinish();
         }
         return false;
       case OPTIONS_PAGE:
         let desc = document.getElementById("mergeChoiceRadio").selectedIndex;
         // No confirmation needed on new account setup or merge option
         // with existing account.
@@ -695,19 +696,19 @@ var gSyncSetup = {
         document.getElementById("easySetupPIN1").value = pin.slice(0, 4);
         document.getElementById("easySetupPIN2").value = pin.slice(4, 8);
         document.getElementById("easySetupPIN3").value = pin.slice(8);
       },
 
       onPairingStart: function onPairingStart() {},
 
       onComplete: function onComplete(credentials) {
-        Weave.Service.account = credentials.account;
-        Weave.Service.password = credentials.password;
-        Weave.Service.passphrase = credentials.synckey;
+        Weave.Identity.account = credentials.account;
+        Weave.Identity.basicPassword = credentials.password;
+        Weave.Identity.syncKey = credentials.synckey;
         Weave.Service.serverURL = credentials.serverURL;
         gSyncSetup.wizardFinish();
       },
 
       onAbort: function onAbort(error) {
         delete self._jpakeclient;
 
         // Ignore if wizard is aborted.
--- a/browser/base/content/sync/utils.js
+++ b/browser/base/content/sync/utils.js
@@ -222,23 +222,23 @@ let gSyncUtils = {
   validatePassword: function (el1, el2) {
     let valid = false;
     let val1 = el1.value;
     let val2 = el2 ? el2.value : "";
     let error = "";
 
     if (!el2)
       valid = val1.length >= Weave.MIN_PASS_LENGTH;
-    else if (val1 && val1 == Weave.Service.username)
+    else if (val1 && val1 == Weave.Identity.username)
       error = "change.password.pwSameAsUsername";
-    else if (val1 && val1 == Weave.Service.account)
+    else if (val1 && val1 == Weave.Identity.account)
       error = "change.password.pwSameAsEmail";
-    else if (val1 && val1 == Weave.Service.password)
+    else if (val1 && val1 == Weave.Identity.basicPassword)
       error = "change.password.pwSameAsPassword";
-    else if (val1 && val1 == Weave.Service.passphrase)
+    else if (val1 && val1 == Weave.Identity.syncKey)
       error = "change.password.pwSameAsRecoveryKey";
     else if (val1 && val2) {
       if (val1 == val2 && val1.length >= Weave.MIN_PASS_LENGTH)
         valid = true;
       else if (val1.length < Weave.MIN_PASS_LENGTH)
         error = "change.password.tooShort";
       else if (val1 != val2)
         error = "change.password.mismatch";
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -541,39 +541,53 @@
                   }
 
                   if (this.mTab.selected)
                     this.mTabBrowser.mIsBusy = true;
                 }
               }
               else if (aStateFlags & nsIWebProgressListener.STATE_STOP &&
                        aStateFlags & nsIWebProgressListener.STATE_IS_NETWORK) {
-                if (aWebProgress.DOMWindow == this.mBrowser.contentWindow) {
-                  // The document is done loading, we no longer want the
-                  // value cleared.
-                  if (this.mBrowser.userTypedClear > 1)
-                    this.mBrowser.userTypedClear -= 2;
-                  else if (this.mBrowser.userTypedClear > 0)
-                    this.mBrowser.userTypedClear--;
-
-                  if (!this.mBrowser.mIconURL)
-                    this.mTabBrowser.useDefaultIcon(this.mTab);
-                }
-
-                if (this.mBlank)
-                  this.mBlank = false;
 
                 if (this.mTab.hasAttribute("busy")) {
                   this.mTab.removeAttribute("busy");
                   this.mTabBrowser._tabAttrModified(this.mTab);
                   if (!this.mTab.selected)
                     this.mTab.setAttribute("unread", "true");
                 }
                 this.mTab.removeAttribute("progress");
 
+                if (aWebProgress.DOMWindow == this.mBrowser.contentWindow) {
+                  if (!Components.isSuccessCode(aStatus) &&
+                      !isTabEmpty(this.mTab)) {
+                    // Restore the current document's location in case the
+                    // request was stopped (possibly from a content script)
+                    // before the location changed.
+
+                    this.mBrowser.userTypedValue = null;
+
+                    if (this.mTab.selected && gURLBar)
+                      URLBarSetURI();
+                  } else {
+                    // The document is done loading, we no longer want the
+                    // value cleared.
+
+                    if (this.mBrowser.userTypedClear > 1)
+                      this.mBrowser.userTypedClear -= 2;
+                    else if (this.mBrowser.userTypedClear > 0)
+                      this.mBrowser.userTypedClear--;
+                  }
+
+                  if (!this.mBrowser.mIconURL)
+                    this.mTabBrowser.useDefaultIcon(this.mTab);
+                }
+
+                if (this.mBlank)
+                  this.mBlank = false;
+
                 var location = aRequest.QueryInterface(nsIChannel).URI;
 
                 // For keyword URIs clear the user typed value since they will be changed into real URIs
                 if (location.scheme == "keyword")
                   this.mBrowser.userTypedValue = null;
 
                 if (this.mTab.label == this.mTabBrowser.mStringBundle.getString("tabs.connecting"))
                   this.mTabBrowser.setTabTitle(this.mTab);
--- a/browser/base/content/test/Makefile.in
+++ b/browser/base/content/test/Makefile.in
@@ -221,16 +221,17 @@ endif
                  browser_tab_dragdrop2_frame1.xul \
                  browser_tabfocus.js \
                  browser_tabs_isActive.js \
                  browser_tabs_owner.js \
                  browser_urlbarAutoFillTrimURLs.js \
                  browser_urlbarCopying.js \
                  browser_urlbarEnter.js \
                  browser_urlbarRevert.js \
+                 browser_urlbarStop.js \
                  browser_urlbarTrimURLs.js \
                  browser_urlHighlight.js \
                  browser_visibleFindSelection.js \
                  browser_visibleTabs.js \
                  browser_visibleTabs_contextMenu.js \
                  browser_visibleTabs_bookmarkAllPages.js \
                  browser_visibleTabs_bookmarkAllTabs.js \
                  browser_visibleTabs_tabPreview.js \
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/browser_urlbarStop.js
@@ -0,0 +1,40 @@
+const goodURL = "http://mochi.test:8888/";
+const badURL = "http://mochi.test:8888/whatever.html";
+
+function test() {
+  waitForExplicitFinish();
+
+  gBrowser.selectedTab = gBrowser.addTab(goodURL);
+  gBrowser.selectedBrowser.addEventListener("load", onload, true);
+}
+
+function onload() {
+  gBrowser.selectedBrowser.removeEventListener("load", onload, true);
+
+  is(gURLBar.value, gURLBar.trimValue(goodURL), "location bar reflects loaded page");
+
+  typeAndSubmit(badURL);
+  is(gURLBar.value, gURLBar.trimValue(badURL), "location bar reflects loading page");
+
+  gBrowser.contentWindow.stop();
+  is(gURLBar.value, gURLBar.trimValue(goodURL), "location bar reflects loaded page after stop()");
+  gBrowser.removeCurrentTab();
+
+  gBrowser.selectedTab = gBrowser.addTab("about:blank");
+  is(gURLBar.value, "", "location bar is empty");
+
+  typeAndSubmit(badURL);
+  is(gURLBar.value, gURLBar.trimValue(badURL), "location bar reflects loading page");
+
+  gBrowser.contentWindow.stop();
+  is(gURLBar.value, gURLBar.trimValue(badURL), "location bar reflects stopped page in an empty tab");
+  gBrowser.removeCurrentTab();
+
+  finish();
+}
+
+function typeAndSubmit(value) {
+  gBrowser.userTypedValue = value;
+  URLBarSetURI();
+  gURLBar.handleCommand();
+}
--- a/browser/base/content/utilityOverlay.js
+++ b/browser/base/content/utilityOverlay.js
@@ -90,19 +90,19 @@ function getTopWin(skipPopups) {
   if (skipPopups) {
     return Components.classes["@mozilla.org/browser/browserglue;1"]
                      .getService(Components.interfaces.nsIBrowserGlue)
                      .getMostRecentBrowserWindow();
   }
   return Services.wm.getMostRecentWindow("navigator:browser");
 }
 
-function openTopWin( url )
-{
-  openUILink(url, {})
+function openTopWin(url) {
+  /* deprecated */
+  openUILinkIn(url, "current");
 }
 
 function getBoolPref(prefname, def)
 {
   try {
     return Services.prefs.getBoolPref(prefname);
   }
   catch(er) {
--- a/browser/branding/nightly/pref/firefox-branding.js
+++ b/browser/branding/nightly/pref/firefox-branding.js
@@ -1,9 +1,9 @@
-pref("startup.homepage_override_url","http://www.mozilla.org/projects/%APP%/%VERSION%/whatsnew/");
+pref("startup.homepage_override_url","http://www.mozilla.org/projects/%APP%/%VERSION%/whatsnew/?oldversion=%OLD_VERSION%");
 pref("startup.homepage_welcome_url","http://www.mozilla.org/projects/%APP%/%VERSION%/firstrun/");
 // The time interval between checks for a new version (in seconds)
 pref("app.update.interval", 3600); // 1 hour
 // The time interval between the downloading of mar file chunks in the
 // background (in seconds)
 pref("app.update.download.backgroundInterval", 60);
 // Give the user x seconds to react before showing the big UI. default=1 hour
 pref("app.update.promptWaitTime", 3600);
--- a/browser/branding/official/pref/firefox-branding.js
+++ b/browser/branding/official/pref/firefox-branding.js
@@ -1,9 +1,9 @@
-pref("startup.homepage_override_url","http://www.mozilla.com/%LOCALE%/%APP%/%VERSION%/whatsnew/");
+pref("startup.homepage_override_url","http://www.mozilla.com/%LOCALE%/%APP%/%VERSION%/whatsnew/?oldversion=%OLD_VERSION%");
 pref("startup.homepage_welcome_url","http://www.mozilla.com/%LOCALE%/%APP%/%VERSION%/firstrun/");
 // Interval: Time between checks for a new version (in seconds)
 // nightly=6 hours, official=24 hours
 pref("app.update.interval", 86400);
 // The time interval between the downloading of mar file chunks in the
 // background (in seconds)
 pref("app.update.download.backgroundInterval", 600);
 // Give the user x seconds to react before showing the big UI. default=24 hours
--- a/browser/components/nsBrowserContentHandler.js
+++ b/browser/components/nsBrowserContentHandler.js
@@ -576,16 +576,25 @@ nsBrowserContentHandler.prototype = {
 
   get defaultArgs() {
     var prefb = Components.classes["@mozilla.org/preferences-service;1"]
                           .getService(nsIPrefBranch);
 
     var overridePage = "";
     var haveUpdateSession = false;
     try {
+      // Read the old value of homepage_override.mstone before
+      // needHomepageOverride updates it, so that we can later add it to the
+      // URL if we do end up showing an overridePage. This makes it possible
+      // to have the overridePage's content vary depending on the version we're
+      // upgrading from.
+      let old_mstone = "unknown";
+      try {
+        old_mstone = Services.prefs.getCharPref("browser.startup.homepage_override.mstone");
+      } catch (ex) {}
       let override = needHomepageOverride(prefb);
       if (override != OVERRIDE_NONE) {
         // Setup the default search engine to about:home page.
         AboutHomeUtils.loadDefaultSearchEngine();
         AboutHomeUtils.loadSnippetsURL();
 
         switch (override) {
           case OVERRIDE_NEW_PROFILE:
@@ -599,16 +608,18 @@ nsBrowserContentHandler.prototype = {
             // Check whether we have a session to restore. If we do, we assume
             // that this is an "update" session.
             var ss = Components.classes["@mozilla.org/browser/sessionstartup;1"]
                                .getService(Components.interfaces.nsISessionStartup);
             haveUpdateSession = ss.doRestore();
             overridePage = Services.urlFormatter.formatURLPref("startup.homepage_override_url");
             if (prefb.prefHasUserValue("app.update.postupdate"))
               overridePage = getPostUpdateOverridePage(overridePage);
+
+            overridePage = overridePage.replace("%OLD_VERSION%", old_mstone);
             break;
         }
       }
       else {
         // No need to override homepage, but update snippets url if the pref has
         // been manually changed.
         if (Services.prefs.prefHasUserValue(AboutHomeUtils.SNIPPETS_URL_PREF)) {
           AboutHomeUtils.loadSnippetsURL();
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -1203,43 +1203,16 @@ BrowserGlue.prototype = {
     } catch(ex) {}
     if (currentUIVersion >= UI_VERSION)
       return;
 
     this._rdf = Cc["@mozilla.org/rdf/rdf-service;1"].getService(Ci.nsIRDFService);
     this._dataSource = this._rdf.GetDataSource("rdf:local-store");
     this._dirty = false;
 
-    if (currentUIVersion < 1) {
-      // this code should always migrate pre-FF3 profiles to the current UI state
-      let currentsetResource = this._rdf.GetResource("currentset");
-      let toolbars = ["nav-bar", "toolbar-menubar", "PersonalToolbar"];
-      for (let i = 0; i < toolbars.length; i++) {
-        let toolbar = this._rdf.GetResource(BROWSER_DOCURL + toolbars[i]);
-        let currentset = this._getPersist(toolbar, currentsetResource);
-        if (!currentset) {
-          // toolbar isn't customized
-          if (i == 0)
-            // new button is in the defaultset, nothing to migrate
-            break;
-          continue;
-        }
-        if (/(?:^|,)unified-back-forward-button(?:$|,)/.test(currentset))
-          // new button is already there, nothing to migrate
-          break;
-        if (/(?:^|,)back-button(?:$|,)/.test(currentset)) {
-          let newset = currentset.replace(/(^|,)back-button($|,)/,
-                                          "$1unified-back-forward-button,back-button$2")
-          this._setPersist(toolbar, currentsetResource, newset);
-          // done migrating
-          break;
-        }
-      }
-    }
-
     if (currentUIVersion < 2) {
       // This code adds the customizable bookmarks button.
       let currentsetResource = this._rdf.GetResource("currentset");
       let toolbarResource = this._rdf.GetResource(BROWSER_DOCURL + "nav-bar");
       let currentset = this._getPersist(toolbarResource, currentsetResource);
       // Need to migrate only if toolbar is customized and the element is not found.
       if (currentset &&
           currentset.indexOf("bookmarks-menu-button-container") == -1) {
--- a/browser/components/places/content/sidebarUtils.js
+++ b/browser/components/places/content/sidebarUtils.js
@@ -131,11 +131,16 @@ var SidebarUtils = {
       else
         this.setMouseoverURL("");
     }
     else
       this.setMouseoverURL("");
   },
 
   setMouseoverURL: function SU_setMouseoverURL(aURL) {
-    window.top.XULBrowserWindow.setOverLink(aURL, null);
+    // When the browser window is closed with an open sidebar, the sidebar
+    // unload event happens after the browser's one.  In this case
+    // top.XULBrowserWindow has been nullified already.
+    if (top.XULBrowserWindow) {
+      top.XULBrowserWindow.setOverLink(aURL, null);
+    }
   }
 };
--- a/browser/components/preferences/sync.js
+++ b/browser/components/preferences/sync.js
@@ -96,17 +96,17 @@ let gSyncPane = {
     if (Weave.Status.service == Weave.CLIENT_NOT_CONFIGURED ||
         Weave.Svc.Prefs.get("firstSync", "") == "notReady") {
       this.page = PAGE_NO_ACCOUNT;
     } else if (Weave.Status.login == Weave.LOGIN_FAILED_INVALID_PASSPHRASE ||
                Weave.Status.login == Weave.LOGIN_FAILED_LOGIN_REJECTED) {
       this.needsUpdate();
     } else {
       this.page = PAGE_HAS_ACCOUNT;
-      document.getElementById("accountName").value = Weave.Service.account;
+      document.getElementById("accountName").value = Weave.Identity.account;
       document.getElementById("syncComputerName").value = Weave.Clients.localName;
       document.getElementById("tosPP").hidden = this._usingCustomServer;
     }
   },
 
   startOver: function (showDialog) {
     if (showDialog) {
       let flags = Services.prompt.BUTTON_POS_0 * Services.prompt.BUTTON_TITLE_IS_STRING +
--- a/browser/components/sessionstore/src/nsSessionStore.js
+++ b/browser/components/sessionstore/src/nsSessionStore.js
@@ -2085,19 +2085,16 @@ SessionStoreService.prototype = {
    * go through all tabs and store the current scroll positions
    * and innerHTML content of WYSIWYG editors
    * @param aWindow
    *        Window reference
    */
   _updateTextAndScrollData: function sss_updateTextAndScrollData(aWindow) {
     var browsers = aWindow.gBrowser.browsers;
     this._windows[aWindow.__SSi].tabs.forEach(function (tabData, i) {
-      if (browsers[i].__SS_data &&
-          browsers[i].__SS_tabStillLoading)
-        return; // ignore incompletely initialized tabs
       try {
         this._updateTextAndScrollDataForTab(aWindow, browsers[i], tabData);
       }
       catch (ex) { debug(ex); } // get as much data as possible, ignore failures (might succeed the next time)
     }, this);
   },
 
   /**
@@ -2109,16 +2106,20 @@ SessionStoreService.prototype = {
    *        single browser reference
    * @param aTabData
    *        tabData object to add the information to
    * @param aFullData
    *        always return privacy sensitive data (use with care)
    */
   _updateTextAndScrollDataForTab:
     function sss_updateTextAndScrollDataForTab(aWindow, aBrowser, aTabData, aFullData) {
+    // we shouldn't update data for incompletely initialized tabs
+    if (aBrowser.__SS_data && aBrowser.__SS_tabStillLoading)
+      return;
+
     var tabIndex = (aTabData.index || aTabData.entries.length) - 1;
     // entry data needn't exist for tabs just initialized with an incomplete session state
     if (!aTabData.entries[tabIndex])
       return;
     
     let selectedPageStyle = aBrowser.markupDocumentViewer.authorStyleDisabled ? "_nostyle" :
                             this._getSelectedPageStyle(aBrowser.contentWindow);
     if (selectedPageStyle)
@@ -2729,32 +2730,43 @@ SessionStoreService.prototype = {
         tabbrowser.unpinTab(tabbrowser.tabs[t]);
     }
 
     // make sure that the selected tab won't be closed in order to
     // prevent unnecessary flickering
     if (aOverwriteTabs && tabbrowser.selectedTab._tPos >= newTabCount)
       tabbrowser.moveTabTo(tabbrowser.selectedTab, newTabCount - 1);
 
+    let numVisibleTabs = 0;
+
     for (var t = 0; t < newTabCount; t++) {
       tabs.push(t < openTabCount ?
                 tabbrowser.tabs[t] :
                 tabbrowser.addTab("about:blank", {skipAnimation: true}));
       // when resuming at startup: add additionally requested pages to the end
       if (!aOverwriteTabs && root._firstTabs) {
         tabbrowser.moveTabTo(tabs[t], t);
       }
 
       if (winData.tabs[t].pinned)
         tabbrowser.pinTab(tabs[t]);
 
-      if (winData.tabs[t].hidden)
+      if (winData.tabs[t].hidden) {
         tabbrowser.hideTab(tabs[t]);
-      else
+      }
+      else {
         tabbrowser.showTab(tabs[t]);
+        numVisibleTabs++;
+      }
+    }
+
+    // if all tabs to be restored are hidden, make the first one visible
+    if (!numVisibleTabs && winData.tabs.length) {
+      winData.tabs[0].hidden = false;
+      tabbrowser.showTab(tabs[0]);
     }
 
     // If overwriting tabs, we want to reset each tab's "restoring" state. Since
     // we're overwriting those tabs, they should no longer be restoring. The
     // tabs will be rebuilt and marked if they need to be restored after loading
     // state (in restoreHistoryPrecursor).
     if (aOverwriteTabs) {
       for (let i = 0; i < tabbrowser.tabs.length; i++) {
@@ -2874,20 +2886,17 @@ SessionStoreService.prototype = {
       // this is normally done in restoreHistory() but as we're returning early
       // here we need to take care of it.
       this._setWindowStateReady(aWindow);
       return;
     }
 
     let unhiddenTabs = aTabData.filter(function (aData) !aData.hidden).length;
 
-    // if all tabs to be restored are hidden, make the first one visible
-    if (unhiddenTabs == 0) {
-      aTabData[0].hidden = false;
-    } else if (aTabs.length > 1) {
+    if (unhiddenTabs && aTabs.length > 1) {
       // Load hidden tabs last, by pushing them to the end of the list
       for (let t = 0, tabsToReorder = aTabs.length - unhiddenTabs; tabsToReorder > 0; ) {
         if (aTabData[t].hidden) {
           aTabs = aTabs.concat(aTabs.splice(t, 1));
           aTabData = aTabData.concat(aTabData.splice(t, 1));
           if (aSelectTab > t)
             --aSelectTab;
           --tabsToReorder;
--- a/browser/components/sessionstore/test/Makefile.in
+++ b/browser/components/sessionstore/test/Makefile.in
@@ -154,18 +154,20 @@ include $(topsrcdir)/config/rules.mk
 	browser_645428.js \
 	browser_659591.js \
 	browser_662812.js \
 	browser_665702-state_session.js \
 	browser_682507.js \
 	browser_687710.js \
 	browser_687710_2.js \
 	browser_694378.js \
+	browser_701377.js \
 	browser_705597.js \
 	browser_707862.js \
+	browser_739805.js \
 	$(NULL)
 
 ifneq ($(OS_ARCH),Darwin)
 _BROWSER_TEST_FILES += \
 	browser_597071.js \
 	browser_625016.js \
 	$(NULL)
 endif
new file mode 100644
--- /dev/null
+++ b/browser/components/sessionstore/test/browser_701377.js
@@ -0,0 +1,49 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+let state = {windows:[{tabs:[
+  {entries:[{url:"http://example.com#1"}]},
+  {entries:[{url:"http://example.com#2"}], hidden: true}
+]}]};
+
+function test() {
+  waitForExplicitFinish();
+
+  newWindowWithState(state, function (aWindow) {
+    let tab = aWindow.gBrowser.tabs[1];
+    ok(tab.hidden, "the second tab is hidden");
+
+    let tabShown = false;
+    let tabShowCallback = function () tabShown = true;
+    tab.addEventListener("TabShow", tabShowCallback, false);
+
+    let tabState = ss.getTabState(tab);
+    ss.setTabState(tab, tabState);
+
+    tab.removeEventListener("TabShow", tabShowCallback, false);
+    ok(tab.hidden && !tabShown, "tab remains hidden");
+
+    finish();
+  });
+}
+
+// ----------
+function whenWindowLoaded(aWindow, aCallback) {
+  aWindow.addEventListener("load", function onLoad() {
+    aWindow.removeEventListener("load", onLoad, false);
+    executeSoon(aCallback);
+  }, false);
+}
+
+// ----------
+function newWindowWithState(aState, aCallback) {
+  let opts = "chrome,all,dialog=no,height=800,width=800";
+  let win = window.openDialog(getBrowserURL(), "_blank", opts);
+
+  registerCleanupFunction(function () win.close());
+
+  whenWindowLoaded(win, function () {
+    ss.setWindowState(win, JSON.stringify(aState), true);
+    executeSoon(function () aCallback(win));
+  });
+}
new file mode 100644
--- /dev/null
+++ b/browser/components/sessionstore/test/browser_739805.js
@@ -0,0 +1,56 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+const TAB_STATE_NEEDS_RESTORE = 1;
+
+let tabState = {
+  entries: [{url: "data:text/html,<input%20id='foo'>", formdata: {"#foo": "bar"}}]
+};
+
+function test() {
+  waitForExplicitFinish();
+  Services.prefs.setBoolPref("browser.sessionstore.restore_on_demand", true);
+
+  registerCleanupFunction(function () {
+    if (gBrowser.tabs.length > 1)
+      gBrowser.removeTab(gBrowser.tabs[1]);
+    Services.prefs.clearUserPref("browser.sessionstore.restore_on_demand");
+  });
+
+  let tab = gBrowser.addTab("about:blank");
+  let browser = tab.linkedBrowser;
+
+  whenBrowserLoaded(browser, function () {
+    isnot(gBrowser.selectedTab, tab, "newly created tab is not selected");
+
+    ss.setTabState(tab, JSON.stringify(tabState));
+    is(browser.__SS_restoreState, TAB_STATE_NEEDS_RESTORE, "tab needs restoring");
+
+    let state = JSON.parse(ss.getTabState(tab));
+    let formdata = state.entries[0].formdata;
+    is(formdata && formdata["#foo"], "bar", "tab state's formdata is valid");
+
+    whenTabRestored(tab, function () {
+      let input = browser.contentDocument.getElementById("foo");
+      is(input.value, "bar", "formdata has been restored correctly");
+      finish();
+    });
+
+    // Restore the tab by selecting it.
+    gBrowser.selectedTab = tab;
+  });
+}
+
+function whenBrowserLoaded(aBrowser, aCallback) {
+  aBrowser.addEventListener("load", function onLoad() {
+    aBrowser.removeEventListener("load", onLoad, true);
+    executeSoon(aCallback);
+  }, true);
+}
+
+function whenTabRestored(aTab, aCallback) {
+  aTab.addEventListener("SSTabRestored", function onRestored() {
+    aTab.removeEventListener("SSTabRestored", onRestored);
+    executeSoon(aCallback);
+  });
+}
--- a/browser/components/tabview/storage.js
+++ b/browser/components/tabview/storage.js
@@ -119,16 +119,30 @@ let Storage = {
       // getTabValue will fail if the property doesn't exist.
       Utils.log(e);
     }
 
     return existingData;
   },
 
   // ----------
+  // Function: getTabState
+  // Returns the current state of the given tab.
+  getTabState: function Storage_getTabState(tab) {
+    Utils.assert(tab, "tab");
+    let tabState;
+
+    try {
+      tabState = JSON.parse(this._sessionStore.getTabState(tab));
+    } catch (e) {}
+
+    return tabState;
+  },
+
+  // ----------
   // Function: saveGroupItem
   // Saves the data for a single groupItem, associated with a specific window.
   saveGroupItem: function Storage_saveGroupItem(win, data) {
     var id = data.id;
     var existingData = this.readGroupItemData(win);
     existingData[id] = data;
     this._sessionStore.setWindowValue(win, this.GROUP_DATA_IDENTIFIER,
       JSON.stringify(existingData));
--- a/browser/components/tabview/tabitems.js
+++ b/browser/components/tabview/tabitems.js
@@ -91,17 +91,16 @@ function TabItem(tab, options) {
   this.defaultSize = new Point(TabItems.tabWidth, TabItems.tabHeight);
   this._hidden = false;
   this.isATabItem = true;
   this.keepProportional = true;
   this._hasBeenDrawn = false;
   this._reconnected = false;
   this.isDragging = false;
   this.isStacked = false;
-  this.url = "";
 
   // Read off the total vertical and horizontal padding on the tab container
   // and cache this value, as it must be the same for every TabItem.
   if (Utils.isEmptyObject(TabItems.tabItemPadding)) {
     TabItems.tabItemPadding.x = parseInt($div.css('padding-left'))
         + parseInt($div.css('padding-right'));
 
     TabItems.tabItemPadding.y = parseInt($div.css('padding-top'))
@@ -195,31 +194,24 @@ TabItem.prototype = Utils.extend(new Ite
   },
 
   // ----------
   // Function: showCachedData
   // Shows the cached data i.e. image and title.  Note: this method should only
   // be called at browser startup with the cached data avaliable.
   //
   // Parameters:
-  //   tabData - the tab data
   //   imageData - the image data
-  showCachedData: function TabItem_showCachedData(tabData, imageData) {
+  showCachedData: function TabItem_showCachedData(imageData) {
     this._cachedImageData = imageData;
     this.$cachedThumb.attr("src", this._cachedImageData).show();
     this.$canvas.css({opacity: 0});
-    let label = "";
-    let title;
-    if (tabData.title) {
-      label = tabData.title;
-      title = label + "\n" + tabData.url;
-    } else {
-      title = tabData.url;
-    }
-    this.$tabTitle.text(label).attr("title", title);
+
+    let {title, url} = this.getTabState();
+    this.$tabTitle.text(title).attr("title", title ? title + "\n" + url : url);
 
     this._sendToSubscribers("showingCachedData");
   },
 
   // ----------
   // Function: hideCachedData
   // Hides the cached data i.e. image and title and show the canvas.
   hideCachedData: function TabItem_hideCachedData() {
@@ -229,19 +221,17 @@ TabItem.prototype = Utils.extend(new Ite
       this._cachedImageData = null;
   },
 
   // ----------
   // Function: getStorageData
   // Get data to be used for persistent storage of this object.
   getStorageData: function TabItem_getStorageData() {
     let data = {
-      url: this.tab.linkedBrowser.currentURI.spec,
-      groupID: (this.parent ? this.parent.id : 0),
-      title: this.tab.label
+      groupID: (this.parent ? this.parent.id : 0)
     };
     if (this.parent && this.parent.getActiveTab() == this)
       data.active = true;
 
     return data;
   },
 
   // ----------
@@ -256,21 +246,55 @@ TabItem.prototype = Utils.extend(new Ite
       if (TabItems.storageSanity(data))
         Storage.saveTab(this.tab, data);
     } catch(e) {
       Utils.log("Error in saving tab value: "+e);
     }
   },
 
   // ----------
+  // Function: _getCurrentTabStateEntry
+  // Returns the current tab state's active history entry.
+  _getCurrentTabStateEntry: function TabItem__getCurrentTabStateEntry() {
+    let tabState = Storage.getTabState(this.tab);
+
+    if (tabState) {
+      let index = (tabState.index || tabState.entries.length) - 1;
+      if (index in tabState.entries)
+        return tabState.entries[index];
+    }
+
+    return null;
+  },
+
+  // ----------
+  // Function: getTabState
+  // Returns the current tab state, i.e. the title and URL of the active
+  // history entry.
+  getTabState: function TabItem_getTabState() {
+    let entry = this._getCurrentTabStateEntry();
+    let title = "";
+    let url = "";
+
+    if (entry) {
+      if (entry.title)
+        title = entry.title;
+
+      url = entry.url;
+    } else {
+      url = this.tab.linkedBrowser.currentURI.spec;
+    }
+
+    return {title: title, url: url};
+  },
+
+  // ----------
   // Function: loadThumbnail
   // Loads the tabItems thumbnail.
-  loadThumbnail: function TabItem_loadThumbnail(tabData) {
-    Utils.assert(tabData, "invalid or missing argument <tabData>");
-
+  loadThumbnail: function TabItem_loadThumbnail() {
     let self = this;
 
     function TabItem_loadThumbnail_callback(error, imageData) {
       // we could have been unlinked while waiting for the thumbnail to load
       if (!self.tab)
         return;
 
       if (error || !imageData) {
@@ -280,21 +304,21 @@ TabItem.prototype = Utils.extend(new Ite
       }
 
       self._sendToSubscribers("loadedCachedImageData");
 
       // If we have a cached image, then show it if the loaded URL matches
       // what the cache is from, OR the loaded URL is blank, which means
       // that the page hasn't loaded yet.
       let currentUrl = self.tab.linkedBrowser.currentURI.spec;
-      if (tabData.url == currentUrl || currentUrl == "about:blank")
-        self.showCachedData(tabData, imageData);
+      if (self.getTabState().url == currentUrl || currentUrl == "about:blank")
+        self.showCachedData(imageData);
     }
 
-    ThumbnailStorage.loadThumbnail(tabData.url, TabItem_loadThumbnail_callback);
+    ThumbnailStorage.loadThumbnail(this.getTabState().url, TabItem_loadThumbnail_callback);
   },
 
   // ----------
   // Function: saveThumbnail
   // Saves the tabItems thumbnail.
   saveThumbnail: function TabItem_saveThumbnail(options) {
     if (!this.tabCanvas)
       return;
@@ -365,17 +389,17 @@ TabItem.prototype = Utils.extend(new Ite
   _reconnect: function TabItem__reconnect(options) {
     Utils.assertThrow(!this._reconnected, "shouldn't already be reconnected");
     Utils.assertThrow(this.tab, "should have a xul:tab");
 
     let tabData = Storage.getTabData(this.tab);
     let groupItem;
 
     if (tabData && TabItems.storageSanity(tabData)) {
-      this.loadThumbnail(tabData);
+      this.loadThumbnail();
 
       if (this.parent)
         this.parent.remove(this, {immediately: true});
 
       if (tabData.groupID)
         groupItem = GroupItems.groupItem(tabData.groupID);
       else
         groupItem = new GroupItem([], {immediately: true, bounds: tabData.bounds});
@@ -929,17 +953,17 @@ let TabItems = {
     // If our readyState is complete, but we're showing about:blank,
     // and we're not loading about:blank, it means we haven't really
     // started loading. This can happen to the first few tabs in a
     // page.
     Utils.assertThrow(tab, "tab");
     return (
       tab.linkedBrowser.contentDocument.readyState == 'complete' &&
       !(tab.linkedBrowser.contentDocument.URL == 'about:blank' &&
-        tab._tabViewTabItem.url != 'about:blank')
+        tab._tabViewTabItem.getTabState().url != 'about:blank')
     );
   },
 
   // ----------
   // Function: update
   // Takes in a xul:tab.
   update: function TabItems_update(tab) {
     try {
@@ -1008,20 +1032,16 @@ let TabItems = {
         $name.text(label);
 
       // ___ remove from waiting list now that we have no other
       // early returns
       this._tabsWaitingForUpdate.remove(tab);
 
       // ___ URL
       let tabUrl = tab.linkedBrowser.currentURI.spec;
-      if (tabUrl != tabItem.url) {
-        tabItem.url = tabUrl;
-        tabItem.save();
-      }
       tabItem.$container.attr("title", label + "\n" + tabUrl);
 
       // ___ Make sure the tab is complete and ready for updating.
       if (!this.isComplete(tab) && (!options || !options.force)) {
         // If it's incomplete, stick it on the end of the queue
         this._tabsWaitingForUpdate.push(tab);
         return;
       }
--- a/browser/components/tabview/test/Makefile.in
+++ b/browser/components/tabview/test/Makefile.in
@@ -165,19 +165,21 @@ include $(topsrcdir)/config/rules.mk
                  browser_tabview_bug685692.js \
                  browser_tabview_bug686654.js \
                  browser_tabview_bug696602.js \
                  browser_tabview_bug697390.js \
                  browser_tabview_bug705621.js \
                  browser_tabview_bug706430.js \
                  browser_tabview_bug706736.js \
                  browser_tabview_bug707466.js \
+                 browser_tabview_bug712203.js \
                  browser_tabview_bug715454.js \
                  browser_tabview_bug716880.js \
                  browser_tabview_bug728887.js \
+                 browser_tabview_bug733115.js \
                  browser_tabview_click_group.js \
                  browser_tabview_dragdrop.js \
                  browser_tabview_exit_button.js \
                  browser_tabview_expander.js \
                  browser_tabview_firstrun_pref.js \
                  browser_tabview_group.js \
                  browser_tabview_launch.js \
                  browser_tabview_multiwindow_search.js \
--- a/browser/components/tabview/test/browser_tabview_bug608153.js
+++ b/browser/components/tabview/test/browser_tabview_bug608153.js
@@ -30,19 +30,8 @@ function test() {
       is(cw.GroupItems.getActiveGroupItem(), groupItemOne, "Group one is active");
       is(gBrowser.selectedTab, pinnedTab, "Selected tab is the pinned tab");
 
       finish();
     });
   });
 }
 
-function goToNextGroup() {
-  let utils =
-    QueryInterface(Ci.nsIInterfaceRequestor).
-      getInterface(Ci.nsIDOMWindowUtils);
-
-  const masks = Ci.nsIDOMNSEvent;
-  let mval = 0;
-  mval |= masks.CONTROL_MASK;
-
-  utils.sendKeyEvent("keypress", 0, 96, mval);
-}
--- a/browser/components/tabview/test/browser_tabview_bug626525.js
+++ b/browser/components/tabview/test/browser_tabview_bug626525.js
@@ -141,19 +141,8 @@ function openTabContextPopup(win, tab) {
   win.document.getElementById("tabContextMenu").openPopup(
     tab, "end_after", 0, 0, true, false, {target: tab});
 }
 
 function closeTabContextPopup(win) {
   win.document.getElementById("tabContextMenu").hidePopup();
 }
 
-function goToNextGroup(win) {
-  let utils =
-    win.QueryInterface(Ci.nsIInterfaceRequestor).
-      getInterface(Ci.nsIDOMWindowUtils);
-
-  const masks = Ci.nsIDOMNSEvent;
-  let mval = 0;
-  mval |= masks.CONTROL_MASK;
-
-  utils.sendKeyEvent("keypress", 0, 96, mval);
-}
new file mode 100644
--- /dev/null
+++ b/browser/components/tabview/test/browser_tabview_bug712203.js
@@ -0,0 +1,67 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+
+function test() {
+  waitForExplicitFinish();
+
+  // create two groups and each group has one tab item
+  let newState = {
+    windows: [{
+      tabs: [{
+        entries: [{ url: "http://www.google.com" }],
+        hidden: true,
+        attributes: {},
+        extData: {
+          "tabview-tab":
+            '{"bounds":{"left":21,"top":29,"width":204,"height":153},' +
+            '"userSize":null,"url":"http://www.google.com","groupID":1,' +
+            '"imageData":null,"title":null}'
+        }
+      },{
+        entries: [{ url: "about:blank" }],
+        hidden: false,
+        attributes: {},
+        extData: {
+          "tabview-tab":
+            '{"bounds":{"left":315,"top":29,"width":111,"height":84},' +
+            '"userSize":null,"url":"about:blank","groupID":2,' +
+            '"imageData":null,"title":null}'
+        },
+      }],
+      selected:2,
+      _closedTabs: [],
+      extData: {
+        "tabview-groups": '{"nextID":3,"activeGroupId":2}',
+        "tabview-group":
+          '{"1":{"bounds":{"left":15,"top":5,"width":280,"height":232},' +
+          '"userSize":null,"title":"","id":1},' +
+          '"2":{"bounds":{"left":309,"top":5,"width":267,"height":226},' +
+          '"userSize":null,"title":"","id":2}}',
+        "tabview-ui": '{"pageBounds":{"left":0,"top":0,"width":788,"height":548}}'
+      }, sizemode:"normal"
+    }]
+  };
+
+  newWindowWithState(newState, function(win) {
+    registerCleanupFunction(function () win.close());
+
+    let selectedTab = win.gBrowser.selectedTab;
+
+    win.addEventListener("tabviewframeinitialized", function onInit() {
+      win.removeEventListener("tabviewframeinitialized", onInit, false);
+      // ensure the TabView.contentWindow is set.
+      executeSoon(function() {
+        let cw = win.TabView.getContentWindow();
+
+        is(cw.GroupItems.groupItems.length, 2, "There are two groups");
+        is(cw.GroupItems.getActiveGroupItem().id, 1, "The active group item is 1");
+        isnot(selectedTab, win.gBrowser.selectedTab, "The selected tab is different");
+
+        finish();
+      });
+    }, false);
+
+    goToNextGroup(win);
+  });
+}
new file mode 100644
--- /dev/null
+++ b/browser/components/tabview/test/browser_tabview_bug733115.js
@@ -0,0 +1,41 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+function test() {
+  waitForExplicitFinish();
+
+  showTabView(function() {
+    registerCleanupFunction(function() {
+      if (gBrowser.tabs[1])
+        gBrowser.removeTab(gBrowser.tabs[1]);
+      TabView.hide();
+    });
+
+    let contentWindow = TabView.getContentWindow();
+    let groupItem = createEmptyGroupItem(contentWindow, 200, 200, 20);
+    contentWindow.GroupItems.setActiveGroupItem(groupItem);
+
+    // A new tab should be added to the active group and tabview should zoom into it.
+    is(groupItem.getChildren().length, 0, "This group doesn't have any tabitems");
+    whenTabViewIsHidden(function() {
+      is(groupItem.getChildren().length, 1, "This group has one tabitem");
+
+      showTabView(function() {
+        // Ensure that no new tab is added to this non-empty tab group.
+        whenTabViewIsHidden(function() {
+          let tabItems = groupItem.getChildren();
+          is(tabItems.length, 1, "This group has one tabitem");
+          is(tabItems[0].tab, gBrowser.selectedTab, "The same tab");
+
+          tabItems[0].close();
+          groupItem.close();
+
+          finish();
+        });
+        EventUtils.synthesizeKey("VK_ENTER", {}, contentWindow);
+      });
+    });
+    EventUtils.synthesizeKey("VK_ENTER", {}, contentWindow);
+  });
+}
+
--- a/browser/components/tabview/test/head.js
+++ b/browser/components/tabview/test/head.js
@@ -247,17 +247,16 @@ function whenSearchIsDisabled(callback, 
   }
 
   contentWindow.addEventListener("tabviewsearchdisabled", function onSearchDisabled() {
     contentWindow.removeEventListener("tabviewsearchdisabled", onSearchDisabled, false);
     callback();
   }, false);
 }
 
-
 // ----------
 function hideGroupItem(groupItem, callback) {
   if (groupItem.hidden) {
     if (callback)
       callback();
     return;
   }
 
@@ -382,16 +381,31 @@ function togglePrivateBrowsing(callback)
 
   let pb = Cc["@mozilla.org/privatebrowsing;1"].
            getService(Ci.nsIPrivateBrowsingService);
 
   pb.privateBrowsingEnabled = !pb.privateBrowsingEnabled;
 }
 
 // ----------
+function goToNextGroup(win) {
+  win = win || window;
+
+  let utils =
+    win.QueryInterface(Ci.nsIInterfaceRequestor).
+      getInterface(Ci.nsIDOMWindowUtils);
+
+  const masks = Ci.nsIDOMNSEvent;
+  let mval = 0;
+  mval |= masks.CONTROL_MASK;
+
+  utils.sendKeyEvent("keypress", 0, 96, mval);
+}
+
+// ----------
 function whenAppTabIconAdded(callback, win) {
   win = win || window;
 
   let contentWindow = win.TabView.getContentWindow();
   let groupItems = contentWindow.GroupItems.groupItems;
   let groupItem = groupItems[(groupItems.length - 1)];
 
   groupItem.addSubscriber("appTabIconAdded", function onAppTabIconAdded() {
--- a/browser/components/tabview/ui.js
+++ b/browser/components/tabview/ui.js
@@ -1188,16 +1188,17 @@ let UI = {
           }
         });
 
         return match && match[1];
       }
 
       let preventDefault = true;
       let activeTab;
+      let activeGroupItem;
       let norm = null;
       switch (event.keyCode) {
         case KeyEvent.DOM_VK_RIGHT:
           norm = function(a, me){return a.x > me.x};
           break;
         case KeyEvent.DOM_VK_LEFT:
           norm = function(a, me){return a.x < me.x};
           break;
@@ -1205,36 +1206,45 @@ let UI = {
           norm = function(a, me){return a.y > me.y};
           break;
         case KeyEvent.DOM_VK_UP:
           norm = function(a, me){return a.y < me.y}
           break;
       }
 
       if (norm != null) {
-        var nextTab = getClosestTabBy(norm);
+        let nextTab = getClosestTabBy(norm);
         if (nextTab) {
           if (nextTab.isStacked && !nextTab.parent.expanded)
             nextTab = nextTab.parent.getChild(0);
           self.setActive(nextTab);
         }
       } else {
         switch(event.keyCode) {
           case KeyEvent.DOM_VK_ESCAPE:
-            let activeGroupItem = GroupItems.getActiveGroupItem();
+            activeGroupItem = GroupItems.getActiveGroupItem();
             if (activeGroupItem && activeGroupItem.expanded)
               activeGroupItem.collapse();
             else
               self.exit();
             break;
           case KeyEvent.DOM_VK_RETURN:
           case KeyEvent.DOM_VK_ENTER:
-            activeTab = self.getActiveTab();
-            if (activeTab)
-              activeTab.zoomIn();
+            activeGroupItem = GroupItems.getActiveGroupItem();
+            if (activeGroupItem) {
+              activeTab = self.getActiveTab();
+
+              if (!activeTab || activeTab.parent != activeGroupItem)
+                activeTab = activeGroupItem.getActiveTab();
+
+              if (activeTab)
+                activeTab.zoomIn();
+              else
+                activeGroupItem.newTab();
+            }
             break;
           case KeyEvent.DOM_VK_TAB:
             // tab/shift + tab to go to the next tab.
             activeTab = self.getActiveTab();
             if (activeTab) {
               let tabItems = (activeTab.parent ? activeTab.parent.getChildren() :
                               [activeTab]);
               let length = tabItems.length;
--- a/browser/devtools/debugger/debugger.js
+++ b/browser/devtools/debugger/debugger.js
@@ -306,16 +306,20 @@ var StackFrames = {
       objClient.getSignature(function SF_getSignature(aResponse) {
         for (let i = 0; i < aResponse.parameters.length; i++) {
           let param = aResponse.parameters[i];
           let paramVar = localScope.addVar(param);
           let paramVal = frame.arguments[i];
           paramVar.setGrip(paramVal);
           this._addExpander(paramVar, paramVal);
         }
+        // Signal that call parameters have been fetched.
+        let evt = document.createEvent("Event");
+        evt.initEvent("Debugger:FetchedParameters", true, false);
+        document.documentElement.dispatchEvent(evt);
       }.bind(this));
     }
   },
 
   /**
    * Update the source editor current debug location based on the selected frame
    * and script.
    */
@@ -464,44 +468,35 @@ var SourceScripts = {
    *        The thread client.
    * @param function aCallback
    *        The next function in the initialization sequence.
    */
   connect: function SS_connect(aThreadClient, aCallback) {
     DebuggerView.Scripts.addChangeListener(this.onChange);
 
     this.activeThread = aThreadClient;
-    aThreadClient.addListener("paused", this.onPaused);
     aThreadClient.addListener("scriptsadded", this.onScripts);
     aThreadClient.addListener("scriptscleared", this.onScriptsCleared);
     this.clearLabelsCache();
     this.onScriptsCleared();
+    // Retrieve the list of scripts known to the server from before the client
+    // was ready to handle new script notifications.
+    this.activeThread.fillScripts();
     aCallback && aCallback();
   },
 
   /**
    * Disconnect from the client.
    */
   disconnect: function TS_disconnect() {
-    this.activeThread.removeListener("paused", this.onPaused);
     this.activeThread.removeListener("scriptsadded", this.onScripts);
     this.activeThread.removeListener("scriptscleared", this.onScriptsCleared);
   },
 
   /**
-   * Handler for the thread client's paused notification. This is triggered only
-   * once, to retrieve the list of scripts known to the server from before the
-   * client was ready to handle new script notifications.
-   */
-  onPaused: function SS_onPaused() {
-    this.activeThread.removeListener("paused", this.onPaused);
-    this.activeThread.fillScripts();
-  },
-
-  /**
    * Handler for the debugger client's unsolicited newScript notification.
    */
   onNewScript: function SS_onNewScript(aNotification, aPacket) {
     this._addScript({ url: aPacket.url, startLine: aPacket.startLine });
   },
 
   /**
    * Handler for the thread client's scriptsadded notification.
@@ -652,16 +647,15 @@ var SourceScripts = {
       window.editor.setText(aScript.text);
       window.updateEditorBreakpoints();
       StackFrames.updateEditor();
     }
     window.editor.resetUndo();
   }
 };
 
-SourceScripts.onPaused = SourceScripts.onPaused.bind(SourceScripts);
 SourceScripts.onScripts = SourceScripts.onScripts.bind(SourceScripts);
 SourceScripts.onNewScript = SourceScripts.onNewScript.bind(SourceScripts);
 SourceScripts.onScriptsCleared = SourceScripts.onScriptsCleared.bind(SourceScripts);
 SourceScripts.onChange = SourceScripts.onChange.bind(SourceScripts);
 
 window.addEventListener("DOMContentLoaded", initDebugger, false);
 window.addEventListener("unload", shutdownDebugger, false);
--- a/browser/devtools/debugger/test/Makefile.in
+++ b/browser/devtools/debugger/test/Makefile.in
@@ -72,30 +72,32 @@ include $(topsrcdir)/config/rules.mk
 	browser_dbg_script-switching.js \
 	browser_dbg_pause-resume.js \
 	browser_dbg_update-editor-mode.js \
 	$(warning browser_dbg_select-line.js temporarily disabled due to oranges, see bug 726609) \
 	browser_dbg_clean-exit.js \
 	browser_dbg_bug723069_editor-breakpoints.js \
 	browser_dbg_bug731394_editor-contextmenu.js \
 	browser_dbg_displayName.js \
+	browser_dbg_iframes.js \
 	head.js \
 	$(NULL)
 
 _BROWSER_TEST_PAGES = \
 	browser_dbg_tab1.html \
 	browser_dbg_tab2.html \
 	browser_dbg_debuggerstatement.html \
 	browser_dbg_stack.html \
 	browser_dbg_script-switching.html \
 	test-script-switching-01.js \
 	test-script-switching-02.js \
 	browser_dbg_frame-parameters.html \
 	browser_dbg_update-editor-mode.html \
 	test-editor-mode \
 	browser_dbg_displayName.html \
+	browser_dbg_iframes.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)
--- a/browser/devtools/debugger/test/browser_dbg_bug723069_editor-breakpoints.js
+++ b/browser/devtools/debugger/test/browser_dbg_bug723069_editor-breakpoints.js
@@ -23,17 +23,17 @@ function test()
   let SourceEditor = tempScope.SourceEditor;
 
   debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
     gTab = aTab;
     gDebuggee = aDebuggee;
     gPane = aPane;
     gDebugger = gPane.debuggerWindow;
 
-    gPane.activeThread.addOneTimeListener("scriptsadded", function() {
+    gPane.activeThread.addOneTimeListener("framesadded", function() {
       Services.tm.currentThread.dispatch({ run: onScriptsAdded }, 0);
     });
     gDebuggee.firstCall();
   });
 
   function onScriptsAdded()
   {
     gScripts = gDebugger.DebuggerView.Scripts;
--- a/browser/devtools/debugger/test/browser_dbg_bug731394_editor-contextmenu.js
+++ b/browser/devtools/debugger/test/browser_dbg_bug731394_editor-contextmenu.js
@@ -21,17 +21,17 @@ function test()
   let contextMenu = null;
 
   debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
     gTab = aTab;
     gDebuggee = aDebuggee;
     gPane = aPane;
     gDebugger = gPane.debuggerWindow;
 
-    gPane.activeThread.addOneTimeListener("scriptsadded", function() {
+    gPane.activeThread.addOneTimeListener("framesadded", function() {
       Services.tm.currentThread.dispatch({ run: onScriptsAdded }, 0);
     });
     gDebuggee.firstCall();
   });
 
   function onScriptsAdded()
   {
     let scripts = gDebugger.DebuggerView.Scripts._scripts;
--- a/browser/devtools/debugger/test/browser_dbg_debuggerstatement.js
+++ b/browser/devtools/debugger/test/browser_dbg_debuggerstatement.js
@@ -27,18 +27,17 @@ function test_early_debugger_statement(a
 {
   let paused = function(aEvent, aPacket) {
     ok(false, "Pause shouldn't be called before we've attached!\n");
     finish_test();
   };
   gClient.addListener("paused", paused);
   // This should continue without nesting an event loop and calling
   // the onPaused hook, because we haven't attached yet.
-  // TODO: uncomment this when bug 723563 is fixed.
-  //gTab.linkedBrowser.contentWindow.wrappedJSObject.runDebuggerStatement();
+  gTab.linkedBrowser.contentWindow.wrappedJSObject.runDebuggerStatement();
 
   gClient.removeListener("paused", paused);
 
   // Now attach and resume...
   gClient.request({ to: aActor.threadActor, type: "attach" }, function(aResponse) {
     gClient.request({ to: aActor.threadActor, type: "resume" }, function(aResponse) {
       test_debugger_statement(aActor);
     });
new file mode 100644
--- /dev/null
+++ b/browser/devtools/debugger/test/browser_dbg_iframes.html
@@ -0,0 +1,12 @@
+<!DOCTYPE HTML>
+<html>
+<head><title>Browser Debugger IFrame Test Tab</title>
+<!-- Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/ -->
+</head>
+
+<body>
+  <iframe src="browser_dbg_debuggerstatement.html"></iframe>
+</body>
+
+</html>
new file mode 100644
--- /dev/null
+++ b/browser/devtools/debugger/test/browser_dbg_iframes.js
@@ -0,0 +1,58 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+// Tests that iframes can be added as debuggees.
+
+var gPane = null;
+var gTab = null;
+
+const TEST_URL = EXAMPLE_URL + "browser_dbg_iframes.html";
+
+function test() {
+  debug_tab_pane(TEST_URL, function(aTab, aDebuggee, aPane) {
+    gTab = aTab;
+    gPane = aPane;
+    let gDebugger = gPane.debuggerWindow;
+
+    is(gDebugger.StackFrames.activeThread.paused, false,
+      "Should be running after debug_tab_pane.");
+
+    gPane.activeThread.addOneTimeListener("framesadded", function() {
+      Services.tm.currentThread.dispatch({ run: function() {
+
+        let frames = gDebugger.DebuggerView.Stackframes._frames;
+        let childNodes = frames.childNodes;
+
+        is(gDebugger.StackFrames.activeThread.paused, true,
+          "Should be paused after an interrupt request.");
+
+        is(frames.querySelectorAll(".dbg-stackframe").length, 1,
+          "Should have one frame in the stack.");
+
+        gPane.activeThread.addOneTimeListener("resumed", function() {
+          Services.tm.currentThread.dispatch({ run: function() {
+            closeDebuggerAndFinish(gTab);
+          }}, 0);
+        });
+
+        EventUtils.sendMouseEvent({ type: "click" },
+          gDebugger.document.getElementById("resume"),
+          gDebugger);
+      }}, 0);
+    });
+
+    let iframe = gTab.linkedBrowser.contentWindow.wrappedJSObject.frames[0];
+
+    is(iframe.document.title, "Browser Debugger Test Tab", "Found the iframe");
+
+    iframe.runDebuggerStatement();
+  });
+}
+
+registerCleanupFunction(function() {
+  removeTab(gTab);
+  gPane = null;
+  gTab = null;
+});
--- a/browser/devtools/debugger/test/browser_dbg_listtabs.js
+++ b/browser/devtools/debugger/test/browser_dbg_listtabs.js
@@ -82,17 +82,17 @@ function test_attach_removed_tab()
   removeTab(gTab2);
   gTab2 = null;
   gClient.addListener("paused", function(aEvent, aPacket) {
     ok(false, "Attaching to an exited tab actor shouldn't generate a pause.");
     finish_test();
   });
 
   gClient.request({ to: gTab2Actor, type: "attach" }, function(aResponse) {
-    is(aResponse.error, "noSuchActor", "Tab should be gone.");
+    is(aResponse.type, "exited", "Tab should consider itself exited.");
     finish_test();
   });
 }
 
 function finish_test()
 {
   gClient.close(function() {
     finish();
--- a/browser/devtools/debugger/test/browser_dbg_propertyview-01.js
+++ b/browser/devtools/debugger/test/browser_dbg_propertyview-01.js
@@ -80,16 +80,17 @@ function testSimpleCall() {
 
   gDebuggee.simpleCall();
 }
 
 function resumeAndFinish() {
   gDebugger.StackFrames.activeThread.resume(function() {
     let vs = gDebugger.DebuggerView.Scripts;
     let ss = gDebugger.SourceScripts;
+    ss.onScriptsCleared();
 
     is(ss._trimUrlQuery("a/b/c.d?test=1&random=4"), "a/b/c.d",
       "Trimming the url query isn't done properly.");
 
     let urls = [
       { href: "ici://some.address.com/random/", leaf: "subrandom/" },
       { href: "ni://another.address.org/random/subrandom/", leaf: "page.html" },
       { href: "san://interesting.address.gro/random/", leaf: "script.js" },
--- a/browser/devtools/debugger/test/browser_dbg_propertyview-07.js
+++ b/browser/devtools/debugger/test/browser_dbg_propertyview-07.js
@@ -20,19 +20,18 @@ function test()
     gDebugger = gPane.debuggerWindow;
 
     testFrameParameters();
   });
 }
 
 function testFrameParameters()
 {
-  // scriptsadded is fired last when switching to a paused state, so the
-  // property view will have had a chance to fetch the call parameters.
-  gPane.activeThread.addOneTimeListener("scriptsadded", function() {
+  gDebugger.addEventListener("Debugger:FetchedParameters", function test() {
+    gDebugger.removeEventListener("Debugger:FetchedParameters", test, false);
     Services.tm.currentThread.dispatch({ run: function() {
 
       var frames = gDebugger.DebuggerView.Stackframes._frames,
           childNodes = frames.childNodes,
           localScope = gDebugger.DebuggerView.Properties.localScope,
           localNodes = localScope.querySelector(".details").childNodes;
 
       is(gDebugger.StackFrames.activeThread.state, "paused",
@@ -65,17 +64,17 @@ function testFrameParameters()
       is(localNodes[6].querySelector(".info").textContent, "null",
         "Should have the right property value for 'eArg'.");
 
       is(localNodes[7].querySelector(".info").textContent, "undefined",
         "Should have the right property value for 'fArg'.");
 
       resumeAndFinish();
     }}, 0);
-  });
+  }, false);
 
   EventUtils.sendMouseEvent({ type: "click" },
     content.document.querySelector("button"),
     content.window);
 }
 
 function resumeAndFinish() {
   gPane.activeThread.addOneTimeListener("framescleared", function() {
--- a/browser/devtools/debugger/test/browser_dbg_propertyview-08.js
+++ b/browser/devtools/debugger/test/browser_dbg_propertyview-08.js
@@ -20,19 +20,18 @@ function test()
     gDebugger = gPane.debuggerWindow;
 
     testFrameParameters();
   });
 }
 
 function testFrameParameters()
 {
-  // scriptsadded is fired last when switching to a paused state, so the
-  // property view will have had a chance to fetch the call parameters.
-  gPane.activeThread.addOneTimeListener("scriptsadded", function() {
+  gDebugger.addEventListener("Debugger:FetchedParameters", function test() {
+    gDebugger.removeEventListener("Debugger:FetchedParameters", test, false);
     Services.tm.currentThread.dispatch({ run: function() {
 
       var frames = gDebugger.DebuggerView.Stackframes._frames,
           localScope = gDebugger.DebuggerView.Properties.localScope,
           localNodes = localScope.querySelector(".details").childNodes;
 
       is(gDebugger.StackFrames.activeThread.state, "paused",
         "Should only be getting stack frames while paused.");
@@ -81,17 +80,17 @@ function testFrameParameters()
 
         is(localNodes[1].querySelector(".property > .title > .value")
                         .textContent, 5,
           "Should have the right argument length.");
 
         resumeAndFinish();
       }, 100);
     }}, 0);
-  });
+  }, false);
 
   EventUtils.synthesizeMouseAtCenter(content.document.querySelector("button"),
                                      {},
                                      content.window);
 }
 
 function resumeAndFinish() {
   gPane.activeThread.addOneTimeListener("framescleared", function() {
--- a/browser/devtools/debugger/test/browser_dbg_script-switching.js
+++ b/browser/devtools/debugger/test/browser_dbg_script-switching.js
@@ -26,17 +26,17 @@ function test()
     gPane = aPane;
     gDebugger = gPane.debuggerWindow;
 
     testScriptsDisplay();
   });
 }
 
 function testScriptsDisplay() {
-  gPane.activeThread.addOneTimeListener("scriptsadded", function() {
+  gPane.activeThread.addOneTimeListener("framesadded", function() {
     Services.tm.currentThread.dispatch({ run: function() {
       gScripts = gDebugger.DebuggerView.Scripts._scripts;
 
       is(gDebugger.StackFrames.activeThread.state, "paused",
         "Should only be getting stack frames while paused.");
 
       is(gScripts.itemCount, 2, "Found the expected number of scripts.");
 
--- a/browser/devtools/debugger/test/browser_dbg_stack-05.js
+++ b/browser/devtools/debugger/test/browser_dbg_stack-05.js
@@ -21,17 +21,17 @@ function test() {
     gPane = aPane;
     gDebugger = gPane.debuggerWindow;
 
     testRecurse();
   });
 }
 
 function testRecurse() {
-  gPane.activeThread.addOneTimeListener("scriptsadded", function() {
+  gPane.activeThread.addOneTimeListener("framesadded", function() {
     Services.tm.currentThread.dispatch({ run: function() {
       let frames = gDebugger.DebuggerView.Stackframes._frames;
       let childNodes = frames.childNodes;
 
       is(frames.querySelectorAll(".dbg-stackframe").length, 4,
         "Correct number of frames.");
 
       is(childNodes.length, frames.querySelectorAll(".dbg-stackframe").length,
--- a/browser/devtools/debugger/test/browser_dbg_update-editor-mode.js
+++ b/browser/devtools/debugger/test/browser_dbg_update-editor-mode.js
@@ -26,17 +26,17 @@ function test()
     gPane = aPane;
     gDebugger = gPane.debuggerWindow;
 
     testScriptsDisplay();
   });
 }
 
 function testScriptsDisplay() {
-  gPane.activeThread.addOneTimeListener("scriptsadded", function() {
+  gPane.activeThread.addOneTimeListener("framesadded", function() {
     Services.tm.currentThread.dispatch({ run: function() {
       gScripts = gDebugger.DebuggerView.Scripts._scripts;
 
       is(gDebugger.StackFrames.activeThread.state, "paused",
         "Should only be getting stack frames while paused.");
 
       is(gScripts.itemCount, 2, "Found the expected number of scripts.");
 
--- a/browser/devtools/highlighter/inspector.jsm
+++ b/browser/devtools/highlighter/inspector.jsm
@@ -1006,32 +1006,52 @@ InspectorUI.prototype = {
     this.nodeChanged(this.ruleViewObject);
   },
 
   /**
    * When a css link is clicked this method is called in order to either:
    *   1. Open the link in view source (for element style attributes)
    *   2. Open the link in the style editor
    *
+   *   Like the style editor, we only view stylesheets contained in
+   *   document.styleSheets.
+   *
    * @param aEvent The event containing the style rule to act on
    */
   ruleViewCSSLinkClicked: function(aEvent)
   {
     if (!this.chromeWin) {
       return;
     }
 
     let rule = aEvent.detail.rule;
     let styleSheet = rule.sheet;
+    let doc = this.chromeWin.content.document;
+    let styleSheets = doc.styleSheets;
+    let contentSheet = false;
+    let line = rule.ruleLine || 0;
 
-    if (styleSheet) {
-      this.chromeWin.StyleEditor.openChrome(styleSheet, rule.ruleLine);
+    // Array.prototype.indexOf always returns -1 here so we loop through
+    // the styleSheets object instead.
+    for each (let sheet in styleSheets) {
+      if (sheet == styleSheet) {
+        contentSheet = true;
+        break;
+      }
+    }
+
+    if (contentSheet)  {
+      this.chromeWin.StyleEditor.openChrome(styleSheet, line);
     } else {
-      let href = rule.elementStyle.element.ownerDocument.location.href;
-      this.chromeWin.openUILinkIn("view-source:" + href, "window");
+      let href = styleSheet ? styleSheet.href : "";
+      if (rule.elementStyle.element) {
+        href = rule.elementStyle.element.ownerDocument.location.href;
+      }
+      let viewSourceUtils = this.chromeWin.gViewSourceUtils;
+      viewSourceUtils.viewSource(href, null, doc, line);
     }
   },
 
   /**
    * This is the mousedown handler for the rule view. We use it to track whether
    * text is currently getting selected.
    * .
    * @param aEvent The event object
--- a/browser/devtools/scratchpad/scratchpad.js
+++ b/browser/devtools/scratchpad/scratchpad.js
@@ -482,17 +482,18 @@ var Scratchpad = {
 
   /**
    * Write out an error at the current insertion point as a block comment
    * @param object aValue
    *        The Error object to write out the message and stack trace
    */
   writeAsErrorComment: function SP_writeAsErrorComment(aError)
   {
-    let newComment = "Exception: " + aError.message + "\n" + aError.stack.substring(0, aError.stack.length - 1);
+    let stack = aError.stack || aError.fileName + ":" + aError.lineNumber;
+    let newComment = "Exception: " + aError.message + "\n" + stack.replace(/\n$/, "");
     
     this.writeAsComment(newComment);
   },
 
   /**
    * Open the Property Panel to inspect the given object.
    *
    * @param string aEvalString
--- a/browser/devtools/styleinspector/CssHtmlTree.jsm
+++ b/browser/devtools/styleinspector/CssHtmlTree.jsm
@@ -1206,23 +1206,50 @@ SelectorView.prototype = {
     }
   },
 
   /**
    * When a css link is clicked this method is called in order to either:
    *   1. Open the link in view source (for element style attributes).
    *   2. Open the link in the style editor.
    *
+   *   Like the style editor, we only view stylesheets contained in
+   *   document.styleSheets inside the style editor.
+   *
    * @param aEvent The click event
    */
   openStyleEditor: function(aEvent)
   {
-    if (this.selectorInfo.selector._cssRule._cssSheet) {
-      let styleSheet = this.selectorInfo.selector._cssRule._cssSheet.domSheet;
-      let line = this.selectorInfo.ruleLine;
+    let rule = this.selectorInfo.selector._cssRule;
+    let doc = this.tree.win.content.document;
+    let line = this.selectorInfo.ruleLine || 0;
+    let cssSheet = rule._cssSheet;
+    let contentSheet = false;
+    let styleSheet;
+    let styleSheets;
+
+    if (cssSheet) {
+      styleSheet = cssSheet.domSheet;
+      styleSheets = doc.styleSheets;
 
+      // Array.prototype.indexOf always returns -1 here so we loop through
+      // the styleSheets array instead.
+      for each (let sheet in styleSheets) {
+        if (sheet == styleSheet) {
+          contentSheet = true;
+          break;
+        }
+      }
+    }
+
+    if (contentSheet) {
       this.tree.win.StyleEditor.openChrome(styleSheet, line);
     } else {
-      let href = this.selectorInfo.sourceElement.ownerDocument.location.href;
-      this.tree.win.openUILinkIn("view-source:" + href, "window");
+      let href = styleSheet ? styleSheet.href : "";
+      let viewSourceUtils = this.tree.win.gViewSourceUtils;
+
+      if (this.selectorInfo.sourceElement) {
+        href = this.selectorInfo.sourceElement.ownerDocument.location.href;
+      }
+      viewSourceUtils.viewSource(href, null, doc, line);
     }
   },
 };
--- a/browser/devtools/styleinspector/test/Makefile.in
+++ b/browser/devtools/styleinspector/test/Makefile.in
@@ -62,16 +62,18 @@ include $(topsrcdir)/config/rules.mk
   browser_ruleview_ui.js \
   browser_ruleview_focus.js \
   browser_bug705707_is_content_stylesheet.js \
   browser_bug722196_property_view_media_queries.js \
   browser_bug722196_rule_view_media_queries.js \
   browser_bug_592743_specificity.js \
   browser_ruleview_bug_703643_context_menu_copy.js \
   browser_computedview_bug_703643_context_menu_copy.js \
+  browser_ruleview_734259_style_editor_link.js \
+  browser_computedview_734259_style_editor_link.js \
   head.js \
   $(NULL)
 
 _BROWSER_TEST_PAGES = \
   browser_bug683672.html \
   browser_bug705707_is_content_stylesheet.html \
   browser_bug705707_is_content_stylesheet_imported.css \
   browser_bug705707_is_content_stylesheet_imported2.css \
new file mode 100644
--- /dev/null
+++ b/browser/devtools/styleinspector/test/browser_computedview_734259_style_editor_link.js
@@ -0,0 +1,161 @@
+/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+let doc;
+let win;
+let stylePanel;
+
+function createDocument()
+{
+  doc.body.innerHTML = '<style type="text/css"> ' +
+    'html { color: #000000; } ' +
+    'span { font-variant: small-caps; color: #000000; } ' +
+    '.nomatches {color: #ff0000;}</style> <div id="first" style="margin: 10em; ' +
+    'font-size: 14pt; font-family: helvetica, sans-serif; color: #AAA">\n' +
+    '<h1>Some header text</h1>\n' +
+    '<p id="salutation" style="font-size: 12pt">hi.</p>\n' +
+    '<p id="body" style="font-size: 12pt">I am a test-case. This text exists ' +
+    'solely to provide some things to <span style="color: yellow">' +
+    'highlight</span> and <span style="font-weight: bold">count</span> ' +
+    'style list-items in the box at right. If you are reading this, ' +
+    'you should go do something else instead. Maybe read a book. Or better ' +
+    'yet, write some test-cases for another bit of code. ' +
+    '<span style="font-style: italic">some text</span></p>\n' +
+    '<p id="closing">more text</p>\n' +
+    '<p>even more text</p>' +
+    '</div>';
+  doc.title = "Rule view style editor link test";
+
+  let span = doc.querySelector("span");
+  ok(span, "captain, we have the span");
+
+  stylePanel = new StyleInspector(window);
+  Services.obs.addObserver(testInlineStyle, "StyleInspector-populated", false);
+  stylePanel.createPanel(false, function() {
+    stylePanel.open(span);
+  });
+}
+
+function testInlineStyle()
+{
+  Services.obs.removeObserver(testInlineStyle, "StyleInspector-populated", false);
+
+  ok(stylePanel.isOpen(), "style inspector is open");
+
+  info("expanding property");
+  expandProperty(0, function propertyExpanded() {
+    Services.ww.registerNotification(function onWindow(aSubject, aTopic) {
+      if (aTopic != "domwindowopened") {
+        return;
+      }
+      info("window opened");
+      win = aSubject.QueryInterface(Ci.nsIDOMWindow);
+      win.addEventListener("load", function windowLoad() {
+        win.removeEventListener("load", windowLoad);
+        info("window load completed");
+        let windowType = win.document.documentElement.getAttribute("windowtype");
+        is(windowType, "navigator:view-source", "view source window is open");
+        info("closing window");
+        win.close();
+        Services.ww.unregisterNotification(onWindow);
+        testInlineStyleSheet();
+      });
+    });
+    let link = getLinkByIndex(0);
+    link.click();
+  });
+}
+
+function testInlineStyleSheet()
+{
+  info("clicking an inline stylesheet");
+
+  Services.ww.registerNotification(function onWindow(aSubject, aTopic) {
+    if (aTopic != "domwindowopened") {
+      return;
+    }
+    info("window opened");
+    win = aSubject.QueryInterface(Ci.nsIDOMWindow);
+    win.addEventListener("load", function windowLoad() {
+      win.removeEventListener("load", windowLoad);
+      info("window load completed");
+      let windowType = win.document.documentElement.getAttribute("windowtype");
+      is(windowType, "Tools:StyleEditor", "style editor window is open");
+
+      win.styleEditorChrome.addChromeListener({
+        onEditorAdded: function checkEditor(aChrome, aEditor) {
+          if (!aEditor.sourceEditor) {
+            aEditor.addActionListener({
+              onAttach: function (aEditor) {
+                aEditor.removeActionListener(this);
+                validateStyleEditorSheet(aEditor);
+              }
+            });
+          } else {
+            validateStyleEditorSheet(aEditor);
+          }
+        }
+      });
+      Services.ww.unregisterNotification(onWindow);
+    });
+  });
+  let link = getLinkByIndex(1);
+  link.click();
+}
+
+function validateStyleEditorSheet(aEditor)
+{
+  info("validating style editor stylesheet");
+
+  let sheet = doc.styleSheets[0];
+  is(aEditor.styleSheet, sheet, "loaded stylesheet matches document stylesheet");
+  info("closing window");
+  win.close();
+
+  Services.obs.addObserver(finishUp, "StyleInspector-closed", false);
+  stylePanel.close();
+}
+
+function expandProperty(aIndex, aCallback)
+{
+  let iframe = stylePanel.iframe;
+  let contentDoc = iframe.contentDocument;
+  let contentWindow = iframe.contentWindow;
+  let expando = contentDoc.querySelectorAll(".expandable")[aIndex];
+  expando.click();
+
+  // We use executeSoon to give the property time to expand.
+  executeSoon(aCallback);
+}
+
+function getLinkByIndex(aIndex)
+{
+  let contentDoc = stylePanel.iframe.contentDocument;
+  let links = contentDoc.querySelectorAll(".rule-link .link");
+  return links[aIndex];
+}
+
+function finishUp()
+{
+  Services.obs.removeObserver(finishUp, "StyleInspector-closed", false);
+  ok(!stylePanel.isOpen(), "style inspector is closed");
+  doc = win = stylePanel = null;
+  gBrowser.removeCurrentTab();
+  finish();
+}
+
+function test()
+{
+  waitForExplicitFinish();
+
+  gBrowser.selectedTab = gBrowser.addTab();
+  gBrowser.selectedBrowser.addEventListener("load", function(evt) {
+    gBrowser.selectedBrowser.removeEventListener(evt.type, arguments.callee,
+      true);
+    doc = content.document;
+    waitForFocus(createDocument, content);
+  }, true);
+
+  content.location = "data:text/html,<p>Computed view style editor link test</p>";
+}
new file mode 100644
--- /dev/null
+++ b/browser/devtools/styleinspector/test/browser_ruleview_734259_style_editor_link.js
@@ -0,0 +1,181 @@
+/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+let win;
+let doc;
+let contentWindow;
+
+let tempScope = {};
+Cu.import("resource:///modules/Services.jsm", tempScope);
+let Services = tempScope.Services;
+
+function createDocument()
+{
+  doc.body.innerHTML = '<style type="text/css"> ' +
+    'html { color: #000000; } ' +
+    'span { font-variant: small-caps; color: #000000; } ' +
+    '.nomatches {color: #ff0000;}</style> <div id="first" style="margin: 10em; ' +
+    'font-size: 14pt; font-family: helvetica, sans-serif; color: #AAA">\n' +
+    '<h1>Some header text</h1>\n' +
+    '<p id="salutation" style="font-size: 12pt">hi.</p>\n' +
+    '<p id="body" style="font-size: 12pt">I am a test-case. This text exists ' +
+    'solely to provide some things to <span style="color: yellow">' +
+    'highlight</span> and <span style="font-weight: bold">count</span> ' +
+    'style list-items in the box at right. If you are reading this, ' +
+    'you should go do something else instead. Maybe read a book. Or better ' +
+    'yet, write some test-cases for another bit of code. ' +
+    '<span style="font-style: italic">some text</span></p>\n' +
+    '<p id="closing">more text</p>\n' +
+    '<p>even more text</p>' +
+    '</div>';
+  doc.title = "Rule view style editor link test";
+
+  openInspector();
+}
+
+function openInspector()
+{
+  ok(window.InspectorUI, "InspectorUI variable exists");
+  ok(!InspectorUI.inspecting, "Inspector is not highlighting");
+  ok(InspectorUI.store.isEmpty(), "Inspector.store is empty");
+
+  Services.obs.addObserver(inspectorUIOpen,
+    InspectorUI.INSPECTOR_NOTIFICATIONS.OPENED, false);
+  InspectorUI.openInspectorUI();
+}
+
+function inspectorUIOpen()
+{
+  Services.obs.removeObserver(inspectorUIOpen,
+    InspectorUI.INSPECTOR_NOTIFICATIONS.OPENED, false);
+
+  // Make sure the inspector is open.
+  ok(InspectorUI.inspecting, "Inspector is highlighting");
+  ok(!InspectorUI.treePanel.isOpen(), "Inspector Tree Panel is not open");
+  ok(!InspectorUI.isSidebarOpen, "Inspector Sidebar is not open");
+  ok(!InspectorUI.store.isEmpty(), "InspectorUI.store is not empty");
+  is(InspectorUI.store.length, 1, "Inspector.store.length = 1");
+
+  // Highlight a node.
+  let div = content.document.getElementsByTagName("div")[0];
+  InspectorUI.inspectNode(div);
+  InspectorUI.stopInspecting();
+  is(InspectorUI.selection, div, "selection matches the div element");
+
+  Services.obs.addObserver(testInlineStyle,
+    InspectorUI.INSPECTOR_NOTIFICATIONS.RULEVIEWREADY, false);
+
+  InspectorUI.showSidebar();
+  InspectorUI.openRuleView();
+}
+
+function testInlineStyle()
+{
+  Services.obs.removeObserver(testInlineStyle,
+    InspectorUI.INSPECTOR_NOTIFICATIONS.RULEVIEWREADY, false);
+
+  executeSoon(function() {
+    info("clicking an inline style");
+
+    Services.ww.registerNotification(function onWindow(aSubject, aTopic) {
+      if (aTopic != "domwindowopened") {
+        return;
+      }
+
+      win = aSubject.QueryInterface(Ci.nsIDOMWindow);
+      win.addEventListener("load", function windowLoad() {
+        win.removeEventListener("load", windowLoad);
+        let windowType = win.document.documentElement.getAttribute("windowtype");
+        is(windowType, "navigator:view-source", "view source window is open");
+        win.close();
+        Services.ww.unregisterNotification(onWindow);
+        testInlineStyleSheet();
+      });
+    });
+    EventUtils.synthesizeMouseAtCenter(getLinkByIndex(0), { }, contentWindow);
+  });
+}
+
+function testInlineStyleSheet()
+{
+  info("clicking an inline stylesheet");
+
+  Services.ww.registerNotification(function onWindow(aSubject, aTopic) {
+    if (aTopic != "domwindowopened") {
+      return;
+    }
+
+    win = aSubject.QueryInterface(Ci.nsIDOMWindow);
+    win.addEventListener("load", function windowLoad() {
+      win.removeEventListener("load", windowLoad);
+
+      let windowType = win.document.documentElement.getAttribute("windowtype");
+      is(windowType, "Tools:StyleEditor", "style editor window is open");
+
+      win.styleEditorChrome.addChromeListener({
+        onEditorAdded: function checkEditor(aChrome, aEditor) {
+          if (!aEditor.sourceEditor) {
+            aEditor.addActionListener({
+              onAttach: function (aEditor) {
+                aEditor.removeActionListener(this);
+                validateStyleEditorSheet(aEditor);
+              }
+            });
+          } else {
+            validateStyleEditorSheet(aEditor);
+          }
+        }
+      });
+
+      Services.ww.unregisterNotification(onWindow);
+    });
+  });
+
+  EventUtils.synthesizeMouse(getLinkByIndex(1), 5, 5, { }, contentWindow);
+}
+
+function validateStyleEditorSheet(aEditor)
+{
+  info("validating style editor stylesheet");
+
+  let sheet = doc.styleSheets[0];
+
+  is(aEditor.styleSheet, sheet, "loaded stylesheet matches document stylesheet");
+  win.close();
+
+  finishup();
+}
+
+function getLinkByIndex(aIndex)
+{
+  let ruleView = document.querySelector("#devtools-sidebar-iframe-ruleview");
+  let contentDoc = ruleView.contentDocument;
+  let links = contentDoc.querySelectorAll(".ruleview-rule-source");
+  contentWindow = ruleView.contentWindow;
+  return links[aIndex];
+}
+
+function finishup()
+{
+  InspectorUI.hideSidebar();
+  InspectorUI.closeInspectorUI();
+  gBrowser.removeCurrentTab();
+  doc = contentWindow = win = null;
+  finish();
+}
+
+function test()
+{
+  waitForExplicitFinish();
+
+  gBrowser.selectedTab = gBrowser.addTab();
+  gBrowser.selectedBrowser.addEventListener("load", function(evt) {
+    gBrowser.selectedBrowser.removeEventListener(evt.type, arguments.callee,
+      true);
+    doc = content.document;
+    waitForFocus(createDocument, content);
+  }, true);
+
+  content.location = "data:text/html,<p>Rule view style editor link test</p>";
+}
--- a/browser/devtools/styleinspector/test/browser_ruleview_bug_703643_context_menu_copy.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_bug_703643_context_menu_copy.js
@@ -182,16 +182,17 @@ function checkClipboardData(aExpectedPat
 {
   let actual = SpecialPowers.getClipboardData("text/unicode");
   let expectedRegExp = new RegExp(aExpectedPattern, "g");
   return expectedRegExp.test(actual);
 }
 
 function finishup()
 {
+  InspectorUI.hideSidebar();
   InspectorUI.closeInspectorUI();
   gBrowser.removeCurrentTab();
   doc = null;
   finish();
 }
 
 function test()
 {
--- a/browser/devtools/styleinspector/test/browser_ruleview_focus.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_focus.js
@@ -72,28 +72,30 @@ function testFocus()
       // If we actually get this focus we're ok.
       ok(true, "We got focus.");
       aEditor.input.value = "green";
 
       // If we've retained focus, pressing return will start a new editor.
       // If not, we'll wait here until we time out.
       waitForEditorFocus(brace.parentNode, function onNewEditor(aEditor) {
         aEditor.input.blur();
-        finishTest();
+        finishUp();
       });
       EventUtils.sendKey("return");
     });
     EventUtils.sendKey("return");
   });
 
   brace.focus();
 }
 
 function finishUp()
 {
+  InspectorUI.hideSidebar();
+  InspectorUI.closeInspectorUI();
   doc = stylePanel = null;
   gBrowser.removeCurrentTab();
   finish();
 }
 
 function test()
 {
   waitForExplicitFinish();
--- a/browser/devtools/tilt/test/browser_tilt_picking.js
+++ b/browser/devtools/tilt/test/browser_tilt_picking.js
@@ -17,18 +17,19 @@ function test() {
   createTab(function() {
     createTilt({
       onTiltOpen: function(instance)
       {
         let presenter = instance.presenter;
         let canvas = presenter.canvas;
 
         presenter._onSetupMesh = function() {
+          let p = getPickablePoint(presenter);
 
-          presenter.pickNode(canvas.width / 2, 10, {
+          presenter.pickNode(p[0], p[1], {
             onpick: function(data)
             {
               ok(data.index > 0,
                 "Simply picking a node didn't work properly.");
 
               Services.obs.addObserver(cleanup, DESTROYED, false);
               InspectorUI.closeInspectorUI();
             }
--- a/browser/devtools/tilt/test/browser_tilt_picking_delete.js
+++ b/browser/devtools/tilt/test/browser_tilt_picking_delete.js
@@ -19,17 +19,19 @@ function test() {
   createTab(function() {
     createTilt({
       onTiltOpen: function(instance)
       {
         presenter = instance.presenter;
         Services.obs.addObserver(whenNodeRemoved, NODE_REMOVED, false);
 
         presenter._onSetupMesh = function() {
-          presenter.highlightNodeAt(presenter.canvas.width / 2, 10, {
+          let p = getPickablePoint(presenter);
+
+          presenter.highlightNodeAt(p[0], p[1], {
             onpick: function()
             {
               ok(presenter._currentSelection > 0,
                 "Highlighting a node didn't work properly.");
               ok(!presenter._highlight.disabled,
                 "After highlighting a node, it should be highlighted. D'oh.");
 
               presenter.deleteNode();
--- a/browser/devtools/tilt/test/browser_tilt_picking_highlight01-offs.js
+++ b/browser/devtools/tilt/test/browser_tilt_picking_highlight01-offs.js
@@ -9,17 +9,16 @@ function test() {
     info("Skipping highlight test because Tilt isn't enabled.");
     return;
   }
   if (!isWebGLSupported()) {
     info("Skipping highlight test because WebGL isn't supported.");
     return;
   }
 
-  requestLongerTimeout(10);
   waitForExplicitFinish();
 
   createTab(function() {
     createTilt({
       onTiltOpen: function(instance)
       {
         presenter = instance.presenter;
         Services.obs.addObserver(whenHighlighting, HIGHLIGHTING, false);
--- a/browser/devtools/tilt/test/browser_tilt_picking_highlight01.js
+++ b/browser/devtools/tilt/test/browser_tilt_picking_highlight01.js
@@ -18,17 +18,17 @@ function test() {
 
   createTab(function() {
     createTilt({
       onTiltOpen: function(instance)
       {
         presenter = instance.presenter;
         Services.obs.addObserver(whenHighlighting, HIGHLIGHTING, false);
 
-        presenter._onSetupMesh = function() {
+        presenter._onInitializationFinished = function() {
           let contentDocument = presenter.contentWindow.document;
           let div = contentDocument.getElementById("first-law");
 
           presenter.highlightNode(div, "moveIntoView");
         };
       }
     });
   });
--- a/browser/devtools/tilt/test/browser_tilt_picking_highlight02.js
+++ b/browser/devtools/tilt/test/browser_tilt_picking_highlight02.js
@@ -18,34 +18,34 @@ function test() {
 
   createTab(function() {
     createTilt({
       onTiltOpen: function(instance)
       {
         presenter = instance.presenter;
         Services.obs.addObserver(whenHighlighting, HIGHLIGHTING, false);
 
-        presenter._onSetupMesh = function() {
-          presenter.highlightNodeAt(presenter.canvas.width / 2, 10);
+        presenter._onInitializationFinished = function() {
+          presenter.highlightNodeAt.apply(this, getPickablePoint(presenter));
         };
       }
     });
   });
 }
 
 function whenHighlighting() {
   ok(presenter._currentSelection > 0,
     "Highlighting a node didn't work properly.");
   ok(!presenter._highlight.disabled,
     "After highlighting a node, it should be highlighted. D'oh.");
 
   executeSoon(function() {
     Services.obs.removeObserver(whenHighlighting, HIGHLIGHTING);
     Services.obs.addObserver(whenUnhighlighting, UNHIGHLIGHTING, false);
-    presenter.highlightNodeAt(-1, -1);
+    presenter.highlightNode(null);
   });
 }
 
 function whenUnhighlighting() {
   ok(presenter._currentSelection < 0,
     "Unhighlighting a should remove the current selection.");
   ok(presenter._highlight.disabled,
     "After unhighlighting a node, it shouldn't be highlighted anymore. D'oh.");
--- a/browser/devtools/tilt/test/browser_tilt_picking_highlight03.js
+++ b/browser/devtools/tilt/test/browser_tilt_picking_highlight03.js
@@ -18,18 +18,18 @@ function test() {
 
   createTab(function() {
     createTilt({
       onTiltOpen: function(instance)
       {
         presenter = instance.presenter;
         Services.obs.addObserver(whenHighlighting, HIGHLIGHTING, false);
 
-        presenter._onSetupMesh = function() {
-          presenter.highlightNodeFor(5); // 1 = html, 2 = body, 3 = first div
+        presenter._onInitializationFinished = function() {
+          presenter.highlightNodeFor(3); // 1 = html, 2 = body, 3 = first div
         };
       }
     });
   });
 }
 
 function whenHighlighting() {
   ok(presenter._currentSelection > 0,
--- a/browser/devtools/tilt/test/browser_tilt_picking_miv.js
+++ b/browser/devtools/tilt/test/browser_tilt_picking_miv.js
@@ -9,17 +9,16 @@ function test() {
     info("Skipping highlight test because Tilt isn't enabled.");
     return;
   }
   if (!isWebGLSupported()) {
     info("Skipping highlight test because WebGL isn't supported.");
     return;
   }
 
-  requestLongerTimeout(10);
   waitForExplicitFinish();
 
   createTab(function() {
     createTilt({
       onTiltOpen: function(instance)
       {
         presenter = instance.presenter;
         Services.obs.addObserver(whenHighlighting, HIGHLIGHTING, false);
--- a/browser/devtools/tilt/test/head.js
+++ b/browser/devtools/tilt/test/head.js
@@ -19,16 +19,17 @@ let TiltUtils = tempScope.TiltUtils;
 let TiltVisualizer = tempScope.TiltVisualizer;
 let LayoutHelpers = tempScope.LayoutHelpers;
 
 
 const DEFAULT_HTML = "data:text/html," +
   "<DOCTYPE html>" +
   "<html>" +
     "<head>" +
+      "<meta charset='utf-8'/>" +
       "<title>Three Laws</title>" +
     "</head>" +
     "<body>" +
       "<div id='first-law'>" +
         "A robot may not injure a human being or, through inaction, allow a " +
         "human being to come to harm." +
       "</div>" +
       "<div>" +
@@ -189,8 +190,21 @@ function createTilt(callbacks, close) {
         callbacks.onInspectorClose();
       }
       if ("function" === typeof callbacks.onEnd) {
         callbacks.onEnd();
       }
     });
   }
 }
+
+function getPickablePoint(presenter) {
+  let vertices = presenter._meshStacks[0].vertices.components;
+
+  let topLeft = vec3.create([vertices[0], vertices[1], vertices[2]]);
+  let bottomRight = vec3.create([vertices[6], vertices[7], vertices[8]]);
+  let center = vec3.lerp(topLeft, bottomRight, 0.5, []);
+
+  let renderer = presenter._renderer;
+  let viewport = [0, 0, renderer.width, renderer.height];
+
+  return vec3.project(center, viewport, renderer.mvMatrix, renderer.projMatrix);
+}
--- a/browser/devtools/webconsole/test/browser_gcli_break.js
+++ b/browser/devtools/webconsole/test/browser_gcli_break.js
@@ -68,17 +68,17 @@ function testCreateCommands() {
   type("break add line");
   is(requisition.getStatus().toString(), "ERROR", "break add line is ERROR");
 
   let pane = DebuggerUI.toggleDebugger();
   pane.onConnected = function test_onConnected(aPane) {
     // Wait for the initial resume.
     aPane.debuggerWindow.gClient.addOneTimeListener("resumed", function() {
       delete aPane.onConnected;
-      aPane.debuggerWindow.gClient.activeThread.addOneTimeListener("scriptsadded", function() {
+      aPane.debuggerWindow.gClient.activeThread.addOneTimeListener("framesadded", function() {
         type("break add line " + TEST_URI + " " + content.wrappedJSObject.line0);
         is(requisition.getStatus().toString(), "VALID", "break add line is VALID");
         requisition.exec();
 
         type("break list");
         is(requisition.getStatus().toString(), "VALID", "break list is VALID");
         requisition.exec();
 
--- a/browser/installer/Makefile.in
+++ b/browser/installer/Makefile.in
@@ -89,16 +89,21 @@ ifdef MOZ_ANGLE
 DEFINES += -DMOZ_ANGLE=$(MOZ_ANGLE)
 DEFINES += -DMOZ_D3DX9_DLL=$(MOZ_D3DX9_DLL)
 DEFINES += -DMOZ_D3DCOMPILER_DLL=$(MOZ_D3DCOMPILER_DLL)
 endif
 
 include $(topsrcdir)/ipc/app/defs.mk
 DEFINES += -DMOZ_CHILD_PROCESS_NAME=$(MOZ_CHILD_PROCESS_NAME)
 
+# Set MSVC dlls version to package, if any.
+ifdef WIN32_REDIST_DIR
+DEFINES += -DMOZ_MSVC_REDIST=$(_MSC_VER)
+endif
+
 ifneq (,$(filter aurora beta,$(MOZ_UPDATE_CHANNEL)))
 DEFINES += -DSHIP_FEEDBACK=1
 endif
 
 ifneq (,$(filter WINNT Darwin Android,$(OS_TARGET)))
 DEFINES += -DMOZ_SHARED_MOZGLUE=1
 endif
 
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -65,30 +65,30 @@
 #ifdef XP_MACOSX
 @BINPATH@/@MOZ_CHILD_PROCESS_NAME@.app/
 @BINPATH@/@DLL_PREFIX@plugin_child_interpose@DLL_SUFFIX@
 #else
 @BINPATH@/@MOZ_CHILD_PROCESS_NAME@
 #endif
 #ifdef XP_WIN32
 #ifndef MOZ_DEBUG
-#if _MSC_VER == 1400
+#if MOZ_MSVC_REDIST == 1400
 @BINPATH@/Microsoft.VC80.CRT.manifest
 @BINPATH@/msvcm80.dll
 @BINPATH@/msvcp80.dll
 @BINPATH@/msvcr80.dll
-#elif _MSC_VER == 1500
+#elif MOZ_MSVC_REDIST == 1500
 @BINPATH@/Microsoft.VC90.CRT.manifest
 @BINPATH@/msvcm90.dll
 @BINPATH@/msvcp90.dll
 @BINPATH@/msvcr90.dll
-#elif _MSC_VER == 1600
+#elif MOZ_MSVC_REDIST == 1600
 @BINPATH@/msvcp100.dll
 @BINPATH@/msvcr100.dll
-#elif _MSC_VER == 1700
+#elif MOZ_MSVC_REDIST == 1700
 @BINPATH@/msvcp110.dll
 @BINPATH@/msvcr110.dll
 #endif
 #endif
 #endif
 
 [browser]
 ; [Base Browser Files]
@@ -284,16 +284,18 @@
 @BINPATH@/components/xuldoc.xpt
 @BINPATH@/components/xultmpl.xpt
 @BINPATH@/components/zipwriter.xpt
 @BINPATH@/components/telemetry.xpt
 
 ; JavaScript components
 @BINPATH@/components/ConsoleAPI.manifest
 @BINPATH@/components/ConsoleAPI.js
+@BINPATH@/components/BrowserElementAPI.manifest
+@BINPATH@/components/BrowserElementAPI.js
 @BINPATH@/components/FeedProcessor.manifest
 @BINPATH@/components/FeedProcessor.js
 @BINPATH@/components/BrowserFeeds.manifest
 @BINPATH@/components/FeedConverter.js
 @BINPATH@/components/FeedWriter.js
 @BINPATH@/components/fuelApplication.manifest
 @BINPATH@/components/fuelApplication.js
 @BINPATH@/components/WebContentConverter.js
--- a/browser/installer/removed-files.in
+++ b/browser/installer/removed-files.in
@@ -1347,39 +1347,39 @@ xpicleanup@BIN_SUFFIX@
 #ifndef XP_WIN
   res/fonts/mathfontSymbol.properties
 #endif
 #ifdef XP_WIN
   components/brwsrcmp.dll
   components/jsd3250.dll
   components/nsPostUpdateWin.js
   js3250.dll
-  plugins/npnul32.dll
-  #if _MSC_VER != 1400
+  mozcpp19.dll
+  mozcrt19.dll
+  #if MOZ_MSVC_REDIST != 1400
     Microsoft.VC80.CRT.manifest
     msvcm80.dll
     msvcp80.dll
     msvcr80.dll
   #endif
-  #if _MSC_VER != 1500
+  #if MOZ_MSVC_REDIST != 1500
     Microsoft.VC90.CRT.manifest
     msvcm90.dll
     msvcp90.dll
     msvcr90.dll
   #endif
-  #if _MSC_VER != 1600
+  #if MOZ_MSVC_REDIST != 1600
     msvcp100.dll
     msvcr100.dll
   #endif
-  #if _MSC_VER != 1700
+  #if MOZ_MSVC_REDIST != 1700
     msvcp110.dll
     msvcr110.dll
   #endif
-  mozcrt19.dll
-  mozcpp19.dll
+  plugins/npnul32.dll
 #endif
 @DLL_PREFIX@xpcom_core@DLL_SUFFIX@
 components/@DLL_PREFIX@jar50@DLL_SUFFIX@
 #ifdef XP_WIN
   components/xpinstal.dll
 #else
   components/@DLL_PREFIX@jsd@DLL_SUFFIX@
   components/@DLL_PREFIX@xpinstall@DLL_SUFFIX@
--- a/browser/locales/en-US/chrome/browser/aboutHome.dtd
+++ b/browser/locales/en-US/chrome/browser/aboutHome.dtd
@@ -19,8 +19,9 @@
 <!ENTITY abouthome.defaultSnippet2.v1 "It's easy to customize your Firefox exactly the way you want it. <a>Choose from thousands of add-ons</a>.">
 
 <!ENTITY abouthome.bookmarksButton.label "Bookmarks">
 <!ENTITY abouthome.historyButton.label   "History">
 <!ENTITY abouthome.settingsButton.label  "Settings">
 <!ENTITY abouthome.addonsButton.label    "Add-ons">
 <!ENTITY abouthome.appsButton.label      "Marketplace">
 <!ENTITY abouthome.downloadsButton.label "Downloads">
+<!ENTITY abouthome.syncButton.label      "&syncBrand.shortName.label;">
--- a/browser/locales/en-US/chrome/browser/devtools/debugger.properties
+++ b/browser/locales/en-US/chrome/browser/devtools/debugger.properties
@@ -25,17 +25,17 @@ runningState=Running
 # LOCALIZATION NOTE (localScope): The label that is displayed in the variables
 # pane as a header on the local scope container.
 localScope=Local
 
 # LOCALIZATION NOTE (globalScope): The label that is displayed in the variables
 # pane as a header on the globel scope container.
 globalScope=Global
 
-# LOCALIZATION NOTE (localScope): The label that is displayed in the variables
+# LOCALIZATION NOTE (withScope): The label that is displayed in the variables
 # pane as a header on the container for identifiers in a with block.
 withScope=With block
 
 # LOCALIZATION NOTE (closureScope): The label that is displayed in the variables
 # pane as a header on container for identifiers in a closure scope.
 closureScope=Closure
 
 # LOCALIZATION NOTE (emptyText): The text that is displayed in the stack frames
--- a/browser/locales/en-US/searchplugins/google.xml
+++ b/browser/locales/en-US/searchplugins/google.xml
@@ -8,17 +8,17 @@
 #else
 #define GOOGLE_CLIENT_PARAM <MozParam name="client" condition="defaultEngine" trueValue="firefox-a" falseValue="firefox"/>
 #endif
 <SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
 <ShortName>Google</ShortName>
 <Description>Google Search</Description>
 <InputEncoding>UTF-8</InputEncoding>
 <Image width="16" height="16">data:image/png;base64,AAABAAEAEBAAAAEAGABoAwAAFgAAACgAAAAQAAAAIAAAAAEAGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADs9Pt8xetPtu9FsfFNtu%2BTzvb2%2B%2Fne4dFJeBw0egA%2FfAJAfAA8ewBBegAAAAD%2B%2FPtft98Mp%2BwWsfAVsvEbs%2FQeqvF8xO7%2F%2F%2F63yqkxdgM7gwE%2FggM%2BfQA%2BegBDeQDe7PIbotgQufcMufEPtfIPsvAbs%2FQvq%2Bfz%2Bf%2F%2B%2B%2FZKhR05hgBBhQI8hgBAgAI9ewD0%2B%2Fg3pswAtO8Cxf4Kw%2FsJvvYAqupKsNv%2B%2Fv7%2F%2FP5VkSU0iQA7jQA9hgBDgQU%2BfQH%2F%2Ff%2FQ6fM4sM4KsN8AteMCruIqqdbZ7PH8%2Fv%2Fg6Nc%2Fhg05kAA8jAM9iQI%2BhQA%2BgQDQu6b97uv%2F%2F%2F7V8Pqw3eiWz97q8%2Ff%2F%2F%2F%2F7%2FPptpkkqjQE4kwA7kAA5iwI8iAA8hQCOSSKdXjiyflbAkG7u2s%2F%2B%2F%2F39%2F%2F7r8utrqEYtjQE8lgA7kwA7kwA9jwA9igA9hACiWSekVRyeSgiYSBHx6N%2F%2B%2Fv7k7OFRmiYtlAA5lwI7lwI4lAA7kgI9jwE9iwI4iQCoVhWcTxCmb0K%2BooT8%2Fv%2F7%2F%2F%2FJ2r8fdwI1mwA3mQA3mgA8lAE8lAE4jwA9iwE%2BhwGfXifWvqz%2B%2Ff%2F58u%2Fev6Dt4tr%2B%2F%2F2ZuIUsggA7mgM6mAM3lgA5lgA6kQE%2FkwBChwHt4dv%2F%2F%2F728ei1bCi7VAC5XQ7kz7n%2F%2F%2F6bsZkgcB03lQA9lgM7kwA2iQktZToPK4r9%2F%2F%2F9%2F%2F%2FSqYK5UwDKZAS9WALIkFn%2B%2F%2F3%2F%2BP8oKccGGcIRJrERILYFEMwAAuEAAdX%2F%2Ff7%2F%2FP%2B%2BfDvGXQLIZgLEWgLOjlf7%2F%2F%2F%2F%2F%2F9QU90EAPQAAf8DAP0AAfMAAOUDAtr%2F%2F%2F%2F7%2B%2Fu2bCTIYwDPZgDBWQDSr4P%2F%2Fv%2F%2F%2FP5GRuABAPkAA%2FwBAfkDAPAAAesAAN%2F%2F%2B%2Fz%2F%2F%2F64g1C5VwDMYwK8Yg7y5tz8%2Fv%2FV1PYKDOcAAP0DAf4AAf0AAfYEAOwAAuAAAAD%2F%2FPvi28ymXyChTATRrIb8%2F%2F3v8fk6P8MAAdUCAvoAAP0CAP0AAfYAAO4AAACAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAQAA</Image>
-<Url type="application/x-suggestions+json" method="GET" template="https://www.google.com/complete/search?output=firefox&amp;client=firefox&amp;hl={moz:locale}&amp;q={searchTerms}"/>
+<Url type="application/x-suggestions+json" method="GET" template="https://www.google.com/complete/search?client=firefox&amp;q={searchTerms}"/>
 <Url type="text/html" method="GET" template="https://www.google.com/search">
 #expand   __GOOGLE_PARAMS__
 #expand   __GOOGLE_CLIENT_PARAM__
 </Url>
 <!-- Keyword search URL is the same as the default, but with an additional parameter -->
 <Url type="application/x-moz-keywordsearch" method="GET" template="https://www.google.com/search">
 #expand   __GOOGLE_PARAMS__
 #expand   __GOOGLE_CLIENT_PARAM__
--- a/browser/themes/winstripe/browser-aero.css
+++ b/browser/themes/winstripe/browser-aero.css
@@ -148,38 +148,33 @@
 
   #main-window[sizemode=fullscreen]:not(:-moz-lwtheme) {
     -moz-appearance: none;
     background-color: #556;
   }
 
   #toolbar-menubar:not(:-moz-lwtheme),
   #TabsToolbar[tabsontop=true]:not(:-moz-lwtheme),
-  #navigator-toolbox[tabsontop=false] > #nav-bar:not(:-moz-lwtheme),
+  #nav-bar[tabsontop=false]:not(:-moz-lwtheme),
   #nav-bar + #customToolbars + #PersonalToolbar[collapsed=true] + #TabsToolbar[tabsontop=false]:last-child:not(:-moz-lwtheme) {
     background-color: transparent !important;
     color: black;
     text-shadow: 0 0 .5em white, 0 0 .5em white, 0 1px 0 rgba(255,255,255,.4);
     border-left-style: none !important;
     border-right-style: none !important;
   }
 
-  #toolbar-menubar :-moz-any(@primaryToolbarButtons@):not(:-moz-any(#alltabs-button,#tabview-button,#sync-button[status])) > .toolbarbutton-icon:not(:-moz-lwtheme),
+  :-moz-any(#toolbar-menubar, #nav-bar[tabsontop=false]) :-moz-any(@primaryToolbarButtons@):not(:-moz-any(#alltabs-button,#tabview-button,#sync-button[status])) > .toolbarbutton-icon:not(:-moz-lwtheme),
   #TabsToolbar[tabsontop=true] :-moz-any(@primaryToolbarButtons@):not(:-moz-any(#alltabs-button,#tabview-button,#new-tab-button,#sync-button[status])) > .toolbarbutton-icon:not(:-moz-lwtheme),
-  #navigator-toolbox[tabsontop=false] > #nav-bar :-moz-any(@primaryToolbarButtons@):not(:-moz-any(#alltabs-button,#tabview-button,#sync-button[status])) > .toolbarbutton-icon:not(:-moz-lwtheme),
   #nav-bar + #customToolbars + #PersonalToolbar[collapsed=true] + #TabsToolbar[tabsontop=false]:last-child :-moz-any(@primaryToolbarButtons@):not(:-moz-any(#alltabs-button,#tabview-button,#new-tab-button,#sync-button[status])) > .toolbarbutton-icon:not(:-moz-lwtheme) {
     list-style-image: url("chrome://browser/skin/Toolbar-inverted.png");
   }
 
-  #toolbar-menubar .toolbarbutton-1 > .toolbarbutton-menu-dropmarker:not(:-moz-lwtheme),
-  #toolbar-menubar .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker:not(:-moz-lwtheme),
-  #TabsToolbar[tabsontop=true] .toolbarbutton-1 > .toolbarbutton-menu-dropmarker:not(:-moz-lwtheme),
-  #TabsToolbar[tabsontop=true] .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker:not(:-moz-lwtheme),
-  #navigator-toolbox[tabsontop=false] > #nav-bar .toolbarbutton-1 > .toolbarbutton-menu-dropmarker:not(:-moz-lwtheme),
-  #navigator-toolbox[tabsontop=false] > #nav-bar .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker:not(:-moz-lwtheme),
+  :-moz-any(#toolbar-menubar, #TabsToolbar[tabsontop=true], #nav-bar[tabsontop=false]) .toolbarbutton-1 > .toolbarbutton-menu-dropmarker:not(:-moz-lwtheme),
+  :-moz-any(#toolbar-menubar, #TabsToolbar[tabsontop=true], #nav-bar[tabsontop=false]) .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker:not(:-moz-lwtheme),
   #nav-bar + #customToolbars + #PersonalToolbar[collapsed=true] + #TabsToolbar[tabsontop=false]:last-child .toolbarbutton-1 > .toolbarbutton-menu-dropmarker:not(:-moz-lwtheme),
   #nav-bar + #customToolbars + #PersonalToolbar[collapsed=true] + #TabsToolbar[tabsontop=false]:last-child .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker:not(:-moz-lwtheme) {
     list-style-image: url("chrome://browser/skin/toolbarbutton-dropdown-arrow-inverted.png");
   }
 
   /* Vertical toolbar border */
   #main-window[sizemode=normal] #navigator-toolbox::after,
   #main-window[sizemode=normal] #navigator-toolbox[tabsontop=true] > toolbar:not(#toolbar-menubar):not(#TabsToolbar),
@@ -206,19 +201,19 @@
   #main-window[sizemode=normal][tabsontop=false] #PersonalToolbar:not(:-moz-lwtheme) {
     border-top-left-radius: 2.5px;
     border-top-right-radius: 2.5px;
   }
 
   /* Toolbar shadow behind tabs */
   /* This code is only needed for restored windows (i.e. sizemode=normal)
      because of the border radius on the toolbar below the tab bar. */
-  #main-window[sizemode=normal] #navigator-toolbox[tabsontop=true] > #nav-bar:not(:-moz-lwtheme),
-  #main-window[sizemode=normal] #navigator-toolbox[tabsontop=true] > #nav-bar[collapsed=true]:not([customizing]) + toolbar:not(:-moz-lwtheme),
-  #main-window[sizemode=normal] #navigator-toolbox[tabsontop=true] > #nav-bar[collapsed=true]:not([customizing]) + #customToolbars + #PersonalToolbar:not(:-moz-lwtheme),
+  #main-window[sizemode=normal] #nav-bar[tabsontop=true]:not(:-moz-lwtheme),
+  #main-window[sizemode=normal] #nav-bar[tabsontop=true][collapsed=true]:not([customizing]) + toolbar:not(:-moz-lwtheme),
+  #main-window[sizemode=normal] #nav-bar[tabsontop=true][collapsed=true]:not([customizing]) + #customToolbars + #PersonalToolbar:not(:-moz-lwtheme),
   #main-window[sizemode=normal][disablechrome] #navigator-toolbox[tabsontop=true]:not(:-moz-lwtheme)::after {
     border-top: 1px solid @toolbarShadowColor@;
     border-top-left-radius: 2.5px;
     border-top-right-radius: 2.5px;
     background-clip: padding-box;
   }
   #main-window[sizemode=normal] #TabsToolbar[tabsontop=true]:not(:-moz-lwtheme) {
     margin-bottom: -1px;
@@ -253,17 +248,17 @@
     background-color: @customToolbarColor@;
     background-image: -moz-linear-gradient(@toolbarHighlight@, @toolbarHighlight@);
     height: 4px;
   }
 
   /* Make the window draggable by glassed toolbars (bug 555081) */
   #toolbar-menubar:not([autohide="true"]),
   #TabsToolbar[tabsontop="true"],
-  #navigator-toolbox[tabsontop="false"] > #nav-bar,
+  #nav-bar[tabsontop=false],
   #nav-bar + #customToolbars + #PersonalToolbar[collapsed="true"] + #TabsToolbar[tabsontop="false"]:last-child,
   #navigator-toolbox > toolbar:not(#toolbar-menubar):-moz-lwtheme {
     -moz-binding: url("chrome://global/content/bindings/toolbar.xml#toolbar-drag");
   }
 
   #appcontent:not(:-moz-lwtheme) {
     background-color: -moz-dialog;
   }
--- a/browser/themes/winstripe/browser.css
+++ b/browser/themes/winstripe/browser.css
@@ -126,19 +126,19 @@
   #main-window[tabsintitlebar] #titlebar-content:-moz-lwtheme {
     -moz-binding: url("chrome://global/content/bindings/general.xml#windowdragbox");
     visibility: visible;
   }
 %ifdef WINSTRIPE_AERO
 }
 %endif
 
-#navigator-toolbox[tabsontop="true"] > #nav-bar,
-#navigator-toolbox[tabsontop="true"]:not([customizing]) > #nav-bar[collapsed="true"] + toolbar,
-#navigator-toolbox[tabsontop="true"]:not([customizing]) > #nav-bar[collapsed="true"] + #customToolbars + #PersonalToolbar {
+#nav-bar[tabsontop=true],
+#nav-bar[tabsontop=true][collapsed=true]:not([customizing]) + toolbar,
+#nav-bar[tabsontop=true][collapsed=true]:not([customizing]) + #customToolbars + #PersonalToolbar {
   background-image: -moz-linear-gradient(@toolbarHighlight@, rgba(255,255,255,0));
 }
 
 #personal-bookmarks {
   min-height: 24px;
 }
 
 #print-preview-toolbar:not(:-moz-lwtheme) {
@@ -996,20 +996,18 @@ toolbar[mode=full] .toolbarbutton-1 > .t
 /* tabview button */
 
 #tabview-button,
 #menu_tabview {
   list-style-image: url(chrome://browser/skin/tabview/tabview.png);
 }
 
 %ifdef WINSTRIPE_AERO
-#TabsToolbar > #tabview-button:-moz-system-metric(windows-compositor):not(:-moz-lwtheme),
-#TabsToolbar > toolbarpaletteitem > #tabview-button:-moz-system-metric(windows-compositor):not(:-moz-lwtheme),
-#navigator-toolbox[tabsontop=false] > #nav-bar #tabview-button:-moz-system-metric(windows-compositor):not(:-moz-lwtheme),
-#toolbar-menubar #tabview-button:-moz-system-metric(windows-compositor):not(:-moz-lwtheme),
+:-moz-any(#TabsToolbar, #nav-bar[tabsontop=false], #toolbar-menubar) > #tabview-button:-moz-system-metric(windows-compositor):not(:-moz-lwtheme),
+:-moz-any(#TabsToolbar, #nav-bar[tabsontop=false], #toolbar-menubar) > toolbarpaletteitem > #tabview-button:-moz-system-metric(windows-compositor):not(:-moz-lwtheme),
 %endif
 #tabview-button:-moz-lwtheme-brighttext {
   list-style-image: url(chrome://browser/skin/tabview/tabview-inverted.png);
 }
 
 #tabview-button {
   -moz-image-region: rect(0, 90px, 18px, 72px);
 }
@@ -2046,20 +2044,18 @@ richlistitem[type~="action"][actiontype=
 }
 
 #alltabs-button[type="menu"] {
   list-style-image: url("chrome://browser/skin/toolbarbutton-dropdown-arrow.png");
   -moz-image-region: auto;
 }
 
 %ifdef WINSTRIPE_AERO
-#TabsToolbar > #alltabs-button[type="menu"]:-moz-system-metric(windows-compositor):not(:-moz-lwtheme),
-#TabsToolbar > toolbarpaletteitem > #alltabs-button[type="menu"]:-moz-system-metric(windows-compositor):not(:-moz-lwtheme),
-#navigator-toolbox[tabsontop=false] > #nav-bar #alltabs-button[type="menu"]:-moz-system-metric(windows-compositor):not(:-moz-lwtheme),
-#toolbar-menubar #alltabs-button[type="menu"]:-moz-system-metric(windows-compositor):not(:-moz-lwtheme),
+:-moz-any(#TabsToolbar, #nav-bar[tabsontop=false], #toolbar-menubar) > #alltabs-button[type=menu]:-moz-system-metric(windows-compositor):not(:-moz-lwtheme),
+:-moz-any(#TabsToolbar, #nav-bar[tabsontop=false], #toolbar-menubar) > toolbarpaletteitem > #alltabs-button[type=menu]:-moz-system-metric(windows-compositor):not(:-moz-lwtheme),
 %endif
 #alltabs-button[type="menu"]:-moz-lwtheme-brighttext {
   list-style-image: url("chrome://browser/skin/toolbarbutton-dropdown-arrow-inverted.png");
 }
 
 #alltabs-button[type="menu"] > .toolbarbutton-icon {
   margin: 0 2px;
 }
--- a/content/base/public/nsContentUtils.h
+++ b/content/base/public/nsContentUtils.h
@@ -599,17 +599,18 @@ public:
    * form is a leaf element then all elements will be accepted into this list,
    * since this can happen due to content fixup when a form spans table rows or
    * table cells.
    */
   static bool BelongsInForm(nsIContent *aForm,
                               nsIContent *aContent);
 
   static nsresult CheckQName(const nsAString& aQualifiedName,
-                             bool aNamespaceAware = true);
+                             bool aNamespaceAware = true,
+                             const PRUnichar** aColon = nsnull);
 
   static nsresult SplitQName(const nsIContent* aNamespaceResolver,
                              const nsAFlatString& aQName,
                              PRInt32 *aNamespace, nsIAtom **aLocalName);
 
   static nsresult GetNodeInfoFromQName(const nsAString& aNamespaceURI,
                                        const nsAString& aQualifiedName,
                                        nsNodeInfoManager* aNodeInfoManager,
@@ -1281,78 +1282,22 @@ public:
   static void DestroyMatchString(void* aData)
   {
     if (aData) {
       nsString* matchString = static_cast<nsString*>(aData);
       delete matchString;
     }
   }
 
-  static void DropScriptObject(PRUint32 aLangID, void *aObject,
-                               const char *name, void *aClosure)
-  {
-    DropScriptObject(aLangID, aObject, aClosure);
-  }
-
   /**
    * Unbinds the content from the tree and nulls it out if it's not null.
    */
   static void DestroyAnonymousContent(nsCOMPtr<nsIContent>* aContent);
 
   /**
-   * Keep script object aNewObject, held by aScriptObjectHolder, alive.
-   *
-   * NOTE: This currently only supports objects that hold script objects of one
-   *       scripting language.
-   *
-   * @param aLangID script language ID of aNewObject
-   * @param aScriptObjectHolder the object that holds aNewObject
-   * @param aTracer the tracer for aScriptObject
-   * @param aNewObject the script object to hold
-   * @param aWasHoldingObjects whether aScriptObjectHolder was already holding
-   *                           script objects (ie. HoldScriptObject was called
-   *                           on it before, without a corresponding call to
-   *                           DropScriptObjects)
-   */
-  static nsresult HoldScriptObject(PRUint32 aLangID, void* aScriptObjectHolder,
-                                   nsScriptObjectTracer* aTracer,
-                                   void* aNewObject, bool aWasHoldingObjects)
-  {
-    if (aLangID == nsIProgrammingLanguage::JAVASCRIPT) {
-      return aWasHoldingObjects ? NS_OK :
-                                  HoldJSObjects(aScriptObjectHolder, aTracer);
-    }
-
-    return HoldScriptObject(aLangID, aNewObject);
-  }
-
-  /**
-   * Drop any script objects that aScriptObjectHolder is holding.
-   *
-   * NOTE: This currently only supports objects that hold script objects of one
-   *       scripting language.
-   *
-   * @param aLangID script language ID of the objects that 
-   * @param aScriptObjectHolder the object that holds script object that we want
-   *                            to drop
-   * @param aTracer the tracer for aScriptObject
-   */
-  static nsresult DropScriptObjects(PRUint32 aLangID, void* aScriptObjectHolder,
-                                    nsScriptObjectTracer* aTracer)
-  {
-    if (aLangID == nsIProgrammingLanguage::JAVASCRIPT) {
-      return DropJSObjects(aScriptObjectHolder);
-    }
-
-    aTracer->Trace(aScriptObjectHolder, DropScriptObject, nsnull);
-
-    return NS_OK;
-  }
-
-  /**
    * Keep the JS objects held by aScriptObjectHolder alive.
    *
    * @param aScriptObjectHolder the object that holds JS objects that we want to
    *                            keep alive
    * @param aTracer the tracer for aScriptObject
    */
   static nsresult HoldJSObjects(void* aScriptObjectHolder,
                                 nsScriptObjectTracer* aTracer);
@@ -2057,21 +2002,16 @@ public:
   static void SplitMimeType(const nsAString& aValue, nsString& aType,
                             nsString& aParams);
 
 private:
   static bool InitializeEventTable();
 
   static nsresult EnsureStringBundle(PropertiesFile aFile);
 
-  static nsIDOMScriptObjectFactory *GetDOMScriptObjectFactory();
-
-  static nsresult HoldScriptObject(PRUint32 aLangID, void* aObject);
-  static void DropScriptObject(PRUint32 aLangID, void *aObject, void *aClosure);
-
   static bool CanCallerAccess(nsIPrincipal* aSubjectPrincipal,
                                 nsIPrincipal* aPrincipal);
 
   static nsresult WrapNative(JSContext *cx, JSObject *scope,
                              nsISupports *native, nsWrapperCache *cache,
                              const nsIID* aIID, jsval *vp,
                              nsIXPConnectJSObjectHolder** aHolder,
                              bool aAllowWrapping);
@@ -2123,18 +2063,16 @@ private:
   static nsIStringBundle* sStringBundles[PropertiesFile_COUNT];
 
   static nsIContentPolicy* sContentPolicyService;
   static bool sTriedToGetContentPolicy;
 
   static nsILineBreaker* sLineBreaker;
   static nsIWordBreaker* sWordBreaker;
 
-  static nsIScriptRuntime* sScriptRuntimes[NS_STID_ARRAY_UBOUND];
-  static PRInt32 sScriptRootCount[NS_STID_ARRAY_UBOUND];
   static PRUint32 sJSGCThingRootCount;
 
 #ifdef IBMBIDI
   static nsIBidiKeyboard* sBidiKeyboard;
 #endif
 
   static bool sInitialized;
   static PRUint32 sScriptBlockerCount;
--- a/content/base/public/nsIContent.h
+++ b/content/base/public/nsIContent.h
@@ -522,17 +522,17 @@ public:
    * it is simply null;
    */
   virtual const nsTextFragment *GetText() = 0;
 
   /**
    * Get the length of the text content.
    * NOTE: This should not be called on elements.
    */
-  virtual PRUint32 TextLength() = 0;
+  virtual PRUint32 TextLength() const = 0;
 
   /**
    * Set the text to the given value. If aNotify is true then
    * the document is notified of the content change.
    * NOTE: For elements this always ASSERTS and returns NS_ERROR_FAILURE
    */
   virtual nsresult SetText(const PRUnichar* aBuffer, PRUint32 aLength,
                            bool aNotify) = 0;
--- a/content/base/public/nsIDocument.h
+++ b/content/base/public/nsIDocument.h
@@ -106,16 +106,17 @@ class nsIDOMNodeList;
 class mozAutoSubtreeModified;
 struct JSObject;
 class nsFrameLoader;
 class nsIBoxObject;
 class imgIRequest;
 class nsISHEntry;
 class nsDOMNavigationTiming;
 class nsWindowSizes;
+class nsIObjectLoadingContent;
 
 namespace mozilla {
 namespace css {
 class Loader;
 } // namespace css
 
 namespace dom {
 class Link;
@@ -1565,16 +1566,20 @@ public:
   // Add/Remove images from the document image tracker
   virtual nsresult AddImage(imgIRequest* aImage) = 0;
   virtual nsresult RemoveImage(imgIRequest* aImage) = 0;
 
   // Makes the images on this document locked/unlocked. By default, the locking
   // state is unlocked/false.
   virtual nsresult SetImageLockingState(bool aLocked) = 0;
 
+  virtual nsresult AddPlugin(nsIObjectLoadingContent* aPlugin) = 0;
+  virtual void RemovePlugin(nsIObjectLoadingContent* aPlugin) = 0;
+  virtual void GetPlugins(nsTArray<nsIObjectLoadingContent*>& aPlugins) = 0;
+
   virtual nsresult GetStateObject(nsIVariant** aResult) = 0;
 
   virtual nsDOMNavigationTiming* GetNavigationTiming() const = 0;
 
   virtual nsresult SetNavigationTiming(nsDOMNavigationTiming* aTiming) = 0;
 
   virtual Element* FindImageMap(const nsAString& aNormalizedMapName) = 0;
 
--- a/content/base/public/nsINode.h
+++ b/content/base/public/nsINode.h
@@ -286,18 +286,18 @@ private:
 // Categories of node properties
 // 0 is global.
 #define DOM_USER_DATA         1
 #define DOM_USER_DATA_HANDLER 2
 #define SMIL_MAPPED_ATTR_ANIMVAL 3
 
 // IID for the nsINode interface
 #define NS_INODE_IID \
-{ 0xfcd3b0d1, 0x75db, 0x46c4, \
-  { 0xa1, 0xf5, 0x07, 0xc2, 0x09, 0xf8, 0x1f, 0x44 } }
+{ 0x458300ed, 0xe418, 0x4577, \
+  { 0x89, 0xd7, 0xfe, 0xf1, 0x34, 0xf3, 0x52, 0x19 } }
 
 /**
  * An internal interface that abstracts some DOMNode-related parts that both
  * nsIContent and nsIDocument share.  An instance of this interface has a list
  * of nsIContent children and provides access to them.
  */
 class nsINode : public nsIDOMEventTarget,
                 public nsWrapperCache
@@ -582,22 +582,20 @@ public:
   /**
    * Remove a child from this node.  This method handles calling UnbindFromTree
    * on the child appropriately.
    *
    * @param aIndex the index of the child to remove
    * @param aNotify whether to notify the document (current document for
    *        nsIContent, and |this| for nsIDocument) that the remove has
    *        occurred
-   * @param aMutationEvent whether to fire a mutation event
    *
    * Note: If there is no child at aIndex, this method will simply do nothing.
    */
-  virtual nsresult RemoveChildAt(PRUint32 aIndex, 
-                                 bool aNotify) = 0;
+  virtual void RemoveChildAt(PRUint32 aIndex, bool aNotify) = 0;
 
   /**
    * Get a property associated with this node.
    *
    * @param aPropertyName  name of property to get.
    * @param aStatus        out parameter for storing resulting status.
    *                       Set to NS_PROPTABLE_PROP_NOT_THERE if the property
    *                       is not set.
@@ -1418,16 +1416,22 @@ protected:
   {
     mSubtreeRoot = nsnull;
   }
 
 public:
   // Optimized way to get classinfo.
   virtual nsXPCClassInfo* GetClassInfo() = 0;
 
+  /**
+   * Returns the length of this node, as specified at
+   * <http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-node-length>
+   */
+  PRUint32 Length() const;
+
 protected:
 
   // Override this function to create a custom slots class.
   virtual nsINode::nsSlots* CreateSlots();
 
   bool HasSlots() const
   {
     return mSlots != nsnull;
@@ -1502,18 +1506,18 @@ protected:
    * nodes.  The aChildArray passed in should be the one for |this|.
    *
    * @param aIndex The index to remove at.
    * @param aNotify Whether to notify.
    * @param aKid The kid at aIndex.  Must not be null.
    * @param aChildArray The child array to work with.
    * @param aMutationEvent whether to fire a mutation event for this removal.
    */
-  nsresult doRemoveChildAt(PRUint32 aIndex, bool aNotify, nsIContent* aKid,
-                           nsAttrAndChildArray& aChildArray);
+  void doRemoveChildAt(PRUint32 aIndex, bool aNotify, nsIContent* aKid,
+                       nsAttrAndChildArray& aChildArray);
 
   /**
    * Most of the implementation of the nsINode InsertChildAt method.
    * Should only be called on document, element, and document fragment
    * nodes.  The aChildArray passed in should be the one for |this|.
    *
    * @param aKid The child to insert.
    * @param aIndex The index to insert at.
--- a/content/base/public/nsIObjectLoadingContent.idl
+++ b/content/base/public/nsIObjectLoadingContent.idl
@@ -47,17 +47,17 @@ interface nsIURI;
 %{C++
 #include "nsNPAPIPluginInstance.h"
 %}
 [ptr] native nsNPAPIPluginInstancePtr(nsNPAPIPluginInstance);
 
 /**
  * This interface represents a content node that loads objects.
  */
-[scriptable, uuid(3FF07AB3-5BAC-4D98-9549-5BD15CCEBCD3)]
+[scriptable, uuid(fd56fda8-d3c3-4368-8cf3-67dbc992aec9)]
 interface nsIObjectLoadingContent : nsISupports
 {
   const unsigned long TYPE_LOADING  = 0;
   const unsigned long TYPE_IMAGE    = 1;
   const unsigned long TYPE_PLUGIN   = 2;
   const unsigned long TYPE_DOCUMENT = 3;
   const unsigned long TYPE_NULL     = 4;
 
@@ -120,16 +120,22 @@ interface nsIObjectLoadingContent : nsIS
                                 in boolean submittedCrashReport);
 
   /**
    * This method will play a plugin that has been stopped by the
    * click-to-play plugins feature.
    */
   void playPlugin();
 
+  /**
+   * This attribute will return true if the plugin has been activated
+   * and false if the plugin is still in the click-to-play state.
+   */
+  readonly attribute boolean activated;
+
   [noscript] void stopPluginInstance();
 
   [noscript] void syncStartPluginInstance();
   [noscript] void asyncStartPluginInstance();
 
   /**
    * The URL of the data/src loaded in the object. This may be null (i.e.
    * an <embed> with no src).
--- a/content/base/public/nsIXMLHttpRequest.idl
+++ b/content/base/public/nsIXMLHttpRequest.idl
@@ -156,29 +156,30 @@ interface nsIXMLHttpRequest : nsISupport
    * NULL if the request is unsuccessful or
    * has not yet been sent.
    */
   [implicit_jscontext] readonly attribute jsval /* any */ response;
 
   /**
    * The status of the response to the request for HTTP requests.
    */
+  // XXX spec says unsigned short
   readonly attribute unsigned long status;
 
   /**
    * The string representing the status of the response for
    * HTTP requests.
    */
-  readonly attribute AUTF8String statusText;
+  readonly attribute DOMString statusText;
 
   /**
    * If the request has been sent already, this method will
    * abort the request.
    */
-  void   abort();
+  [binaryname(SlowAbort)] void abort();
 
   /**
    * Returns all of the response headers as a string for HTTP
    * requests.
    *
    * Note that this will return all the headers from the *current*
    * part of a multipart request, not from the original channel.
    *
@@ -307,17 +308,17 @@ interface nsIXMLHttpRequest : nsISupport
    * Override the mime type returned by the server (if any). This may
    * be used, for example, to force a stream to be treated and parsed
    * as text/xml, even if the server does not report it as such. This
    * must be done before the <code>send</code> method is invoked.
    *
    * @param mimetype The type used to override that returned by the server
    *                 (if any).
    */
-  void   overrideMimeType(in AUTF8String mimetype);
+  [binaryname(SlowOverrideMimeType)] void overrideMimeType(in DOMString mimetype);
 
   /**
    * Set to true if the response is expected to be a stream of
    * possibly multiple (XML) documents. If set to true, the content
    * type of the initial response must be multipart/x-mixed-replace or
    * an error will be triggerd. All requests must be asynchronous.
    *
    * This enables server push. For each XML document that's written to
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -211,16 +211,18 @@ static NS_DEFINE_CID(kXTFServiceCID, NS_
 
 #include "nsWrapperCacheInlines.h"
 #include "nsIDOMDocumentType.h"
 #include "nsIDOMWindowUtils.h"
 #include "nsCharSeparatedTokenizer.h"
 
 extern "C" int MOZ_XMLTranslateEntity(const char* ptr, const char* end,
                                       const char** next, PRUnichar* result);
+extern "C" int MOZ_XMLCheckQName(const char* ptr, const char* end,
+                                 int ns_aware, const char** colon);
 
 using namespace mozilla::dom;
 using namespace mozilla::layers;
 using namespace mozilla::widget;
 using namespace mozilla;
 
 const char kLoadAsData[] = "loadAsData";
 
@@ -256,18 +258,16 @@ nsDataHashtable<nsISupportsHashKey, Even
 nsDataHashtable<nsStringHashKey, EventNameMapping>* nsContentUtils::sStringEventTable = nsnull;
 nsCOMArray<nsIAtom>* nsContentUtils::sUserDefinedEvents = nsnull;
 nsIStringBundleService *nsContentUtils::sStringBundleService;
 nsIStringBundle *nsContentUtils::sStringBundles[PropertiesFile_COUNT];
 nsIContentPolicy *nsContentUtils::sContentPolicyService;
 bool nsContentUtils::sTriedToGetContentPolicy = false;
 nsILineBreaker *nsContentUtils::sLineBreaker;
 nsIWordBreaker *nsContentUtils::sWordBreaker;
-nsIScriptRuntime *nsContentUtils::sScriptRuntimes[NS_STID_ARRAY_UBOUND];
-PRInt32 nsContentUtils::sScriptRootCount[NS_STID_ARRAY_UBOUND];
 PRUint32 nsContentUtils::sJSGCThingRootCount;
 #ifdef IBMBIDI
 nsIBidiKeyboard *nsContentUtils::sBidiKeyboard = nsnull;
 #endif
 PRUint32 nsContentUtils::sScriptBlockerCount = 0;
 #ifdef DEBUG
 PRUint32 nsContentUtils::sDOMNodeRemovedSuppressCount = 0;
 #endif
@@ -480,17 +480,17 @@ nsContentUtils::GetModifierSeparatorText
 
 void
 nsContentUtils::InitializeModifierStrings()
 {
   //load the display strings for the keyboard accelerators
   nsCOMPtr<nsIStringBundleService> bundleService =
     mozilla::services::GetStringBundleService();
   nsCOMPtr<nsIStringBundle> bundle;
-  nsresult rv = NS_OK;
+  DebugOnly<nsresult> rv = NS_OK;
   if (bundleService) {
     rv = bundleService->CreateBundle( "chrome://global-platform/locale/platformKeys.properties",
                                       getter_AddRefs(bundle));
   }
   
   NS_ASSERTION(NS_SUCCEEDED(rv) && bundle, "chrome://global/locale/platformKeys.properties could not be loaded");
   nsXPIDLString shiftModifier;
   nsXPIDLString metaModifier;
@@ -2381,37 +2381,51 @@ nsContentUtils::BelongsInForm(nsIContent
   }
 
   return false;
 }
 
 // static
 nsresult
 nsContentUtils::CheckQName(const nsAString& aQualifiedName,
-                           bool aNamespaceAware)
-{
-  nsIParserService *parserService = GetParserService();
-  NS_ENSURE_TRUE(parserService, NS_ERROR_FAILURE);
-
-  const PRUnichar *colon;
-  return parserService->CheckQName(PromiseFlatString(aQualifiedName),
-                                   aNamespaceAware, &colon);
+                           bool aNamespaceAware,
+                           const PRUnichar** aColon)
+{
+  const char* colon = nsnull;
+  const PRUnichar* begin = aQualifiedName.BeginReading();
+  const PRUnichar* end = aQualifiedName.EndReading();
+  
+  int result = MOZ_XMLCheckQName(reinterpret_cast<const char*>(begin),
+                                 reinterpret_cast<const char*>(end),
+                                 aNamespaceAware, &colon);
+
+  if (!result) {
+    if (aColon) {
+      *aColon = reinterpret_cast<const PRUnichar*>(colon);
+    }
+
+    return NS_OK;
+  }
+
+  // MOZ_EXPAT_EMPTY_QNAME || MOZ_EXPAT_INVALID_CHARACTER
+  if (result == (1 << 0) || result == (1 << 1)) {
+    return NS_ERROR_DOM_INVALID_CHARACTER_ERR;
+  }
+
+  return NS_ERROR_DOM_NAMESPACE_ERR;
 }
 
 //static
 nsresult
 nsContentUtils::SplitQName(const nsIContent* aNamespaceResolver,
                            const nsAFlatString& aQName,
                            PRInt32 *aNamespace, nsIAtom **aLocalName)
 {
-  nsIParserService* parserService = GetParserService();
-  NS_ENSURE_TRUE(parserService, NS_ERROR_FAILURE);
-
   const PRUnichar* colon;
-  nsresult rv = parserService->CheckQName(aQName, true, &colon);
+  nsresult rv = nsContentUtils::CheckQName(aQName, true, &colon);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (colon) {
     const PRUnichar* end;
     aQName.EndReading(end);
     nsAutoString nameSpace;
     rv = aNamespaceResolver->LookupNamespaceURIInternal(Substring(aQName.get(),
                                                                   colon),
@@ -2435,22 +2449,19 @@ nsContentUtils::SplitQName(const nsICont
 // static
 nsresult
 nsContentUtils::GetNodeInfoFromQName(const nsAString& aNamespaceURI,
                                      const nsAString& aQualifiedName,
                                      nsNodeInfoManager* aNodeInfoManager,
                                      PRUint16 aNodeType,
                                      nsINodeInfo** aNodeInfo)
 {
-  nsIParserService* parserService = GetParserService();
-  NS_ENSURE_TRUE(parserService, NS_ERROR_FAILURE);
-
   const nsAFlatString& qName = PromiseFlatString(aQualifiedName);
   const PRUnichar* colon;
-  nsresult rv = parserService->CheckQName(qName, true, &colon);
+  nsresult rv = nsContentUtils::CheckQName(qName, true, &colon);
   NS_ENSURE_SUCCESS(rv, rv);
 
   PRInt32 nsID;
   sNameSpaceManager->RegisterNameSpace(aNamespaceURI, nsID);
   if (colon) {
     const PRUnichar* end;
     qName.EndReading(end);
 
@@ -4313,79 +4324,16 @@ void
 nsContentUtils::DestroyAnonymousContent(nsCOMPtr<nsIContent>* aContent)
 {
   if (*aContent) {
     AddScriptRunner(new AnonymousContentDestroyer(aContent));
   }
 }
 
 /* static */
-nsIDOMScriptObjectFactory*
-nsContentUtils::GetDOMScriptObjectFactory()
-{
-  if (!sDOMScriptObjectFactory) {
-    static NS_DEFINE_CID(kDOMScriptObjectFactoryCID,
-                         NS_DOM_SCRIPT_OBJECT_FACTORY_CID);
-
-    CallGetService(kDOMScriptObjectFactoryCID, &sDOMScriptObjectFactory);
-  }
-
-  return sDOMScriptObjectFactory;
-}
-
-/* static */
-nsresult
-nsContentUtils::HoldScriptObject(PRUint32 aLangID, void *aObject)
-{
-  NS_ASSERTION(aObject, "unexpected null object");
-  NS_ASSERTION(aLangID != nsIProgrammingLanguage::JAVASCRIPT,
-               "Should use HoldJSObjects.");
-  nsresult rv;
-
-  PRUint32 langIndex = NS_STID_INDEX(aLangID);
-  nsIScriptRuntime *runtime = sScriptRuntimes[langIndex];
-  if (!runtime) {
-    nsIDOMScriptObjectFactory *factory = GetDOMScriptObjectFactory();
-    NS_ENSURE_TRUE(factory, NS_ERROR_FAILURE);
-
-    rv = factory->GetScriptRuntimeByID(aLangID, &runtime);
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    // This makes sScriptRuntimes hold a strong ref.
-    sScriptRuntimes[langIndex] = runtime;
-  }
-
-  rv = runtime->HoldScriptObject(aObject);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  ++sScriptRootCount[langIndex];
-  NS_LOG_ADDREF(sScriptRuntimes[langIndex], sScriptRootCount[langIndex],
-                "HoldScriptObject", sizeof(void*));
-
-  return NS_OK;
-}
-
-/* static */
-void
-nsContentUtils::DropScriptObject(PRUint32 aLangID, void *aObject,
-                                 void *aClosure)
-{
-  NS_ASSERTION(aObject, "unexpected null object");
-  NS_ASSERTION(aLangID != nsIProgrammingLanguage::JAVASCRIPT,
-               "Should use DropJSObjects.");
-  PRUint32 langIndex = NS_STID_INDEX(aLangID);
-  NS_LOG_RELEASE(sScriptRuntimes[langIndex], sScriptRootCount[langIndex] - 1,
-                 "HoldScriptObject");
-  sScriptRuntimes[langIndex]->DropScriptObject(aObject);
-  if (--sScriptRootCount[langIndex] == 0) {
-    NS_RELEASE(sScriptRuntimes[langIndex]);
-  }
-}
-
-/* static */
 nsresult
 nsContentUtils::HoldJSObjects(void* aScriptObjectHolder,
                               nsScriptObjectTracer* aTracer)
 {
   NS_ENSURE_TRUE(sXPConnect, NS_ERROR_UNEXPECTED);
 
   nsresult rv = sXPConnect->AddJSHolder(aScriptObjectHolder, aTracer);
   NS_ENSURE_SUCCESS(rv, rv);
--- a/content/base/src/nsDOMAttribute.cpp
+++ b/content/base/src/nsDOMAttribute.cpp
@@ -692,29 +692,28 @@ nsDOMAttribute::InsertChildAt(nsIContent
 }
 
 nsresult
 nsDOMAttribute::AppendChildTo(nsIContent* aKid, bool aNotify)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
-nsresult
+void
 nsDOMAttribute::RemoveChildAt(PRUint32 aIndex, bool aNotify)
 {
   if (aIndex != 0 || !mChild) {
-    return NS_OK;
+    return;
   }
 
   doRemoveChild(aNotify);
 
   nsString nullString;
   SetDOMStringToNull(nullString);
   SetValue(nullString);
-  return NS_OK;
 }
 
 nsresult
 nsDOMAttribute::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
 {
   aVisitor.mCanHandle = true;
   return NS_OK;
 }
--- a/content/base/src/nsDOMAttribute.h
+++ b/content/base/src/nsDOMAttribute.h
@@ -85,17 +85,17 @@ public:
   virtual bool IsNodeOfType(PRUint32 aFlags) const;
   virtual PRUint32 GetChildCount() const;
   virtual nsIContent *GetChildAt(PRUint32 aIndex) const;
   virtual nsIContent * const * GetChildArray(PRUint32* aChildCount) const;
   virtual PRInt32 IndexOf(nsINode* aPossibleChild) const;
   virtual nsresult InsertChildAt(nsIContent* aKid, PRUint32 aIndex,
                                  bool aNotify);
   virtual nsresult AppendChildTo(nsIContent* aKid, bool aNotify);
-  virtual nsresult RemoveChildAt(PRUint32 aIndex, bool aNotify);
+  virtual void RemoveChildAt(PRUint32 aIndex, bool aNotify);
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
   virtual already_AddRefed<nsIURI> GetBaseURI() const;
 
   static void Initialize();
   static void Shutdown();
 
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsDOMAttribute,
                                                          nsIAttribute)
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -1415,22 +1415,19 @@ nsDOMImplementation::CreateDocument(cons
                                     const nsAString& aQualifiedName,
                                     nsIDOMDocumentType* aDoctype,
                                     nsIDOMDocument** aReturn)
 {
   *aReturn = nsnull;
 
   nsresult rv;
   if (!aQualifiedName.IsEmpty()) {
-    nsIParserService *parserService = nsContentUtils::GetParserService();
-    NS_ENSURE_TRUE(parserService, NS_ERROR_FAILURE);
-
     const nsAFlatString& qName = PromiseFlatString(aQualifiedName);
     const PRUnichar *colon;
-    rv = parserService->CheckQName(qName, true, &colon);
+    rv = nsContentUtils::CheckQName(qName, true, &colon);
     NS_ENSURE_SUCCESS(rv, rv);
 
     if (colon &&
         (DOMStringIsNull(aNamespaceURI) ||
          (Substring(qName.get(), colon).EqualsLiteral("xml") &&
           !aNamespaceURI.EqualsLiteral("http://www.w3.org/XML/1998/namespace")))) {
       return NS_ERROR_DOM_NAMESPACE_ERR;
     }
@@ -1669,16 +1666,18 @@ nsDocument::~nsDocument()
   for (PRUint32 i = 0; i < mFileDataUris.Length(); ++i) {
     nsBlobProtocolHandler::RemoveFileDataEntry(mFileDataUris[i]);
   }
 
   // We don't want to leave residual locks on images. Make sure we're in an
   // unlocked state, and then clear the table.
   SetImageLockingState(false);
   mImageTracker.Clear();
+
+  mPlugins.Clear();
 }
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsDocument)
 
 NS_INTERFACE_TABLE_HEAD(nsDocument)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_DOCUMENT_INTERFACE_TABLE_BEGIN(nsDocument)
     NS_INTERFACE_TABLE_ENTRY(nsDocument, nsIDocument)
@@ -2019,17 +2018,18 @@ nsDocument::Init()
   NS_ABORT_IF_FALSE(mNodeInfo->NodeType() == nsIDOMNode::DOCUMENT_NODE,
                     "Bad NodeType in aNodeInfo");
 
   NS_ASSERTION(OwnerDoc() == this, "Our nodeinfo is busted!");
 
   mScriptLoader = new nsScriptLoader(this);
   NS_ENSURE_TRUE(mScriptLoader, NS_ERROR_OUT_OF_MEMORY);
 
-  if (!mImageTracker.Init()) {
+  if (!mImageTracker.Init() ||
+      !mPlugins.Init()) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   return NS_OK;
 }
 
 void 
 nsIDocument::DeleteAllProperties()
@@ -3509,33 +3509,31 @@ nsDocument::AppendChildTo(nsIContent* aK
   // Make sure to _not_ call the subclass InsertChildAt here.  If
   // subclasses wanted to hook into this stuff, they would have
   // overridden AppendChildTo.
   // XXXbz maybe this should just be a non-virtual method on nsINode?
   // Feels that way to me...
   return nsDocument::InsertChildAt(aKid, GetChildCount(), aNotify);
 }
 
-nsresult
+void
 nsDocument::RemoveChildAt(PRUint32 aIndex, bool aNotify)
 {
   nsCOMPtr<nsIContent> oldKid = GetChildAt(aIndex);
   if (!oldKid) {
-    return NS_OK;
+    return;
   }
 
   if (oldKid->IsElement()) {
     // Destroy the link map up front before we mess with the child list.
     DestroyElementMaps();
   }
 
-  nsresult rv =
-    doRemoveChildAt(aIndex, aNotify, oldKid, mChildren);
+  doRemoveChildAt(aIndex, aNotify, oldKid, mChildren);
   mCachedRootElement = nsnull;
-  return rv;
 }
 
 PRInt32
 nsDocument::GetNumberOfStyleSheets() const
 {
   return mStyleSheets.Count();
 }
 
@@ -5981,17 +5979,16 @@ BlastFunc(nsAttrHashKey::KeyType aKey, n
                "non-nsIAttribute somehow made it into the hashmap?!");
 
   return PL_DHASH_STOP;
 }
 
 static void
 BlastSubtreeToPieces(nsINode *aNode)
 {
-  PRUint32 i, count;
   if (aNode->IsElement()) {
     nsGenericElement *element = static_cast<nsGenericElement*>(aNode);
     const nsDOMAttributeMap *map = element->GetAttributeMap();
     if (map) {
       nsCOMPtr<nsIAttribute> attr;
       while (map->Enumerate(BlastFunc, &attr) > 0) {
         BlastSubtreeToPieces(attr);
 
@@ -6003,26 +6000,20 @@ BlastSubtreeToPieces(nsINode *aNode)
                              false);
 
         // XXX Should we abort here?
         NS_ASSERTION(NS_SUCCEEDED(rv), "Uhoh, UnsetAttr shouldn't fail!");
       }
     }
   }
 
-  count = aNode->GetChildCount();
-  for (i = 0; i < count; ++i) {
+  PRUint32 count = aNode->GetChildCount();
+  for (PRUint32 i = 0; i < count; ++i) {
     BlastSubtreeToPieces(aNode->GetFirstChild());
-#ifdef DEBUG
-    nsresult rv =
-#endif
-      aNode->RemoveChildAt(0, false);
-
-    // XXX Should we abort here?
-    NS_ASSERTION(NS_SUCCEEDED(rv), "Uhoh, RemoveChildAt shouldn't fail!");
+    aNode->RemoveChildAt(0, false);
   }
 }
 
 
 class nsUserDataCaller : public nsRunnable
 {
 public:
   nsUserDataCaller(nsCOMArray<nsINode>& aNodesWithProperties,
@@ -6116,18 +6107,17 @@ nsDocument::AdoptNode(nsIDOMNode *aAdopt
             return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
           }
         }
       } while ((doc = doc->GetParentDocument()));
 
       // Remove from parent.
       nsCOMPtr<nsINode> parent = adoptedNode->GetNodeParent();
       if (parent) {
-        rv = parent->RemoveChildAt(parent->IndexOf(adoptedNode), true);
-        NS_ENSURE_SUCCESS(rv, rv);
+        parent->RemoveChildAt(parent->IndexOf(adoptedNode), true);
       }
 
       break;
     }
     case nsIDOMNode::ENTITY_REFERENCE_NODE:
     {
       return NS_ERROR_NOT_IMPLEMENTED;
     }
@@ -8357,16 +8347,61 @@ nsDocument::RemoveImage(imgIRequest* aIm
   // Request that the image be discarded if nobody else holds a lock on it.
   // Do this even if !mLockingImages, because even if we didn't just unlock
   // this image, it might still be a candidate for discarding.
   aImage->RequestDiscard();
 
   return rv;
 }
 
+nsresult
+nsDocument::AddPlugin(nsIObjectLoadingContent* aPlugin)
+{
+  MOZ_ASSERT(aPlugin);
+  if (!mPlugins.PutEntry(aPlugin)) {
+    return NS_ERROR_OUT_OF_MEMORY;
+  }
+  return NS_OK;
+}
+
+void
+nsDocument::RemovePlugin(nsIObjectLoadingContent* aPlugin)
+{
+  MOZ_ASSERT(aPlugin);
+  mPlugins.RemoveEntry(aPlugin);
+}
+
+static bool
+AllSubDocumentPluginEnum(nsIDocument* aDocument, void* userArg)
+{
+  nsTArray<nsIObjectLoadingContent*>* plugins =
+    reinterpret_cast< nsTArray<nsIObjectLoadingContent*>* >(userArg);
+  MOZ_ASSERT(plugins);
+  aDocument->GetPlugins(*plugins);
+  return true;
+}
+
+static PLDHashOperator
+AllPluginEnum(nsPtrHashKey<nsIObjectLoadingContent>* aPlugin, void* userArg)
+{
+  nsTArray<nsIObjectLoadingContent*>* allPlugins =
+    reinterpret_cast< nsTArray<nsIObjectLoadingContent*>* >(userArg);
+  MOZ_ASSERT(allPlugins);
+  allPlugins->AppendElement(aPlugin->GetKey());
+  return PL_DHASH_NEXT;
+}
+
+void
+nsDocument::GetPlugins(nsTArray<nsIObjectLoadingContent*>& aPlugins)
+{
+  aPlugins.SetCapacity(aPlugins.Length() + mPlugins.Count());
+  mPlugins.EnumerateEntries(AllPluginEnum, &aPlugins);
+  EnumerateSubDocuments(AllSubDocumentPluginEnum, &aPlugins);
+}
+
 PLDHashOperator LockEnumerator(imgIRequest* aKey,
                                PRUint32 aData,
                                void*    userArg)
 {
   aKey->LockImage();
   aKey->RequestDecode();
   return PL_DHASH_NEXT;
 }
--- a/content/base/src/nsDocument.h
+++ b/content/base/src/nsDocument.h
@@ -719,17 +719,17 @@ public:
   virtual void NodeName(nsAString& aNodeName);
   virtual nsIContent *GetChildAt(PRUint32 aIndex) const;
   virtual nsIContent * const * GetChildArray(PRUint32* aChildCount) const;
   virtual PRInt32 IndexOf(nsINode* aPossibleChild) const;
   virtual PRUint32 GetChildCount() const;
   virtual nsresult InsertChildAt(nsIContent* aKid, PRUint32 aIndex,
                                  bool aNotify);
   virtual nsresult AppendChildTo(nsIContent* aKid, bool aNotify);
-  virtual nsresult RemoveChildAt(PRUint32 aIndex, bool aNotify);
+  virtual void RemoveChildAt(PRUint32 aIndex, bool aNotify);
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const
   {
     return NS_ERROR_NOT_IMPLEMENTED;
   }
 
   // nsIRadioGroupContainer
   NS_IMETHOD WalkRadioGroup(const nsAString& aName,
                             nsIRadioVisitor* aVisitor,
@@ -930,16 +930,26 @@ public:
   virtual const nsSmallVoidArray* GetAllElementsForId(const nsAString& aElementId) const;
 
   virtual Element *LookupImageElement(const nsAString& aElementId);
 
   virtual NS_HIDDEN_(nsresult) AddImage(imgIRequest* aImage);
   virtual NS_HIDDEN_(nsresult) RemoveImage(imgIRequest* aImage);
   virtual NS_HIDDEN_(nsresult) SetImageLockingState(bool aLocked);
 
+  // AddPlugin adds a plugin-related element to mPlugins when the element is
+  // added to the tree.
+  virtual nsresult AddPlugin(nsIObjectLoadingContent* aPlugin);
+  // RemovePlugin removes a plugin-related element to mPlugins when the
+  // element is removed from the tree.
+  virtual void RemovePlugin(nsIObjectLoadingContent* aPlugin);
+  // GetPlugins returns the plugin-related elements from
+  // the frame and any subframes.
+  virtual void GetPlugins(nsTArray<nsIObjectLoadingContent*>& aPlugins);
+
   virtual nsresult GetStateObject(nsIVariant** aResult);
 
   virtual nsDOMNavigationTiming* GetNavigationTiming() const;
   virtual nsresult SetNavigationTiming(nsDOMNavigationTiming* aTiming);
 
   virtual Element* FindImageMap(const nsAString& aNormalizedMapName);
 
   virtual void NotifyAudioAvailableListener();
@@ -1299,16 +1309,19 @@ private:
 
   nsCString mScrollToRef;
   PRUint8 mScrolledToRefAlready : 1;
   PRUint8 mChangeScrollPosWhenScrollingToRef : 1;
 
   // Tracking for images in the document.
   nsDataHashtable< nsPtrHashKey<imgIRequest>, PRUint32> mImageTracker;
 
+  // Tracking for plugins in the document.
+  nsTHashtable< nsPtrHashKey<nsIObjectLoadingContent> > mPlugins;
+
   VisibilityState mVisibilityState;
 
 #ifdef DEBUG
 protected:
   bool mWillReparent;
 #endif
 };
 
--- a/content/base/src/nsDocumentEncoder.cpp
+++ b/content/base/src/nsDocumentEncoder.cpp
@@ -737,42 +737,16 @@ static nsresult GetNextNode(nsIDOMNode* 
 }
 #endif
 
 static bool IsTextNode(nsINode *aNode)
 {
   return aNode && aNode->IsNodeOfType(nsINode::eTEXT);
 }
 
-static nsresult GetLengthOfDOMNode(nsIDOMNode *aNode, PRUint32 &aCount) 
-{
-  aCount = 0;
-  if (!aNode) { return NS_ERROR_NULL_POINTER; }
-  nsresult result=NS_OK;
-  nsCOMPtr<nsIDOMCharacterData>nodeAsChar;
-  nodeAsChar = do_QueryInterface(aNode);
-  if (nodeAsChar) {
-    nodeAsChar->GetLength(&aCount);
-  }
-  else
-  {
-    bool hasChildNodes;
-    aNode->HasChildNodes(&hasChildNodes);
-    if (true==hasChildNodes)
-    {
-      nsCOMPtr<nsIDOMNodeList>nodeList;
-      result = aNode->GetChildNodes(getter_AddRefs(nodeList));
-      if (NS_SUCCEEDED(result) && nodeList) {
-        nodeList->GetLength(&aCount);
-      }
-    }
-  }
-  return result;
-}
-
 nsresult
 nsDocumentEncoder::SerializeRangeNodes(nsRange* aRange,
                                        nsINode* aNode,
                                        nsAString& aString,
                                        PRInt32 aDepth)
 {
   nsCOMPtr<nsIContent> content = do_QueryInterface(aNode);
   NS_ENSURE_TRUE(content, NS_ERROR_FAILURE);
@@ -1694,23 +1668,22 @@ nsHTMLCopyEncoder::GetPromotedPoint(Endp
   
   if (aWhere == kEnd)
   {
     // some special casing for text nodes
     nsCOMPtr<nsINode> n = do_QueryInterface(aNode);
     if (IsTextNode(n))
     {
       // if not at end of text node, we are done
-      PRUint32 len;
-      GetLengthOfDOMNode(aNode, len);
+      PRUint32 len = n->Length();
       if (offset < (PRInt32)len)
       {
         // unless everything after us in just whitespace.  NOTE: we need a more
         // general solution that truly detects all cases of non-significant
-        // whitesace with no false alarms.
+        // whitespace with no false alarms.
         nsCOMPtr<nsIDOMCharacterData> nodeAsText = do_QueryInterface(aNode);
         nsAutoString text;
         nodeAsText->SubstringData(offset, len-offset, text);
         text.CompressWhitespace();
         if (!text.IsEmpty())
           return NS_OK;
         bResetPromotion = true;
       }
@@ -1886,28 +1859,30 @@ nsHTMLCopyEncoder::IsFirstNode(nsIDOMNod
 }
 
 
 bool
 nsHTMLCopyEncoder::IsLastNode(nsIDOMNode *aNode)
 {
   nsCOMPtr<nsIDOMNode> parent;
   PRInt32 offset,j;
-  PRUint32 numChildren;
   nsresult rv = GetNodeLocation(aNode, address_of(parent), &offset);
   if (NS_FAILED(rv)) 
   {
     NS_NOTREACHED("failure in IsLastNode");
     return false;
   }
-  GetLengthOfDOMNode(parent, numChildren); 
+  nsCOMPtr<nsINode> parentNode = do_QueryInterface(parent);
+  if (!parentNode) {
+    return true;
+  }
+
+  PRUint32 numChildren = parentNode->Length();
   if (offset+1 == (PRInt32)numChildren) // easy case, we are last dom child
     return true;
-  if (!parent)
-    return true;
   // need to check if any nodes after us are really visible.
   // Mike wrote something for me along these lines in nsSelectionController,
   // but I don't think it's ready for use yet - revisit.
   // HACK: for now, simply consider all whitespace text nodes to be 
   // invisible formatting nodes.
   j = (PRInt32)numChildren-1;
   nsCOMPtr<nsIDOMNodeList>childList;
   nsCOMPtr<nsIDOMNode> child;
--- a/content/base/src/nsEventSource.cpp
+++ b/content/base/src/nsEventSource.cpp
@@ -462,17 +462,17 @@ nsEventSource::Observe(nsISupports* aSub
     return NS_OK;
   }
 
   nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aSubject);
   if (!GetOwner() || window != GetOwner()) {
     return NS_OK;
   }
 
-  nsresult rv;
+  DebugOnly<nsresult> rv;
   if (strcmp(aTopic, DOM_WINDOW_FROZEN_TOPIC) == 0) {
     rv = Freeze();
     NS_ASSERTION(rv, "Freeze() failed");
   } else if (strcmp(aTopic, DOM_WINDOW_THAWED_TOPIC) == 0) {
     rv = Thaw();
     NS_ASSERTION(rv, "Thaw() failed");
   } else if (strcmp(aTopic, DOM_WINDOW_DESTROYED_TOPIC) == 0) {
     Close();
--- a/content/base/src/nsFrameMessageManager.cpp
+++ b/content/base/src/nsFrameMessageManager.cpp
@@ -1105,14 +1105,12 @@ NS_NewChildProcessMessageManager(nsISync
   return CallQueryInterface(mm, aResult);
 }
 
 bool
 nsFrameMessageManager::MarkForCC()
 {
   PRUint32 len = mListeners.Length();
   for (PRUint32 i = 0; i < len; ++i) {
-    nsCOMPtr<nsIXPConnectWrappedJS> wjs =
-      do_QueryInterface(mListeners[i].mListener);
-    xpc_UnmarkGrayObject(wjs);
+    xpc_TryUnmarkWrappedGrayObject(mListeners[i].mListener);
   }
   return true;
 }
--- a/content/base/src/nsGenericDOMDataNode.cpp
+++ b/content/base/src/nsGenericDOMDataNode.cpp
@@ -675,20 +675,19 @@ nsGenericDOMDataNode::IndexOf(nsINode* a
 
 nsresult
 nsGenericDOMDataNode::InsertChildAt(nsIContent* aKid, PRUint32 aIndex,
                                     bool aNotify)
 {
   return NS_OK;
 }
 
-nsresult
+void
 nsGenericDOMDataNode::RemoveChildAt(PRUint32 aIndex, bool aNotify)
 {
-  return NS_OK;
 }
 
 nsIContent *
 nsGenericDOMDataNode::GetBindingParent() const
 {
   nsDataSlots *slots = GetExistingDataSlots();
   return slots ? slots->mBindingParent : nsnull;
 }
@@ -869,17 +868,17 @@ nsGenericDOMDataNode::GetWholeText(nsASt
 
 const nsTextFragment *
 nsGenericDOMDataNode::GetText()
 {
   return &mText;
 }
 
 PRUint32
-nsGenericDOMDataNode::TextLength()
+nsGenericDOMDataNode::TextLength() const
 {
   return mText.GetLength();
 }
 
 nsresult
 nsGenericDOMDataNode::SetText(const PRUnichar* aBuffer,
                               PRUint32 aLength,
                               bool aNotify)
--- a/content/base/src/nsGenericDOMDataNode.h
+++ b/content/base/src/nsGenericDOMDataNode.h
@@ -165,17 +165,17 @@ public:
 
   // nsINode methods
   virtual PRUint32 GetChildCount() const;
   virtual nsIContent *GetChildAt(PRUint32 aIndex) const;
   virtual nsIContent * const * GetChildArray(PRUint32* aChildCount) const;
   virtual PRInt32 IndexOf(nsINode* aPossibleChild) const;
   virtual nsresult InsertChildAt(nsIContent* aKid, PRUint32 aIndex,
                                  bool aNotify);
-  virtual nsresult RemoveChildAt(PRUint32 aIndex, bool aNotify);
+  virtual void RemoveChildAt(PRUint32 aIndex, bool aNotify);
   NS_IMETHOD GetTextContent(nsAString &aTextContent)
   {
     nsresult rv = GetNodeValue(aTextContent);
     NS_ASSERTION(NS_SUCCEEDED(rv), "GetNodeValue() failed?");
     return rv;
   }
   NS_IMETHOD SetTextContent(const nsAString& aTextContent)
   {
@@ -206,17 +206,17 @@ public:
   virtual nsresult UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
                              bool aNotify);
   virtual bool GetAttr(PRInt32 aNameSpaceID, nsIAtom *aAttribute,
                          nsAString& aResult) const;
   virtual bool HasAttr(PRInt32 aNameSpaceID, nsIAtom *aAttribute) const;
   virtual const nsAttrName* GetAttrNameAt(PRUint32 aIndex) const;
   virtual PRUint32 GetAttrCount() const;
   virtual const nsTextFragment *GetText();
-  virtual PRUint32 TextLength();
+  virtual PRUint32 TextLength() const;
   virtual nsresult SetText(const PRUnichar* aBuffer, PRUint32 aLength,
                            bool aNotify);
   // Need to implement this here too to avoid hiding.
   nsresult SetText(const nsAString& aStr, bool aNotify)
   {
     return SetText(aStr.BeginReading(), aStr.Length(), aNotify);
   }
   virtual nsresult AppendText(const PRUnichar* aBuffer, PRUint32 aLength,
--- a/content/base/src/nsGenericElement.cpp
+++ b/content/base/src/nsGenericElement.cpp
@@ -530,17 +530,18 @@ nsINode::RemoveChild(nsINode *aOldChild)
   }
 
   PRInt32 index = IndexOf(aOldChild);
   if (index == -1) {
     // aOldChild isn't one of our children.
     return NS_ERROR_DOM_NOT_FOUND_ERR;
   }
 
-  return RemoveChildAt(index, true);
+  RemoveChildAt(index, true);
+  return NS_OK;
 }
 
 nsresult
 nsINode::ReplaceOrInsertBefore(bool aReplace, nsIDOMNode* aNewChild,
                                nsIDOMNode* aRefChild, nsIDOMNode** aReturn)
 {
   nsCOMPtr<nsINode> newChild = do_QueryInterface(aNewChild);
 
@@ -3843,30 +3844,28 @@ nsINode::doInsertChildAt(nsIContent* aKi
       mozAutoSubtreeModified subtree(OwnerDoc(), this);
       (new nsAsyncDOMEvent(aKid, mutation))->RunDOMEventWhenSafe();
     }
   }
 
   return NS_OK;
 }
 
-nsresult
+void
 nsGenericElement::RemoveChildAt(PRUint32 aIndex, bool aNotify)
 {
   nsCOMPtr<nsIContent> oldKid = mAttrsAndChildren.GetSafeChildAt(aIndex);
   NS_ASSERTION(oldKid == GetChildAt(aIndex), "Unexpected child in RemoveChildAt");
 
   if (oldKid) {
-    return doRemoveChildAt(aIndex, aNotify, oldKid, mAttrsAndChildren);
-  }
-
-  return NS_OK;
-}
-
-nsresult
+    doRemoveChildAt(aIndex, aNotify, oldKid, mAttrsAndChildren);
+  }
+}
+
+void
 nsINode::doRemoveChildAt(PRUint32 aIndex, bool aNotify,
                          nsIContent* aKid, nsAttrAndChildArray& aChildArray)
 {
   NS_PRECONDITION(aKid && aKid->GetNodeParent() == this &&
                   aKid == GetChildAt(aIndex) &&
                   IndexOf(aKid) == (PRInt32)aIndex, "Bogus aKid");
 
   nsMutationGuard::DidMutate();
@@ -3883,18 +3882,16 @@ nsINode::doRemoveChildAt(PRUint32 aIndex
 
   aChildArray.RemoveChildAt(aIndex);
 
   if (aNotify) {
     nsNodeUtils::ContentRemoved(this, aKid, aIndex, previousSibling);
   }
 
   aKid->UnbindFromTree();
-
-  return NS_OK;
 }
 
 NS_IMETHODIMP
 nsGenericElement::GetTextContent(nsAString &aTextContent)
 {
   nsContentUtils::GetNodeTextContent(this, true, aTextContent);
   return NS_OK;
 }
@@ -4268,22 +4265,19 @@ nsINode::ReplaceOrInsertBefore(bool aRep
     insPos = GetChildCount();
   }
 
   // Make sure that the inserted node is allowed as a child of its new parent.
   if (!IsAllowedAsChild(newContent, this, aReplace, aRefChild)) {
     return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
   }
 
-  nsresult res;
-
   // If we're replacing
   if (aReplace) {
-    res = RemoveChildAt(insPos, true);
-    NS_ENSURE_SUCCESS(res, res);
+    RemoveChildAt(insPos, true);
   }
 
   if (newContent->IsRootOfAnonymousSubtree()) {
     // This is anonymous content.  Don't allow its insertion
     // anywhere, since it might have UnbindFromTree calls coming
     // its way.
     return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
   }
@@ -4293,26 +4287,26 @@ nsINode::ReplaceOrInsertBefore(bool aRep
   if (oldParent) {
     PRInt32 removeIndex = oldParent->IndexOf(newContent);
     if (removeIndex < 0) {
       // newContent is anonymous.  We can't deal with this, so just bail
       NS_ERROR("How come our flags didn't catch this?");
       return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
     }
 
-    res = oldParent->RemoveChildAt(removeIndex, true);
-    NS_ENSURE_SUCCESS(res, res);
+    oldParent->RemoveChildAt(removeIndex, true);
 
     // Adjust insert index if the node we ripped out was a sibling
     // of the node we're inserting before
     if (oldParent == this && removeIndex < insPos) {
       --insPos;
     }
   }
 
+  nsresult res = NS_OK;
   // Move new child over to our document if needed. Do this after removing
   // it from its parent so that AdoptNode doesn't fire DOMNodeRemoved
   // DocumentType nodes are the only nodes that can have a null
   // ownerDocument according to the DOM spec, and we need to allow
   // inserting them w/o calling AdoptNode().
   if (!HasSameOwnerDoc(newContent)) {
     res = AdoptNodeIntoOwnerDoc(this, aNewChild);
     NS_ENSURE_SUCCESS(res, res);
@@ -4577,19 +4571,17 @@ nsGenericElement::MarkUserData(void* aOb
   PRUint32* gen = static_cast<PRUint32*>(aData);
   xpc_MarkInCCGeneration(static_cast<nsISupports*>(aChild), *gen);
 }
 
 void
 nsGenericElement::MarkUserDataHandler(void* aObject, nsIAtom* aKey,
                                       void* aChild, void* aData)
 {
-  nsCOMPtr<nsIXPConnectWrappedJS> wjs =
-    do_QueryInterface(static_cast<nsISupports*>(aChild));
-  xpc_UnmarkGrayObject(wjs);
+  xpc_TryUnmarkWrappedGrayObject(static_cast<nsISupports*>(aChild));
 }
 
 void
 nsGenericElement::MarkNodeChildren(nsINode* aNode)
 {
   JSObject* o = GetJSObjectChild(aNode);
   xpc_UnmarkGrayObject(o);
 
@@ -4987,16 +4979,17 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_
     }
 
     nsAutoString classes;
     const nsAttrValue* classAttrValue = tmp->GetClasses();
     if (classAttrValue) {
       classes.AppendLiteral(" class='");
       nsAutoString classString;
       classAttrValue->ToString(classString);
+      classString.ReplaceChar(PRUnichar('\n'), PRUnichar(' '));
       classes.Append(classString);
       classes.AppendLiteral("'");
     }
 
     const char* nsuri = nsid < ArrayLength(kNSURIs) ? kNSURIs[nsid] : "";
     PR_snprintf(name, sizeof(name), "nsGenericElement%s %s%s%s %s",
                 nsuri,
                 localName.get(),
@@ -5618,17 +5611,17 @@ nsGenericElement::GetAttrCount() const
 
 const nsTextFragment*
 nsGenericElement::GetText()
 {
   return nsnull;
 }
 
 PRUint32
-nsGenericElement::TextLength()
+nsGenericElement::TextLength() const
 {
   // We can remove this assertion if it turns out to be useful to be able
   // to depend on this returning 0
   NS_NOTREACHED("called nsGenericElement::TextLength");
 
   return 0;
 }
 
@@ -6413,16 +6406,35 @@ nsINode::Contains(const nsINode* aOther)
 nsresult
 nsINode::Contains(nsIDOMNode* aOther, bool* aReturn)
 {
   nsCOMPtr<nsINode> node = do_QueryInterface(aOther);
   *aReturn = Contains(node);
   return NS_OK;
 }
 
+PRUint32
+nsINode::Length() const
+{
+  switch (NodeType()) {
+  case nsIDOMNode::DOCUMENT_TYPE_NODE:
+    return 0;
+
+  case nsIDOMNode::TEXT_NODE:
+  case nsIDOMNode::CDATA_SECTION_NODE:
+  case nsIDOMNode::PROCESSING_INSTRUCTION_NODE:
+  case nsIDOMNode::COMMENT_NODE:
+    MOZ_ASSERT(IsNodeOfType(eCONTENT));
+    return static_cast<const nsIContent*>(this)->TextLength();
+
+  default:
+    return GetChildCount();
+  }
+}
+
 nsresult nsGenericElement::MozRequestFullScreen()
 {
   // Only grant full-screen requests if this is called from inside a trusted
   // event handler (i.e. inside an event handler for a user initiated event).
   // This stops the full-screen from being abused similar to the popups of old,
   // and it also makes it harder for bad guys' script to go full-screen and
   // spoof the browser chrome/window and phish logins etc.
   if (!nsContentUtils::IsRequestFullScreenAllowed()) {
--- a/content/base/src/nsGenericElement.h
+++ b/content/base/src/nsGenericElement.h
@@ -258,17 +258,17 @@ public:
 
   // nsINode interface methods
   virtual PRUint32 GetChildCount() const;
   virtual nsIContent *GetChildAt(PRUint32 aIndex) const;
   virtual nsIContent * const * GetChildArray(PRUint32* aChildCount) const;
   virtual PRInt32 IndexOf(nsINode* aPossibleChild) const;
   virtual nsresult InsertChildAt(nsIContent* aKid, PRUint32 aIndex,
                                  bool aNotify);
-  virtual nsresult RemoveChildAt(PRUint32 aIndex, bool aNotify);
+  virtual void RemoveChildAt(PRUint32 aIndex, bool aNotify);
   NS_IMETHOD GetTextContent(nsAString &aTextContent);
   NS_IMETHOD SetTextContent(const nsAString& aTextContent);
 
   // nsIContent interface methods
   virtual void UpdateEditableState(bool aNotify);
 
   virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
                               nsIContent* aBindingParent,
@@ -322,17 +322,17 @@ public:
                                   nsIAtom* aName,
                                   AttrValuesArray* aValues,
                                   nsCaseTreatment aCaseSensitive) const;
   virtual nsresult UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
                              bool aNotify);
   virtual const nsAttrName* GetAttrNameAt(PRUint32 aIndex) const;
   virtual PRUint32 GetAttrCount() const;
   virtual const nsTextFragment *GetText();
-  virtual PRUint32 TextLength();
+  virtual PRUint32 TextLength() const;
   virtual nsresult SetText(const PRUnichar* aBuffer, PRUint32 aLength,
                            bool aNotify);
   // Need to implement this here too to avoid hiding.
   nsresult SetText(const nsAString& aStr, bool aNotify)
   {
     return SetText(aStr.BeginReading(), aStr.Length(), aNotify);
   }
   virtual nsresult AppendText(const PRUnichar* aBuffer, PRUint32 aLength,
--- a/content/base/src/nsGkAtomList.h
+++ b/content/base/src/nsGkAtomList.h
@@ -1860,16 +1860,57 @@ GK_ATOM(lockedStyleStates, "lockedStyleS
 
 // Languages for lang-specific transforms
 GK_ATOM(Japanese, "ja")
 GK_ATOM(Chinese, "zh-CN")
 GK_ATOM(Taiwanese, "zh-TW")
 GK_ATOM(HongKongChinese, "zh-HK")
 GK_ATOM(Unicode, "x-unicode")
 
+// language codes specifically referenced in the gfx code
+GK_ATOM(ko, "ko")
+GK_ATOM(zh_cn, "zh-cn")
+GK_ATOM(zh_hk, "zh-hk")
+GK_ATOM(zh_tw, "zh-tw")
+
+// additional codes used in nsUnicodeRange.cpp
+GK_ATOM(x_cyrillic, "x-cyrillic")
+GK_ATOM(he, "he")
+GK_ATOM(ar, "ar")
+GK_ATOM(x_baltic, "x-baltic")
+GK_ATOM(x_devanagari, "x-devanagari")
+GK_ATOM(x_tamil, "x-tamil")
+GK_ATOM(x_armn, "x-armn")
+GK_ATOM(x_beng, "x-beng")
+GK_ATOM(x_cans, "x-cans")
+GK_ATOM(x_ethi, "x-ethi")
+GK_ATOM(x_geor, "x-geor")
+GK_ATOM(x_gujr, "x-gujr")
+GK_ATOM(x_guru, "x-guru")
+GK_ATOM(x_khmr, "x-khmr")
+GK_ATOM(x_knda, "x-knda")
+GK_ATOM(x_mlym, "x-mlym")
+GK_ATOM(x_orya, "x-orya")
+GK_ATOM(x_sinh, "x-sinh")
+GK_ATOM(x_telu, "x-telu")
+GK_ATOM(x_tibt, "x-tibt")
+
+// used in gfxGDIFontList.h
+GK_ATOM(ko_xxx, "ko-xxx")
+GK_ATOM(x_central_euro, "x-central-euro")
+GK_ATOM(x_symbol, "x-symbol")
+
+// referenced in all.js
+GK_ATOM(x_user_def, "x-user-def")
+
+// additional languages that use Turkish-style case transformation
+GK_ATOM(az, "az")
+GK_ATOM(ba, "ba")
+GK_ATOM(crh, "crh")
+
 // Names for editor transactions
 GK_ATOM(TypingTxnName, "Typing")
 GK_ATOM(IMETxnName, "IME")
 GK_ATOM(DeleteTxnName, "Deleting")
 
 // IPC stuff
 GK_ATOM(Remote, "remote")
 GK_ATOM(RemoteId, "_remote_id")
--- a/content/base/src/nsObjectLoadingContent.cpp
+++ b/content/base/src/nsObjectLoadingContent.cpp
@@ -110,16 +110,28 @@ static NS_DEFINE_CID(kAppShellCID, NS_AP
 static PRLogModuleInfo* gObjectLog = PR_NewLogModule("objlc");
 #endif
 
 #define LOG(args) PR_LOG(gObjectLog, PR_LOG_DEBUG, args)
 #define LOG_ENABLED() PR_LOG_TEST(gObjectLog, PR_LOG_DEBUG)
 
 #include "mozilla/Preferences.h"
 
+static bool gClickToPlayPlugins = false;
+
+static void
+InitPrefCache()
+{
+  static bool initializedPrefCache = false;
+  if (!initializedPrefCache) {
+    mozilla::Preferences::AddBoolVarCache(&gClickToPlayPlugins, "plugins.click_to_play");
+  }
+  initializedPrefCache = true;
+}
+
 class nsAsyncInstantiateEvent : public nsRunnable {
 public:
   nsObjectLoadingContent *mContent;
   nsAsyncInstantiateEvent(nsObjectLoadingContent* aContent)
   : mContent(aContent)
   {
     static_cast<nsIObjectLoadingContent *>(mContent)->AddRef();
   }
@@ -481,26 +493,36 @@ IsSupportedImage(const nsCString& aMimeT
 
   bool supported;
   nsresult rv = loader->SupportImageWithMimeType(aMimeType.get(), &supported);
   return NS_SUCCEEDED(rv) && supported;
 }
 
 nsresult nsObjectLoadingContent::IsPluginEnabledForType(const nsCString& aMIMEType)
 {
+  nsCOMPtr<nsIPluginHost> pluginHostCOM(do_GetService(MOZ_PLUGIN_HOST_CONTRACTID));
+  nsPluginHost *pluginHost = static_cast<nsPluginHost*>(pluginHostCOM.get());
+  if (!pluginHost) {
+    return NS_ERROR_FAILURE;
+  }
+
+  nsresult rv = pluginHost->IsPluginEnabledForType(aMIMEType.get());
+
+  // Check to see if the plugin is disabled before deciding if it
+  // should be in the "click to play" state, since we only want to
+  // display "click to play" UI for enabled plugins.
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+
   if (!mShouldPlay) {
     return NS_ERROR_PLUGIN_CLICKTOPLAY;
   }
 
-  nsCOMPtr<nsIPluginHost> pluginHostCOM(do_GetService(MOZ_PLUGIN_HOST_CONTRACTID));
-  nsPluginHost *pluginHost = static_cast<nsPluginHost*>(pluginHostCOM.get());
-  if (!pluginHost) {
-    return false;
-  }
-  return pluginHost->IsPluginEnabledForType(aMIMEType.get());
+  return NS_OK;
 }
 
 static void
 GetExtensionFromURI(nsIURI* uri, nsCString& ext)
 {
   nsCOMPtr<nsIURL> url(do_QueryInterface(uri));
   if (url) {
     url->GetFileExtension(ext);
@@ -541,29 +563,52 @@ bool nsObjectLoadingContent::IsPluginEna
   const char* typeFromExt;
   if (NS_SUCCEEDED(pluginHost->IsPluginEnabledForExtension(ext.get(), typeFromExt))) {
     mimeType = typeFromExt;
     return true;
   }
   return false;
 }
 
+nsresult
+nsObjectLoadingContent::BindToTree(nsIDocument* aDocument, nsIContent* /*aParent*/,
+                                   nsIContent* /*aBindingParent*/,
+                                   bool /*aCompileEventHandlers*/)
+{
+  if (aDocument) {
+    return aDocument->AddPlugin(this);
+  }
+  return NS_OK;
+}
+
+void
+nsObjectLoadingContent::UnbindFromTree(bool /*aDeep*/, bool /*aNullParent*/)
+{
+  nsCOMPtr<nsIContent> thisContent = do_QueryInterface(static_cast<nsIObjectLoadingContent*>(this));
+  MOZ_ASSERT(thisContent);
+  nsIDocument* ownerDoc = thisContent->OwnerDoc();
+  ownerDoc->RemovePlugin(this);
+}
+
 nsObjectLoadingContent::nsObjectLoadingContent()
   : mPendingInstantiateEvent(nsnull)
   , mChannel(nsnull)
   , mType(eType_Loading)
   , mInstantiating(false)
   , mUserDisabled(false)
   , mSuppressed(false)
   , mNetworkCreated(true)
-  // If plugins.click_to_play is false, plugins should always play
-  , mShouldPlay(!mozilla::Preferences::GetBool("plugins.click_to_play", false))
   , mSrcStreamLoading(false)
   , mFallbackReason(ePluginOtherState)
 {
+  InitPrefCache();
+  // If plugins.click_to_play is false, plugins should always play
+  mShouldPlay = !gClickToPlayPlugins;
+  // If plugins.click_to_play is true, track the activated state of plugins.
+  mActivated = !gClickToPlayPlugins;
 }
 
 nsObjectLoadingContent::~nsObjectLoadingContent()
 {
   DestroyImageLoadingContent();
   if (mFrameLoader) {
     mFrameLoader->Destroy();
   }
@@ -2201,10 +2246,18 @@ nsObjectLoadingContent::NotifyContentObj
 
 NS_IMETHODIMP
 nsObjectLoadingContent::PlayPlugin()
 {
   if (!nsContentUtils::IsCallerChrome())
     return NS_OK;
 
   mShouldPlay = true;
+  mActivated = true;
   return LoadObject(mURI, true, mContentType, true);
 }
+
+NS_IMETHODIMP
+nsObjectLoadingContent::GetActivated(bool* aActivated)
+{
+  *aActivated = mActivated;
+  return NS_OK;
+}
--- a/content/base/src/nsObjectLoadingContent.h
+++ b/content/base/src/nsObjectLoadingContent.h
@@ -239,16 +239,22 @@ class nsObjectLoadingContent : public ns
 
     static void Traverse(nsObjectLoadingContent *tmp,
                          nsCycleCollectionTraversalCallback &cb);
 
     void CreateStaticClone(nsObjectLoadingContent* aDest) const;
 
     static void DoStopPlugin(nsPluginInstanceOwner *aInstanceOwner, bool aDelayedStop);
 
+    nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
+                        nsIContent* aBindingParent,
+                        bool aCompileEventHandler);
+    void UnbindFromTree(bool aDeep = true,
+                        bool aNullParent = true);
+
   private:
 
     void NotifyContentObjectWrapper();
 
     /**
      * Check whether the given request represents a successful load.
      */
     static bool IsSuccessfulRequest(nsIRequest* aRequest);
@@ -394,16 +400,20 @@ class nsObjectLoadingContent : public ns
     // created using NS_FROM_PARSER_NETWORK flag. If the element is modified,
     // it may lose the flag.
     bool                        mNetworkCreated : 1;
 
     // Used to keep track of whether or not a plugin should be played.
     // This is used for click-to-play plugins.
     bool                        mShouldPlay : 1;
 
+    // Used to keep track of whether or not a plugin has been played.
+    // This is used for click-to-play plugins.
+    bool                        mActivated : 1;
+
     // Used to track when we might try to instantiate a plugin instance based on
     // a src data stream being delivered to this object. When this is true we don't
     // want plugin instance instantiation code to attempt to load src data again or
     // we'll deliver duplicate streams. Should be cleared when we are not loading
     // src data.
     bool mSrcStreamLoading;
 
     // A specific state that caused us to fallback
--- a/content/base/src/nsRange.cpp
+++ b/content/base/src/nsRange.cpp
@@ -617,26 +617