Merge from mozilla-central.
authorDavid Anderson <danderson@mozilla.com>
Fri, 30 Mar 2012 18:40:08 -0700
changeset 106080 c95bd17c4ae77baa34324a9e790b5684254830eb
parent 106079 66aed5264e79ecf48eba64d793a15723c0e37778 (current diff)
parent 90720 4c43cfe73516df0b3ec7686fc12a920ab85dc1f8 (diff)
child 106081 196cd36978ba034263f3efcc1a6e78c2aed800fd
push id1075
push uservporof@mozilla.com
push dateThu, 13 Sep 2012 10:46:49 +0000
treeherderfx-team@f39786e8364d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone14.0a1
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,16 @@ nsRange::ParentChainChanged(nsIContent *
   NS_ASSERTION(newRoot, "No valid boundary or root found!");
   NS_ASSERTION(newRoot == IsValidBoundary(mEndParent),
                "Start parent and end parent give different root!");
   // This is safe without holding a strong ref to self as long as the change
   // of mRoot is the last thing in DoSetRange.
   DoSetRange(mStartParent, mStartOffset, mEndParent, mEndOffset, newRoot);
 }
 
-// Private helper routine: get the length of aNode
-static PRUint32 GetNodeLength(nsINode *aNode)
-{
-  if(aNode->IsNodeOfType(nsINode::eDATA_NODE)) {
-    return static_cast<nsIContent*>(aNode)->TextLength();
-  }
-
-  return aNode->GetChildCount();
-}
-
 /******************************************************
  * Utilities for comparing points: API from nsIDOMRange
  ******************************************************/
 NS_IMETHODIMP
 nsRange::IsPointInRange(nsIDOMNode* aParent, PRInt32 aOffset, bool* aResult)
 {
   PRInt16 compareResult = 0;
   nsresult rv = ComparePoint(aParent, aOffset, &compareResult);
@@ -669,17 +659,17 @@ nsRange::ComparePoint(nsIDOMNode* aParen
   if (!nsContentUtils::ContentIsDescendantOf(parent, mRoot)) {
     return NS_ERROR_DOM_WRONG_DOCUMENT_ERR;
   }
   
   if (parent->NodeType() == nsIDOMNode::DOCUMENT_TYPE_NODE) {
     return NS_ERROR_DOM_INVALID_NODE_TYPE_ERR;
   }
 
-  if (aOffset < 0 || aOffset > GetNodeLength(parent)) {
+  if (aOffset < 0 || aOffset > parent->Length()) {
     return NS_ERROR_DOM_INDEX_SIZE_ERR;
   }
   
   PRInt32 cmp;
   if ((cmp = nsContentUtils::ComparePoints(parent, aOffset,
                                            mStartParent, mStartOffset)) <= 0) {
     
     *aResult = cmp;
@@ -933,19 +923,19 @@ nsRange::SetStart(nsIDOMNode* aParent, P
 }
 
 /* virtual */ nsresult
 nsRange::SetStart(nsINode* aParent, PRInt32 aOffset)
 {
   nsINode* newRoot = IsValidBoundary(aParent);
   NS_ENSURE_TRUE(newRoot, NS_ERROR_DOM_INVALID_NODE_TYPE_ERR);
 
-  PRInt32 len = GetNodeLength(aParent);
-  if (aOffset < 0 || aOffset > len)
+  if (aOffset < 0 || aOffset > aParent->Length()) {
     return NS_ERROR_DOM_INDEX_SIZE_ERR;
+  }
 
   // Collapse if not positioned yet, if positioned in another doc or
   // if the new start is after end.
   if (!mIsPositioned || newRoot != mRoot ||
       nsContentUtils::ComparePoints(aParent, aOffset,
                                     mEndParent, mEndOffset) == 1) {
     DoSetRange(aParent, aOffset, aParent, aOffset, newRoot);
 
@@ -997,18 +987,17 @@ nsRange::SetEnd(nsIDOMNode* aParent, PRI
 
 
 /* virtual */ nsresult
 nsRange::SetEnd(nsINode* aParent, PRInt32 aOffset)
 {
   nsINode* newRoot = IsValidBoundary(aParent);
   NS_ENSURE_TRUE(newRoot, NS_ERROR_DOM_INVALID_NODE_TYPE_ERR);
 
-  PRInt32 len = GetNodeLength(aParent);
-  if (aOffset < 0 || aOffset > len) {
+  if (aOffset < 0 || aOffset > aParent->Length()) {
     return NS_ERROR_DOM_INDEX_SIZE_ERR;
   }
 
   // Collapse if not positioned yet, if positioned in another doc or
   // if the new end is before start.
   if (!mIsPositioned || newRoot != mRoot ||
       nsContentUtils::ComparePoints(mStartParent, mStartOffset,
                                     aParent, aOffset) == 1) {
@@ -1095,17 +1084,17 @@ nsRange::SelectNodeContents(nsIDOMNode* 
 {
   VALIDATE_ACCESS(aN);
 
   nsCOMPtr<nsINode> node = do_QueryInterface(aN);
   nsINode* newRoot = IsValidBoundary(node);
   NS_ENSURE_TRUE(newRoot, NS_ERROR_DOM_INVALID_NODE_TYPE_ERR);
   
   AutoInvalidateSelection atEndOfBlock(this);
-  DoSetRange(node, 0, node, GetNodeLength(node), newRoot);
+  DoSetRange(node, 0, node, node->Length(), newRoot);
   
   return NS_OK;
 }
 
 // The Subtree Content Iterator only returns subtrees that are
 // completely within a given range. It doesn't return a CharacterData
 // node that contains either the start or end point of the range.,
 // nor does it return element nodes when nothing in the element is selected.
--- a/content/base/src/nsScriptLoader.cpp
+++ b/content/base/src/nsScriptLoader.cpp
@@ -913,17 +913,18 @@ nsScriptLoader::EvaluateScript(nsScriptL
   nsCAutoString url;
   nsContentUtils::GetWrapperSafeScriptFilename(mDocument, aRequest->mURI, url);
 
   bool isUndefined;
   rv = context->EvaluateString(aScript, globalObject->GetGlobalJSObject(),
                                mDocument->NodePrincipal(),
                                aRequest->mOriginPrincipal,
                                url.get(), aRequest->mLineNo,
-                               aRequest->mJSVersion, nsnull, &isUndefined);
+                               JSVersion(aRequest->mJSVersion), nsnull,
+                               &isUndefined);
 
   // Put the old script back in case it wants to do anything else.
   mCurrentScript = oldCurrent;
 
   JSContext *cx = nsnull; // Initialize this to keep GCC happy.
   if (stid == nsIProgrammingLanguage::JAVASCRIPT) {
     cx = context->GetNativeContext();
     ::JS_BeginRequest(cx);
--- a/content/base/src/nsXMLHttpRequest.cpp
+++ b/content/base/src/nsXMLHttpRequest.cpp
@@ -100,19 +100,22 @@
 #include "nsIContentSecurityPolicy.h"
 #include "nsAsyncRedirectVerifyHelper.h"
 #include "jstypedarray.h"
 #include "nsStringBuffer.h"
 #include "nsDOMFile.h"
 #include "nsIFileChannel.h"
 #include "mozilla/Telemetry.h"
 #include "sampler.h"
+#include "nsIDOMFormData.h"
+
 #include "nsWrapperCacheInlines.h"
 
 using namespace mozilla;
+using namespace mozilla::dom;
 
 #define LOAD_STR "load"
 #define ERROR_STR "error"
 #define ABORT_STR "abort"
 #define TIMEOUT_STR "timeout"
 #define LOADSTART_STR "loadstart"
 #define PROGRESS_STR "progress"
 #define UPLOADPROGRESS_STR "uploadprogress"
@@ -156,16 +159,26 @@ using namespace mozilla;
    XML_HTTP_REQUEST_SENT |                  \
    XML_HTTP_REQUEST_STOPPED)
 
 #define NS_BADCERTHANDLER_CONTRACTID \
   "@mozilla.org/content/xmlhttprequest-bad-cert-handler;1"
 
 #define NS_PROGRESS_EVENT_INTERVAL 50
 
+#define IMPL_STRING_GETTER(_name)                                               \
+  NS_IMETHODIMP                                                                 \
+  nsXMLHttpRequest::_name(nsAString& aOut)                                      \
+  {                                                                             \
+    nsString tmp;                                                               \
+    _name(tmp);                                                                 \
+    aOut = tmp;                                                                 \
+    return NS_OK;                                                               \
+  }
+
 NS_IMPL_ISUPPORTS1(nsXHRParseEndListener, nsIDOMEventListener)
 
 class nsResumeTimeoutsEvent : public nsRunnable
 {
 public:
   nsResumeTimeoutsEvent(nsPIDOMWindow* aWindow) : mWindow(aWindow) {}
 
   NS_IMETHOD Run()
@@ -465,16 +478,19 @@ nsXMLHttpRequest::nsXMLHttpRequest()
     mWarnAboutSyncHtml(false),
     mLoadLengthComputable(false), mLoadTotal(0),
     mFirstStartRequestSeen(false),
     mInLoadProgressEvent(false),
     mResultJSON(JSVAL_VOID),
     mResultArrayBuffer(nsnull)
 {
   nsLayoutStatics::AddRef();
+#ifdef DEBUG
+  StaticAssertions();
+#endif
 }