Merge mozilla central and tracemonkey.
authorChris Leary <cdleary@mozilla.com>
Mon, 20 Jun 2011 16:49:20 -0700
changeset 71401 a285146675dc126245856dcdc324b4f0264d0740
parent 71400 41d5782eabf2bd500d6d8c61be8f03915959891b (current diff)
parent 71338 d578ca1a42e71a85ffa5faa4901dfed414270f86 (diff)
child 71426 bf714fffdfdfd31293017ca79bad20a4097f2fe6
child 71838 1e464e38591eca2dec796c67d2a8bb07c881e391
push idunknown
push userunknown
push dateunknown
milestone7.0a1
Merge mozilla central and tracemonkey.
browser/components/places/tests/perf/Makefile.in
browser/components/places/tests/perf/browser_ui_000_data.js
browser/components/places/tests/perf/browser_ui_bookmarks_sidebar.js
browser/components/places/tests/perf/browser_ui_history_menu.js
browser/components/places/tests/perf/browser_ui_history_sidebar.js
browser/components/places/tests/perf/browser_ui_history_sidebar_2.js
browser/components/places/tests/perf/browser_ui_history_sidebar_3.js
browser/components/places/tests/perf/browser_ui_locationbar.js
browser/components/places/tests/perf/perf_large_delete.xul
config/installcfunc.pl
config/installchrome.pl
content/base/public/nsContentUtils.h
content/base/public/nsISyncLoadDOMService.idl
content/base/src/nsContentUtils.cpp
content/base/src/nsFrameMessageManager.cpp
content/base/src/nsXMLHttpRequest.cpp
content/base/test/test_bug574596.html
content/events/src/nsDOMOrientationEvent.cpp
content/events/src/nsDOMOrientationEvent.h
dom/interfaces/base/nsIDOMNSFeatureFactory.idl
dom/interfaces/core/nsIDOM3Node.idl
dom/ipc/TabParent.cpp
dom/system/android/nsAccelerometerSystem.cpp
dom/system/android/nsAccelerometerSystem.h
dom/system/cocoa/nsAccelerometerSystem.h
dom/system/cocoa/nsAccelerometerSystem.mm
dom/system/nsAccelerometer.cpp
dom/system/nsAccelerometer.h
dom/system/unix/nsAccelerometerSystem.cpp
dom/system/unix/nsAccelerometerSystem.h
dom/system/windows/nsAccelerometerSystem.cpp
dom/system/windows/nsAccelerometerSystem.h
gfx/cairo/cairo/src/cairo-ddraw.h
gfx/cairo/wince-fixes.patch
js/src/Makefile.in
js/src/jsarray.cpp
js/src/jscntxt.h
js/src/jsfun.h
js/src/jsinterp.cpp
js/src/jstracer.cpp
js/src/xpconnect/src/xpcwrappednativejsops.cpp
modules/libreg/standalone/Makefile.in
startupcache/nsStartupCacheUtils.cpp
toolkit/crashreporter/test/browser/aboutcrashes_utils.js
toolkit/themes/pinstripe/mozapps/extensions/background-texture.png
toolkit/themes/winstripe/mozapps/extensions/background-texture.png
xpcom/base/nsSetDllDirectory.cpp
xpcom/io/nsFastLoadFile.cpp
xpcom/io/nsFastLoadFile.h
xpcom/io/nsFastLoadService.cpp
xpcom/io/nsFastLoadService.h
xpcom/io/nsIFastLoadFileControl.idl
xpcom/io/nsIFastLoadService.idl
xpcom/system/nsIAccelerometer.idl
--- a/accessible/src/base/nsCoreUtils.cpp
+++ b/accessible/src/base/nsCoreUtils.cpp
@@ -38,17 +38,16 @@
 
 #include "nsCoreUtils.h"
 
 #include "nsIAccessibleTypes.h"
 
 #include "nsAccessNode.h"
 
 #include "nsIDocument.h"
-#include "nsIDOM3Node.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOMHTMLDocument.h"
 #include "nsIDOMHTMLElement.h"
 #include "nsIDOMNodeList.h"
 #include "nsIDOMRange.h"
 #include "nsIDOMWindowInternal.h"
 #include "nsIDOMXULElement.h"
 #include "nsIDocShell.h"
--- a/browser/app/Makefile.in
+++ b/browser/app/Makefile.in
@@ -86,39 +86,30 @@ endif
 
 LIBS += $(JEMALLOC_LIBS)
 
 ifdef LIBXUL_SDK
 include $(topsrcdir)/config/rules.mk
 else
 # Build a binary bootstrapping with XRE_main
 
-ifneq (,$(filter OS2 WINNT,$(OS_ARCH)))
 PROGRAM = $(MOZ_APP_NAME)$(BIN_SUFFIX)
-else
-PROGRAM = $(MOZ_APP_NAME)-bin$(BIN_SUFFIX)
-endif
 
 CPPSRCS = nsBrowserApp.cpp
 
 LOCAL_INCLUDES += -I$(topsrcdir)/toolkit/xre
 LOCAL_INCLUDES += -I$(topsrcdir)/xpcom/base
+LOCAL_INCLUDES += -I$(topsrcdir)/xpcom/build
 
-ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
-LIBS += $(DIST)/bin/XUL
-TK_LIBS := $(TK_LIBS)
-else
-EXTRA_DSO_LIBS += xul
-endif
+DEFINES += -DXPCOM_GLUE
+STL_FLAGS=
 
 LIBS += \
-	$(STATIC_COMPONENTS_LINKER_PATH) \
 	$(EXTRA_DSO_LIBS) \
-	$(XPCOM_GLUE_LDOPTS) \
-	$(NSPR_LIBS) \
+	$(XPCOM_STANDALONE_GLUE_LDOPTS) \
 	$(NULL)
 
 ifdef MOZ_JPROF
 LIBS += -ljprof
 endif
 
 ifndef MOZ_WINCONSOLE
 ifdef MOZ_DEBUG
@@ -189,28 +180,19 @@ ifeq ($(OS_TEST),x86_64)
 # set stack to 2MB on x64 build.  See bug 582910
 LDFLAGS += -STACK:2097152
 endif
 endif
 endif
 
 ifneq (,$(filter-out OS2 WINNT,$(OS_ARCH)))
 
-$(MOZ_APP_NAME):: $(topsrcdir)/build/unix/mozilla.in $(GLOBAL_DEPS)
-	cat $< | sed -e "s|%MOZAPPDIR%|$(installdir)|" \
-		-e "s|%MOZ_APP_DISPLAYNAME%|$(MOZ_APP_DISPLAYNAME)|" > $@
-	chmod +x $@
+libs:: 
+	cp -p $(MOZ_APP_NAME)$(BIN_SUFFIX) $(DIST)/bin/$(MOZ_APP_NAME)-bin$(BIN_SUFFIX)
 
-libs:: $(MOZ_APP_NAME)
-	$(INSTALL) $< $(DIST)/bin
-
-install:: $(MOZ_APP_NAME)
-	$(SYSINSTALL) $< $(DESTDIR)$(bindir)
-
-GARBAGE += $(MOZ_APP_NAME)
 GARBAGE += $(addprefix $(DIST)/bin/defaults/pref/, firefox.js)
 
 endif
 
 endif # LIBXUL_SDK
 
 DEFINES += -DFIREFOX_ICO=\"$(DIST)/branding/firefox.ico\" -DDOCUMENT_ICO=\"$(DIST)/branding/document.ico\"
 
@@ -268,17 +250,17 @@ libs repackage:: $(PROGRAM) application.
 	rsync -a --exclude CVS --exclude "*.in" $(srcdir)/macbuild/Contents $(DIST)/$(APP_NAME).app --exclude English.lproj
 	$(MKDIR) -p $(DIST)/$(APP_NAME).app/Contents/Resources/$(AB).lproj
 	rsync -a --exclude CVS --exclude "*.in" $(srcdir)/macbuild/Contents/Resources/English.lproj/ $(DIST)/$(APP_NAME).app/Contents/Resources/$(AB).lproj
 	sed -e "s/%APP_VERSION%/$(APP_VERSION)/" -e "s/%APP_NAME%/$(APP_NAME)/" -e "s/%LOWER_APP_NAME%/$(LOWER_APP_NAME)/" $(srcdir)/macbuild/Contents/Info.plist.in > $(DIST)/$(APP_NAME).app/Contents/Info.plist
 	sed -e "s/%APP_NAME%/$(APP_NAME)/" $(srcdir)/macbuild/Contents/Resources/English.lproj/InfoPlist.strings.in | iconv -f UTF-8 -t UTF-16 > $(DIST)/$(APP_NAME).app/Contents/Resources/$(AB).lproj/InfoPlist.strings
 	rsync -a $(DIST)/bin/ $(DIST)/$(APP_NAME).app/Contents/$(APPFILES)
 	$(RM) $(DIST)/$(APP_NAME).app/Contents/$(APPFILES)/mangle $(DIST)/$(APP_NAME).app/Contents/$(APPFILES)/shlibsign
 ifdef LIBXUL_SDK
-	cp $(LIBXUL_DIST)/bin/$(XR_STUB_NAME) $(DIST)/$(APP_NAME).app/Contents/MacOS/firefox-bin
+	cp $(LIBXUL_DIST)/bin/$(XR_STUB_NAME) $(DIST)/$(APP_NAME).app/Contents/MacOS/firefox
 else
 	$(RM) $(DIST)/$(APP_NAME).app/Contents/MacOS/$(PROGRAM)
 	rsync -aL $(PROGRAM) $(DIST)/$(APP_NAME).app/Contents/MacOS
 endif
 	-cp -L $(DIST)/bin/mangle $(DIST)/bin/shlibsign $(DIST)/$(APP_NAME).app/Contents/$(APPFILES)
 	cp -RL $(DIST)/branding/firefox.icns $(DIST)/$(APP_NAME).app/Contents/Resources/firefox.icns
 	cp -RL $(DIST)/branding/document.icns $(DIST)/$(APP_NAME).app/Contents/Resources/document.icns
 	printf APPLMOZB > $(DIST)/$(APP_NAME).app/Contents/PkgInfo
--- a/browser/app/blocklist.xml
+++ b/browser/app/blocklist.xml
@@ -1,201 +1,193 @@
 <?xml version="1.0"?>
-<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1306529826000">
+<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist">
   <emItems>
-      <emItem  blockID="i8" id="{B13721C7-F507-4982-B2E5-502A71474FED}">
-                        <versionRange  minVersion=" " severity="1">
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i38" id="{B7082FAA-CB62-4872-9106-E42DD88EDE45}">
-                        <versionRange  minVersion="0.1" maxVersion="3.3.0.*" severity="0">
-                      <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-                              <versionRange  minVersion="3.7a1" maxVersion="*" />
-                          </targetApplication>
-                    </versionRange>
-                                <versionRange  minVersion="3.3.1" maxVersion="*" severity="0">
-                      <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-                              <versionRange  minVersion="5.0a1" maxVersion="*" />
-                          </targetApplication>
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i19" id="{46551EC9-40F0-4e47-8E18-8E5CF550CFB8}">
-                        <versionRange  minVersion="1.1b1" maxVersion="1.1b1" severity="0">
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i16" id="{27182e60-b5f3-411c-b545-b44205977502}">
-                        <versionRange  minVersion="1.0" maxVersion="1.0" severity="0">
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i10" id="{8CE11043-9A15-4207-A565-0C94C42D590D}">
-                        </emItem>
-      <emItem  blockID="i1" id="mozilla_cc@internetdownloadmanager.com">
-                        <versionRange  minVersion="2.1" maxVersion="3.3" severity="0">
-                      <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-                              <versionRange  minVersion="3.0a1" maxVersion="*" />
-                          </targetApplication>
-                    </versionRange>
-                                <versionRange  minVersion=" " maxVersion="6.9.8" severity="0">
-                      <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-                              <versionRange  minVersion="3.7a1pre" maxVersion="*" />
-                          </targetApplication>
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i18" id="msntoolbar@msn.com">
-                        <versionRange  minVersion=" " maxVersion="6.*" severity="0">
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i13" id="{E8E88AB0-7182-11DF-904E-6045E0D72085}">
-                        </emItem>
-      <emItem  blockID="i4" id="{4B3803EA-5230-4DC3-A7FC-33638F3D3542}">
-                        <versionRange  minVersion="1.2" maxVersion="1.2" severity="0">
-                      <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-                              <versionRange  minVersion="3.0a1" maxVersion="*" />
-                          </targetApplication>
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i23" id="firefox@bandoo.com">
-                        <versionRange  minVersion="5.0" maxVersion="5.0" severity="1">
-                      <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-                              <versionRange  minVersion="3.7a1pre" maxVersion="*" />
-                          </targetApplication>
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i22" id="ShopperReports@ShopperReports.com">
-                        <versionRange  minVersion="3.1.22.0" maxVersion="3.1.22.0" severity="0">
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i2" id="fdm_ffext@freedownloadmanager.org">
-                        <versionRange  minVersion="1.0" maxVersion="1.3.1" severity="0">
-                      <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-                              <versionRange  minVersion="3.0a1" maxVersion="*" />
-                          </targetApplication>
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i5" id="support@daemon-tools.cc">
-                        <versionRange  minVersion=" " maxVersion="1.0.0.5" severity="0">
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i6" id="{3f963a5b-e555-4543-90e2-c3908898db71}">
-                        <versionRange  minVersion=" " maxVersion="8.5" severity="0">
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i12" id="masterfiler@gmail.com">
-                        <versionRange  severity="3">
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i20" id="{AB2CE124-6272-4b12-94A9-7303C7397BD1}">
-                        <versionRange  minVersion="0.1" maxVersion="5.2.0.7164" severity="1">
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i11" id="yslow@yahoo-inc.com">
-                        <versionRange  minVersion="2.0.5" maxVersion="2.0.5" severity="0">
-                      <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-                              <versionRange  minVersion="3.5.7" maxVersion="*" />
-                          </targetApplication>
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i17" id="{3252b9ae-c69a-4eaf-9502-dc9c1f6c009e}">
-                        <versionRange  minVersion="2.2" maxVersion="2.2" severity="0">
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i3" id="langpack-vi-VN@firefox.mozilla.org">
-                        <versionRange  minVersion="2.0" maxVersion="2.0" severity="0">
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i7" id="{2224e955-00e9-4613-a844-ce69fccaae91}">
-                        </emItem>
-      <emItem  blockID="i24" id="{6E19037A-12E3-4295-8915-ED48BC341614}">
-                        <versionRange  minVersion="0.1" maxVersion="1.3.328.4" severity="1">
-                      <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-                              <versionRange  minVersion="3.7a1pre" maxVersion="*" />
-                          </targetApplication>
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i15" id="personas@christopher.beard">
-                        <versionRange  minVersion="1.6" maxVersion="1.6" severity="0">
-                      <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-                              <versionRange  minVersion="3.6" maxVersion="3.6.*" />
-                          </targetApplication>
-                    </versionRange>
-                  </emItem>
-      <emItem  blockID="i21" id="support@update-firefox.com">
-                        </emItem>
-    </emItems>
-
-  <pluginItems>
-      <pluginItem  blockID="p26">
-      <match name="name" exp="^Yahoo Application State Plugin$" />      <match name="description" exp="^Yahoo Application State Plugin$" />      <match name="filename" exp="npYState.dll" />              <versionRange  severity="0">
-                      <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-              <versionRange  minVersion="3.0a1" maxVersion="3.*" />
-            </targetApplication>
-                  </versionRange>
-          </pluginItem>
-      <pluginItem  blockID="p27">
-      <match name="name" exp="QuickTime Plug-in 7[.]1[.]" />            <match name="filename" exp="npqtplugin.?[.]dll" />              <versionRange  severity="0">
-                      <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-              <versionRange  minVersion="3.0a1" maxVersion="3.*" />
-            </targetApplication>
-                  </versionRange>
-          </pluginItem>
-      <pluginItem  blockID="p28">
-                  <match name="filename" exp="NPFFAddOn.dll" />              <versionRange  severity="0">
-                  </versionRange>
-          </pluginItem>
-      <pluginItem  blockID="p31">
-                  <match name="filename" exp="NPMySrch.dll" />              <versionRange  severity="0">
-                  </versionRange>
-          </pluginItem>
-      <pluginItem  blockID="p32">
-                  <match name="filename" exp="npViewpoint.dll" />              <versionRange  severity="0">
-                      <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-              <versionRange  minVersion="3.0" maxVersion="*" />
-            </targetApplication>
-                  </versionRange>
-          </pluginItem>
-      <pluginItem  blockID="p33">
-      <match name="name" exp="[0-6]\.0\.[01]\d{2}\.\d+" />            <match name="filename" exp="npdeploytk.dll" />              <versionRange  severity="1">
-                  </versionRange>
-          </pluginItem>
-      <pluginItem  blockID="p34">
-                  <match name="filename" exp="[Nn][Pp][Jj][Pp][Ii]1[56]0_[0-9]+\.[Dd][Ll][Ll]" />              <versionRange  severity="0">
-                      <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-              <versionRange  minVersion="3.6a1pre" maxVersion="*" />
-            </targetApplication>
-                  </versionRange>
-          </pluginItem>
-    </pluginItems>
-
-  <gfxItems>
-    <gfxBlacklistEntry  blockID="g35">
-      <os>WINNT 6.1</os>
-      <vendor>0x10de</vendor>
-              <devices>
-                      <device>0x0a6c</device>
-                  </devices>
-            <feature>DIRECT2D</feature>
-      <featureStatus>BLOCKED_DRIVER_VERSION</featureStatus>
-      <driverVersion>8.17.12.5896</driverVersion>
-      <driverVersionComparator>LESS_THAN_OR_EQUAL</driverVersionComparator>
-    </gfxBlacklistEntry>
-    <gfxBlacklistEntry  blockID="g36">
-      <os>WINNT 6.1</os>
-      <vendor>0x10de</vendor>
-              <devices>
-                      <device>0x0a6c</device>
-                  </devices>
-            <feature>DIRECT3D_9_LAYERS</feature>
-      <featureStatus>BLOCKED_DRIVER_VERSION</featureStatus>
-      <driverVersion>8.17.12.5896</driverVersion>
-      <driverVersionComparator>LESS_THAN_OR_EQUAL</driverVersionComparator>
-    </gfxBlacklistEntry>
-    <gfxBlacklistEntry  blockID="g37">
-      <os>WINNT 5.1</os>
-      <vendor>0x10de</vendor>
-            <feature>DIRECT3D_9_LAYERS</feature>
-      <featureStatus>BLOCKED_DRIVER_VERSION</featureStatus>
-      <driverVersion>7.0.0.0</driverVersion>
-      <driverVersionComparator>GREATER_THAN_OR_EQUAL</driverVersionComparator>
-    </gfxBlacklistEntry>
-    </gfxItems>
-
-
-</blocklist>
\ No newline at end of file
+    <emItem id="fdm_ffext@freedownloadmanager.org">
+      <versionRange minVersion="1.0" maxVersion="1.3.1">
+        <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
+           <versionRange minVersion="3.0a1" maxVersion="*"/>
+        </targetApplication>
+      </versionRange>
+    </emItem>
+    <emItem id="firefox@bandoo.com">
+      <versionRange minVersion="5.0" maxVersion="5.0" severity="1">
+        <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
+           <versionRange minVersion="3.7a1pre" maxVersion="*"/>
+        </targetApplication>
+      </versionRange>
+    </emItem>
+    <emItem id="langpack-vi-VN@firefox.mozilla.org">
+      <versionRange minVersion="2.0" maxVersion="2.0"/>
+    </emItem>
+    <emItem id="masterfiler@gmail.com">
+      <versionRange severity="3"/>
+    </emItem>
+    <emItem id="mozilla_cc@internetdownloadmanager.com">
+      <versionRange minVersion=" " maxVersion="6.9.8">
+        <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
+           <versionRange minVersion="3.7a1pre" maxVersion="*"/>
+        </targetApplication>
+      </versionRange>
+      <versionRange minVersion="2.1" maxVersion="3.3">
+        <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
+           <versionRange minVersion="3.0a1" maxVersion="*"/>
+        </targetApplication>
+      </versionRange>
+    </emItem>
+    <emItem id="msntoolbar@msn.com">
+      <versionRange minVersion=" " maxVersion="6.*"/>
+    </emItem>
+    <emItem id="personas@christopher.beard">
+      <versionRange minVersion="1.6" maxVersion="1.6">
+        <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
+           <versionRange minVersion="3.6" maxVersion="3.6.*"/>
+        </targetApplication>
+      </versionRange>
+    </emItem>
+    <emItem id="ShopperReports@ShopperReports.com">
+      <versionRange minVersion="3.1.22.0" maxVersion="3.1.22.0"/>
+    </emItem>
+    <emItem id="support@daemon-tools.cc">
+      <versionRange minVersion=" " maxVersion="1.0.0.5"/>
+    </emItem>
+    <emItem id="support@update-firefox.com"/>
+    <emItem id="yslow@yahoo-inc.com">
+      <versionRange minVersion="2.0.5" maxVersion="2.0.5">
+        <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
+           <versionRange minVersion="3.5.7" maxVersion="*"/>
+        </targetApplication>
+      </versionRange>
+    </emItem>
+    <emItem id="{2224e955-00e9-4613-a844-ce69fccaae91}"/>
+    <emItem id="{27182e60-b5f3-411c-b545-b44205977502}">
+      <versionRange minVersion="1.0" maxVersion="1.0"/>
+    </emItem>
+    <emItem id="{3252b9ae-c69a-4eaf-9502-dc9c1f6c009e}">
+      <versionRange minVersion="2.2" maxVersion="2.2"/>
+    </emItem>
+    <emItem id="{3f963a5b-e555-4543-90e2-c3908898db71}">
+      <versionRange minVersion=" " maxVersion="8.5"/>
+    </emItem>
+    <emItem id="{46551EC9-40F0-4e47-8E18-8E5CF550CFB8}">
+      <versionRange minVersion="1.1b1" maxVersion="1.1b1"/>
+    </emItem>
+    <emItem id="{4B3803EA-5230-4DC3-A7FC-33638F3D3542}">
+      <versionRange minVersion="1.2" maxVersion="1.2">
+        <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
+           <versionRange minVersion="3.0a1" maxVersion="*"/>
+        </targetApplication>
+      </versionRange>
+    </emItem>
+    <emItem id="{6E19037A-12E3-4295-8915-ED48BC341614}">
+      <versionRange minVersion="0.1" maxVersion="1.3.328.4" severity="1">
+        <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
+           <versionRange minVersion="3.7a1pre" maxVersion="*"/>
+        </targetApplication>
+      </versionRange>
+    </emItem>
+    <emItem id="{8CE11043-9A15-4207-A565-0C94C42D590D}"/>
+    <emItem id="{AB2CE124-6272-4b12-94A9-7303C7397BD1}">
+      <versionRange minVersion="0.1" maxVersion="5.2.0.7164" severity="1"/>
+    </emItem>
+    <emItem id="{B13721C7-F507-4982-B2E5-502A71474FED}">
+      <versionRange severity="1"/>
+    </emItem>
+    <emItem id="{B7082FAA-CB62-4872-9106-E42DD88EDE45}">
+      <versionRange minVersion="0.1" maxVersion="3.3.0.*">
+        <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
+           <versionRange minVersion="3.7a1" maxVersion="*"/>
+        </targetApplication>
+      </versionRange>
+      <versionRange minVersion="3.3.1" maxVersion="*">
+        <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
+           <versionRange minVersion="5.0a1" maxVersion="*"/>
+        </targetApplication>
+      </versionRange>
+    </emItem>
+    <emItem id="{E8E88AB0-7182-11DF-904E-6045E0D72085}"/>
+  </emItems>
+<pluginItems>
+  <pluginItem>
+    <match name="name" exp="^Yahoo Application State Plugin$"/>
+    <match name="description" exp="^Yahoo Application State Plugin$"/>
+    <match name="filename" exp="npYState.dll"/>
+    <versionRange>
+      <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
+        <versionRange minVersion="3.0a1" maxVersion="3.*"/>
+      </targetApplication>
+    </versionRange>
+  </pluginItem>
+  <pluginItem>
+    <match name="name" exp="QuickTime Plug-in 7[.]1[.]"/>
+    <match name="filename" exp="npqtplugin.?[.]dll"/>
+    <versionRange>
+      <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
+        <versionRange minVersion="3.0a1" maxVersion="3.*"/>
+      </targetApplication>
+    </versionRange>
+  </pluginItem>
+  <pluginItem>
+    <match name="filename" exp="NPFFAddOn.dll"/>
+    <versionRange>
+    </versionRange>
+  </pluginItem>
+  <pluginItem>
+    <match name="filename" exp="NPMySrch.dll"/>
+    <versionRange>
+    </versionRange>
+  </pluginItem>
+  <pluginItem>
+    <match name="filename" exp="npViewpoint.dll"/>
+    <versionRange>
+      <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
+        <versionRange minVersion="3.0" maxVersion="*"/>
+      </targetApplication>
+    </versionRange>
+  </pluginItem>
+  <pluginItem>
+    <match name="name" exp="[0-6]\.0\.[01]\d{2}\.\d+"/>
+    <match name="filename" exp="npdeploytk.dll"/>
+    <versionRange severity="1">
+    </versionRange>
+  </pluginItem>
+  <pluginItem>
+    <match name="filename" exp="[Nn][Pp][Jj][Pp][Ii]1[56]0_[0-9]+\.[Dd][Ll][Ll]"/>
+    <versionRange>
+      <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
+        <versionRange minVersion="3.6a1pre" maxVersion="*"/>
+      </targetApplication>
+    </versionRange>
+  </pluginItem>
+</pluginItems>
+<gfxItems>
+  <gfxBlacklistEntry>
+    <os>WINNT 6.1</os>
+    <vendor>0x10de</vendor>
+    <devices>
+      <device>0x0a6c</device>
+    </devices>
+    <feature>DIRECT2D</feature>
+    <featureStatus>BLOCKED_DRIVER_VERSION</featureStatus>
+    <driverVersion>8.17.12.5896</driverVersion>
+    <driverVersionComparator>LESS_THAN_OR_EQUAL</driverVersionComparator>
+  </gfxBlacklistEntry>
+  <gfxBlacklistEntry>
+    <os>WINNT 6.1</os>
+    <vendor>0x10de</vendor>
+    <devices>
+      <device>0x0a6c</device>
+    </devices>
+    <feature>DIRECT3D_9_LAYERS</feature>
+    <featureStatus>BLOCKED_DRIVER_VERSION</featureStatus>
+    <driverVersion>8.17.12.5896</driverVersion>
+    <driverVersionComparator>LESS_THAN_OR_EQUAL</driverVersionComparator>
+  </gfxBlacklistEntry>
+  <gfxBlacklistEntry>
+    <os>WINNT 5.1</os>
+    <vendor>0x10de</vendor>
+    <feature>DIRECT3D_9_LAYERS</feature>
+    <featureStatus>BLOCKED_DRIVER_VERSION</featureStatus>
+    <driverVersion>7.0.0.0</driverVersion>
+    <driverVersionComparator>GREATER_THAN_OR_EQUAL</driverVersionComparator>
+  </gfxBlacklistEntry>
+</gfxItems>
+</blocklist>
--- a/browser/app/macbuild/Contents/Info.plist.in
+++ b/browser/app/macbuild/Contents/Info.plist.in
@@ -138,17 +138,17 @@
 			</array>
 			<key>CFBundleTypeName</key>
 			<string>HTML5 Video (WebM)</string>
 			<key>CFBundleTypeRole</key>
 			<string>Viewer</string>
 		</dict>
 	</array>
 	<key>CFBundleExecutable</key>
-	<string>firefox-bin</string>
+	<string>firefox</string>
 	<key>CFBundleGetInfoString</key>
 	<string>%APP_NAME% %APP_VERSION%</string>
 	<key>CFBundleIconFile</key>
 	<string>firefox</string>
 	<key>CFBundleIdentifier</key>
 	<string>org.mozilla.%LOWER_APP_NAME%</string>
 	<key>CFBundleInfoDictionaryVersion</key>
 	<string>6.0</string>
--- a/browser/app/nsBrowserApp.cpp
+++ b/browser/app/nsBrowserApp.cpp
@@ -31,39 +31,44 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
+#include "nsXPCOMGlue.h"
 #include "nsXULAppAPI.h"
 #ifdef XP_WIN
 #include <windows.h>
 #include <stdlib.h>
 #endif
 
 #include <stdio.h>
 #include <stdarg.h>
+#include <string.h>
 
 #include "plstr.h"
 #include "prprf.h"
 #include "prenv.h"
 
 #include "nsCOMPtr.h"
 #include "nsILocalFile.h"
 #include "nsStringGlue.h"
 
 #ifdef XP_WIN
-// we want to use the DLL blocklist if possible
-#define XRE_WANT_DLL_BLOCKLIST
 // we want a wmain entry point
 #include "nsWindowsWMain.cpp"
+#define snprintf _snprintf
+#define strcasecmp _stricmp
 #endif
+#include "BinaryPath.h"
+
+#include "nsXPCOMPrivate.h" // for MAXPATHLEN and XPCOM_DLL
 
 static void Output(const char *fmt, ... )
 {
   va_list ap;
   va_start(ap, fmt);
 
 #if defined(XP_WIN) && !MOZ_WINCONSOLE
   PRUnichar msg[2048];
@@ -80,53 +85,77 @@ static void Output(const char *fmt, ... 
  * Return true if |arg| matches the given argument name.
  */
 static PRBool IsArg(const char* arg, const char* s)
 {
   if (*arg == '-')
   {
     if (*++arg == '-')
       ++arg;
-    return !PL_strcasecmp(arg, s);
+    return !strcasecmp(arg, s);
   }
 
 #if defined(XP_WIN) || defined(XP_OS2)
   if (*arg == '/')
-    return !PL_strcasecmp(++arg, s);
+    return !strcasecmp(++arg, s);
 #endif
 
   return PR_FALSE;
 }
 
 /**
  * A helper class which calls NS_LogInit/NS_LogTerm in its scope.
  */
 class ScopedLogging
 {
 public:
   ScopedLogging() { NS_LogInit(); }
   ~ScopedLogging() { NS_LogTerm(); }
 };
 
-int main(int argc, char* argv[])
-{
-  ScopedLogging log;
+XRE_GetFileFromPathType XRE_GetFileFromPath;
+XRE_CreateAppDataType XRE_CreateAppData;
+XRE_FreeAppDataType XRE_FreeAppData;
+#ifdef XRE_HAS_DLL_BLOCKLIST
+XRE_SetupDllBlocklistType XRE_SetupDllBlocklist;
+#endif
+XRE_mainType XRE_main;
 
+static const nsDynamicFunctionLoad kXULFuncs[] = {
+    { "XRE_GetFileFromPath", (NSFuncPtr*) &XRE_GetFileFromPath },
+    { "XRE_CreateAppData", (NSFuncPtr*) &XRE_CreateAppData },
+    { "XRE_FreeAppData", (NSFuncPtr*) &XRE_FreeAppData },
+#ifdef XRE_HAS_DLL_BLOCKLIST
+    { "XRE_SetupDllBlocklist", (NSFuncPtr*) &XRE_SetupDllBlocklist },
+#endif
+    { "XRE_main", (NSFuncPtr*) &XRE_main },
+    { nsnull, nsnull }
+};
+
+static int do_main(const char *exePath, int argc, char* argv[])
+{
   nsCOMPtr<nsILocalFile> appini;
-  nsresult rv = XRE_GetBinaryPath(argv[0], getter_AddRefs(appini));
+#ifdef XP_WIN
+  // exePath comes from mozilla::BinaryPath::Get, which returns a UTF-8
+  // encoded path, so it is safe to convert it
+  nsresult rv = NS_NewLocalFile(NS_ConvertUTF8toUTF16(exePath), PR_FALSE,
+                                getter_AddRefs(appini));
+#else
+  nsresult rv = NS_NewNativeLocalFile(nsDependentCString(exePath), PR_FALSE,
+                                      getter_AddRefs(appini));
+#endif
   if (NS_FAILED(rv)) {
-    Output("Couldn't calculate the application directory.");
     return 255;
   }
+
   appini->SetNativeLeafName(NS_LITERAL_CSTRING("application.ini"));
 
   // Allow firefox.exe to launch XULRunner apps via -app <application.ini>
   // Note that -app must be the *first* argument.
-  char *appEnv = nsnull;
-  const char *appDataFile = PR_GetEnv("XUL_APP_FILE");
+  const char *appDataFile = getenv("XUL_APP_FILE");
   if (appDataFile && *appDataFile) {
     rv = XRE_GetFileFromPath(appDataFile, getter_AddRefs(appini));
     if (NS_FAILED(rv)) {
       Output("Invalid path found: '%s'", appDataFile);
       return 255;
     }
   }
   else if (argc > 1 && IsArg(argv[1], "app")) {
@@ -136,28 +165,87 @@ int main(int argc, char* argv[])
     }
 
     rv = XRE_GetFileFromPath(argv[2], getter_AddRefs(appini));
     if (NS_FAILED(rv)) {
       Output("application.ini path not recognized: '%s'", argv[2]);
       return 255;
     }
 
-    appEnv = PR_smprintf("XUL_APP_FILE=%s", argv[2]);
-    PR_SetEnv(appEnv);
+    char appEnv[MAXPATHLEN];
+    snprintf(appEnv, MAXPATHLEN, "XUL_APP_FILE=%s", argv[2]);
+    if (putenv(appEnv)) {
+      Output("Couldn't set %s.\n", appEnv);
+      return 255;
+    }
     argv[2] = argv[0];
     argv += 2;
     argc -= 2;
   }
 
   nsXREAppData *appData;
   rv = XRE_CreateAppData(appini, &appData);
   if (NS_FAILED(rv)) {
     Output("Couldn't read application.ini");
     return 255;
   }
 
   int result = XRE_main(argc, argv, appData);
   XRE_FreeAppData(appData);
-  if (appEnv)
-    PR_smprintf_free(appEnv);
   return result;
 }
+
+int main(int argc, char* argv[])
+{
+  char exePath[MAXPATHLEN];
+
+  nsresult rv = mozilla::BinaryPath::Get(argv[0], exePath);
+  if (NS_FAILED(rv)) {
+    Output("Couldn't calculate the application directory.\n");
+    return 255;
+  }
+
+  char *lastSlash = strrchr(exePath, XPCOM_FILE_PATH_SEPARATOR[0]);
+  if (!lastSlash || (lastSlash - exePath > MAXPATHLEN - sizeof(XPCOM_DLL) - 1))
+    return 255;
+
+  strcpy(++lastSlash, XPCOM_DLL);
+
+#ifdef XP_WIN
+  // GetProcessIoCounters().ReadOperationCount seems to have little to
+  // do with actual read operations. It reports 0 or 1 at this stage
+  // in the program. Luckily 1 coincides with when prefetch is
+  // enabled. If Windows prefetch didn't happen we can do our own
+  // faster dll preloading.
+  IO_COUNTERS ioCounters;
+  if (GetProcessIoCounters(GetCurrentProcess(), &ioCounters)
+      && !ioCounters.ReadOperationCount)
+#endif
+  {
+      XPCOMGlueEnablePreload();
+  }
+
+
+  rv = XPCOMGlueStartup(exePath);
+  if (NS_FAILED(rv)) {
+    Output("Couldn't load XPCOM.\n");
+    return 255;
+  }
+
+  rv = XPCOMGlueLoadXULFunctions(kXULFuncs);
+  if (NS_FAILED(rv)) {
+    Output("Couldn't load XRE functions.\n");
+    return 255;
+  }
+
+#ifdef XRE_HAS_DLL_BLOCKLIST
+  XRE_SetupDllBlocklist();
+#endif
+
+  int result;
+  {
+    ScopedLogging log;
+    result = do_main(exePath, argc, argv);
+  }
+
+  XPCOMGlueShutdown();
+  return result;
+}
--- a/browser/base/content/aboutDialog.css
+++ b/browser/base/content/aboutDialog.css
@@ -16,16 +16,19 @@
 
 #bottomBox {
   padding: 15px 10px 0;
 }
 
 #version {
   margin-top: 10px;
   -moz-margin-start: 0;
+  -moz-user-select: text;
+  -moz-user-focus: normal;
+  cursor: text;
 }
 
 #distribution,
 #distributionId {
   font-weight: bold;
   display: none;
   margin-top: 0;
   margin-bottom: 0;
--- a/browser/base/content/aboutDialog.js
+++ b/browser/base/content/aboutDialog.js
@@ -65,17 +65,17 @@ function init(aEvent)
     // Pref is unset
   }
 
   // Include the build ID if this is an "a#" (nightly or aurora) build
   let version = Services.appinfo.version;
   if (/a\d+$/.test(version)) {
     let buildID = Services.appinfo.appBuildID;
     let buildDate = buildID.slice(0,4) + "-" + buildID.slice(4,6) + "-" + buildID.slice(6,8);
-    document.getElementById("version").value += " (" + buildDate + ")";
+    document.getElementById("version").textContent += " (" + buildDate + ")";
   }
 
 #ifdef MOZ_OFFICIAL_BRANDING
   // Hide the Charlton trademark attribution for non-en-US/en-GB
   // DO NOT REMOVE without consulting people involved with bug 616193
   let chromeRegistry = Components.classes["@mozilla.org/chrome/chrome-registry;1"].
                        getService(Components.interfaces.nsIXULChromeRegistry);
   let currentLocale = chromeRegistry.getSelectedLocale("global");
--- a/browser/base/content/aboutDialog.xul
+++ b/browser/base/content/aboutDialog.xul
@@ -71,17 +71,17 @@
         >
 
   <script type="application/javascript" src="chrome://browser/content/aboutDialog.js"/>
 
   <vbox id="aboutDialogContainer">
     <hbox id="clientBox">
       <vbox id="leftBox" flex="1"/>
       <vbox id="rightBox" flex="1">
-#expand <label id="version" value="__MOZ_APP_VERSION__"/>
+#expand <label id="version">__MOZ_APP_VERSION__</label>
         <label id="distribution" class="text-blurb"/>
         <label id="distributionId" class="text-blurb"/>
 
         <vbox id="detailsBox" aria-describedby="communityDesc contributeDesc">
           <vbox id="updateBox">
 #ifdef MOZ_UPDATER
             <deck id="updateDeck" orient="vertical">
               <hbox id="updateButtonBox" align="center">
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..22a260da2c5838e2547dc40464fc22c599113881
GIT binary patch
literal 1866
zc$@)B2etT#P)<h;3K|Lk000e1NJLTq001Ze001%w1^@s6F0+}C000LONkl<ZcwWtx
zYiv|S6vxlq-4+U}0Kq5<)$qX&n4nQjFws~LM2$vCl=wl!5J41!L?EJ2iuFUI5+N8~
zCLpDVKvPtaNReO)6qFXAu>gfWwy)i7yW8DuxBI$xuIJ9o?%dtG>Ajmm<uw1ybUSnQ
zH)rNQ9UI){F(}|$<*hSNi%^?U+i!tBM=d~2$O=%KfU3ssanyFyQq-bbpf6FoQ0-bF
zECZ^lx&<{I1;eCV)Rs5*UVq9Ia8Aje_o@J|qkxJLgOn7x3Bs%@%dYz#JJ@UsO#zYU
zag?3YCBXzF3{hgiKv-W?0;XFr$+$%6Aw|Sg`FA^D@ss0WlmiAGC!s`6-BuHFk13$4
z#P8xu;u8g|O0Xp)lMpTk))Y*HXCJx~+xr+~=CKGO;HV&}JX1g=9&@B_FJCcH#mdu^
zKPDH}%(x#$<+617V@I&xbEJ&pGv}e^luQ8$QEV!RA2SC|*5GD7z~Mw7B>g-OAv4ZR
z15EswZ!sZ~I4&x0#TE-OxV6tu(!&`b*Up>-c@9a;6B4lEh?@fnONrI7M%9ab`78sR
z5po<Kmtz}rCjd}cT+~dWZ-kpY2}bAI!Ad+hZX}LRg%s`uy_2m03Q!bpxe#t76uvOo
zGMs><^AOUm&&SM>)nh@N2XXFLi*6kO>*ff!7Edp%-*XK9y408v>W9i2*jRBA{Qcns
zB%MFXVM{%SB&#!MbTII3EqW<GrE&$IY=xrIN+?*djl$~V=jwWR_v`(zeCw}N`brkP
zn4h}cV8z8opKw4-ig4=%TvGl}MD$sejK7P%fE>>tN9WiDB;zy#<ZNjN_>IRVK(jYO
zrH@@J=fQK+ra;mB+3@I;iJ*@Kv!8&E=RO0kJv|lH;oo&Z^MqmwygYTRxGXH2MDGd?
zT2kqRwZApN&gxD*1O4(7-@Fg&-kt@S;@c&!!lCsG4DgtT=KHC(EB(T@c+H4P8kB8V
z$}c|4{vIUQQW*iMd!<<`&6FvBdS0troc_Y19o{zr@~umk=@@=(iTqTwYt_Z+6GdMi
zWA4bKMi?xX8UC&}gaFIp4C+hHSE;*H(*q4coy;TM$y8}!e28SV#X_`WcpibVis)o|
z<sb}&#Wwj_S{RGK`qoWie4|-&F+x!w4n{#UhjGzji;0B_DkRk;Y45h7M|xgJLK0cA
z02q&^99TA=b=-j{l%44qvM>+N%LN=V7BvTy!y!VHINw}8nYZp>1WK#hQEgCqI(y+<
zDo>CCvXI0RMeYj_a~BiRAM?1_agZdMK}}|n#B+?csuhV!@p1_`O2@W08Uxwa-De6I
z8wfPZ{vL>SHshoSj<BH+GSO0I(|?JES2+u9zJ!g9<>i2KzzY#)11NH|%@nYu`e2=^
z5}y+EL!|jCgc~kF)Oii$9v1?N#Iy?5;rPNNwn!xgv5qDPH~tF)4RsK6wSp?gAr=Z$
znF9J+>LLT)_KhHdPFDJQLH4?lO#{?H3dg64f5wJTI<`0jj=NidM8mW%ZV$P=`SgJw
zO#xBy+P!P`2VFOoqgfjCpi0n(pgyrZ65sO7TP<85F*pfZxx1Y%ScDphhx>kMtlB%T
z=f*jo6~HJ;xp?4<Bd5Mw_)68L`48jD3i`WRR%?t{MNHWbl0CzA3nkd-nUic19WVR4
zfP_PU3%}yIa%%3m-76od+Vsw}Gdn(9)meAE2LM8*fIL4A7SUF7xbytJ!itc$y_lBR
zqg5fMeX*#dn9g8zaDZ?m6a)p$r=4%-*+U;(tK3l^_IvcD)cOG{fWQa3ST#k|mVLG_
z+UMN?DuKAmiH*W5DKTkKAfTm$sc<oJcZY@@_cdKurY$(FAVE|cikJfm^`V@o22>Nu
zje@^-F5e(W2abUvgW`6w<8QY!^VsZ3r%PHNrPWq;w^Bn4_*`GrAKvs2UwA9(Iu*+;
zqre)VQ8Hg;7YgbsN>&g#R;R|XGM-jeDTHKTTz0KRQ*^aaQ=kzlYW93us(B67fr_L*
zV9Wu{<wyC@Fp=vgb}v>H*{Mdup!9TLvFucmPNdg^h8h4|Og);ekOOt<t97#hfg7mb
zbNQsN?fjAVv_r3=0Z5<=BnLt|9JD3<ejq^~HAQoE`4VafHaCodTL}o<K#`W}a%cCo
zvx@=iM9`rK#EcTfs(D@16yC<#r5zXk@NgsaqF^`xRep}*SC4M1!%KY?U?3EQR6K3W
z6yDB~%fD}~<>yU<gkb^XQc&&eQZGJ=Teu+ssX0785G=1LTV2M-b)wYa0~Ct$N~-u@
zVMi?F-$x<k*oBJ+i;Ik=7=A$D+vnyNc`-iM_M<75aZ_{)Qw%qt@lx-JNBWhs-+xrd
zO%dSN68yh_LOvZ(Byp+VPJqCn0>Tux6QGbsm}2PhADS<~&U=8j8~^|S07*qoM6N<$
Ef@x4__W%F@
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..e0724fb6df5bbf0a601af72a82d60d942b99d939
GIT binary patch
literal 3287
zc$@*(3@G!7P)<h;3K|Lk000e1NJLTq001Ze001%w1^@s6F0+}C000c0Nkl<ZcwX(9
z3vgBSoyR}tb#HQS9wa0o1VF-5AcR+W8mqk2N>^oZwQJXQtfFYAzPjL!wWD<{R&*;4
zx^}A;ZL`%WENx0bTA&LEAR)xW1jv&lH{6@#zTdC&+L=3!D@2eibnDFScjnHyGiT=B
z&wPIKKfm9cpU9Uy{|^YT;r`i0dw;%aziFDa2i|+Q@=FKk568FH>}b92*Bib$PYv}n
zZdfz>%`X+8w?95Q7PIok+xz*KSC0}+sP}&V&M8$_3{X$C<Y<YH*7mmjb_7GrgH>au
zjVT;izI5q4@^Tcq93cig5kx^Wt{kAQbf(hw*HcNgfA6+uZf6LwDB_NaITZ{z-9*A+
z>~;&HDBS`axh%j`w0XUuM@s-AVI$w?Is<Vpf@E&3-uys0myoqf$`_|JX}rtfrlGMB
zQxFi~Ah6@I4vF7&Xk{Xnd?6AFZUI0~JgBD=gnTZF?Iwb0JbMWz_x5EsO+WD951+v8
zb>i#~Vi+cdW<JPg@{@<|TL0)bZng~xu;cKXk9b-S;OlR>dBD|L4s6kNZ9q3=;*kg=
zOYF1wg2a-k>iO4RFOQpC!1XtbVQNJQZf~jyI0dlrr_T@j#d8nzynnReh0~o5%a8yK
z-JBYY1sGm3mbwGKs;z$QsW&@Y>x%?Q!5>L8bLvEsFUaBrGnBEFt4VvEw70m)&zG1r
zBj;U!=YI0g;y_p(IMa1@Y-ygs{7L!Ap#jSFepAdQ>T@!!qN-@-f~tE<%O*?FSR4c^
zlEqffXA*Tcj`6i^e<R^-JDup+6Y8sbBRaM6E8;-spQ*1sh|?P(98EELOu>no+D&pK
zo;uw4!7j^`0-a?uMj0cAWu=D%C@OhRBiTu*8U<yunKElRnw}=Dn%Hvk*|U3BfKQSP
z_cqAZydImq;6CGQ&DEOcL>^kmo@Itm(hd?yaQi|;qw$x4KaINTtG^NDI8nb3w?B%e
zN27o-)Kk1mlI`1NYd)G9ClYj%N@<9K6^kX8XiR<NkMI6qn2`#&m7LO<7Hffkw~?OM
zFn0Rpv88P`8+PZh>8&~{rkAkd+L>|SaR4oyy45apGHX#j#W@~E6?xbGPdmwKK@_jo
z4P&pCHVyPNM#_U{pqujPRe}~d>q*C*#ey0~b?l-wm`!u;-yoIEWYqYHjGXgzI*K3S
z+1HzxQ(0_#V%=@CpL=K9=J46QqD7YQI$UI1qaonk%jqNsfEB4!?59aJK{%NtsU=Vi
zg|L<<d%EjLcWuY%>Od=7!Scz&nK42}mNfEnBqmHNCp7k6w%0VHCla-$DzDXi$1w~W
zU8i~w73-QS)r;4KU4At?n4my3Fv1RUhfkoTsS#E65;BJ~eq=G(A}ErGtO!V=fko6A
zRz8QeU_REuiL#!km#vCGPjeTENFWAmy;6YW<MHjT*~9LC|0BnK^LrA`4qWj(Tuvu8
z#g37TF%a?*NG8d)h$xDHB7;SNWXVECOkF~<Zy##fr0IitipI|T;br&YKfm+jnEqpL
zFKei&j^-AbrDJDTGHvN~hy^+5l1WxhDfOqr6lgxuzD{D{0BJRaqJS)dMG{EGA}qb_
zF04``k{+Y8DafqV>#1D+_)E8b|5v_6x7`2YU2E@{J7mDOUwh&1ISa-+>W?<;?d)l`
zmrR<^x>vSw_xGM;{PYRr=2{R;a3xCcwlpIJx`>5+Xle>kl96RO(|dDsZQMFHO!Djj
zKHTFacfuW1E_sM>uwLB!v+Bay0|)<cpzm~D_km|_zGT2$%ZRzxEv$S?k+PULEuZ@y
z`3FXnP9fP<L;a2yd8c{@s;`Y=OD}$Zihb=Vw5ShJG%-X0Q&-W`F#^5-3#Z8Bn8*3J
z)<<i5lCsh?!G=w=YS(Zw|55(+kd=lH8}a)cZ+{_R>z>zaN2;HC@70$!*Zu639m<dY
zxtdrwLg}c<xH}Hx7>FU3RB`pxs~K57ky4uzHPFQe?ICK8b&yiQd$x<7mXB#`K8e@S
z%8Hp0I_eJbyIn4H(j>f{wDjpLT(p!MW*1Vr-~n7d6L+t-_`Sz(>aBicS;YkbMUich
zp!d%1P7fbCRPyt(m{K`|$bf^eIFZTMJcvEl#{2~fIef&)n{OQ?5pi<5tCwK!8M<mV
zF(z_~W#v#+7UFAjt%#9B{O8_Y@~k;z%M!78l&qXATAgVU$rxGoTt<v3;dq^sqaU}9
zZfxzYzkhLwJP5FP=S!AkB6`EbiV9xc@?%ylo5hh+UV@=0;b@2v6Rx4ZWhbw1SkLyF
zT{!#wgvlqKNbucj3n@(XF>mGV%wPFEa+B@ME$N`D_yoQ6?T8T(DH-ADu~wQJ9pur&
z!P<QsI~_pp*-6apC*ld?^9Se~@G4e|vT_ihAd1TcL6l<QFzI-LA3eQ>`|tcZzutC&
z-~FM1?xtfj*VWPPh@p~&E0oF%0ITMVCJ_iRY~onTCru#L`UZ7<3NL<i9qWIo(tkEU
z@u*x5?r*`-7+~+dM#8}`X2UP&JG7DU;ls2xbkNn~L^lj976n<Bo*E1&2rqteMO9S-
z9xpfEu#h`$tfIpa<hzfpXUF@;sGPHiq+#J?YdbejEvDtPi*9d-DHUZz&g`elr=gYK
z%joG<D3xpYk2;aEQW?Ky;gAl$-S6O@bvtl&b}&;tL3=|Zz5QM+Sr$Z5#57H0Nt*l2
zZCB@f3V3SwD@7no<Gcj?0c>^)>+W00->;a%?++g5ot;N%>gwa~zA_4z%gu?FZj!o+
zRT6M?cM{J3DobYCnKHJ3vZ7M#BWI8ZCvn&;=s=$)GirDdd8r89Jsy&}iPfs`NiYG^
zG=*GS)|yWN1yOpQ!O7T6r&WT%Ah+E(o9!FF&6LskxIH1x^z>8v@fj8^oW*z6ehrs1
zz^Jm}IOEwg`5+uh5sIZ5nV-NhpyTe3QC3pG)2l0)S!B}h2_Q%kk|<(wZVb~PJ1gti
z&z5+N2^trSfX5p|ktBY(;clM1dkMQ50yw<}lgfwFxc?-FkF=0fgP2`g*?ZW>$L)SJ
z-*NQbTK;WEBUP1Sczk&|Ax|IfU>rq}I6vmOUvkgyBnqP75CjoXR6f^cBALSP^>gp)
z`E1?vEsDmCX5Gv0)9DCv?06?NJKKn!+)waN598eTPsBcWo|A13ZmJl^s;N2jy4<8R
z0Z9`1yhwmym^vU_sFPe35BZ7t2aqim5QOs}!36r;e)4S=UVid#S-oN&2V43uZH4^2
z`WWx+Zs%<C5ju|jfh;}Ewc|>WlObHb7=k1s3}!<V00ELZ0P;m!oo(3g%oOc&oI#Wn
zL{S=415pr&C)4=-VZM3GEH*xR3%-a(Q(uJlYdhKB<YU!>8O$!p!t3*(A|OcuCW9l(
zkk-H-6G-Wo(2GsOB(JCxMFG#5Hqwb0vTPk(asa^NjbgXLJ5R6V8_O!GoKVUu_gq7P
zki-*8AW9OzIdCQ*2_TE$jhMJXpc^0xmpClws*2T?LvFr}aG#5y+l3^{nLj&UgOIVQ
z5sjv~=eh~pzjzF!5(JZK#@hLC0$^1jshPC9H3p(4f|!9D+PGyH2Brx)g?6-f98Xsd
z>0}ZqV{<Sh0-S7fa;DEuTs4q|!R8bZBvIgOK%=EkBd%sFB3#ZyZRiGBHY?dykw||(
zLARTXP4QFtNU}sI6ek)@qUr|WNCH_F&UtKDWRbXPa@v)m*RLUFVBzvdelv6QK@hOz
zW}&CzczgR%H62-&05elc-#`d6V-tLlM8>LVf+PqivWO?Fa>|(?mNu}+!ezZ-?Y^*0
zlWbcSwk(P8fQOJjoUsSsb_cO!%z{6XK-UbiEfT5$t<D%70|_#)7gwTQ3Sha3`2=8G
z2og~wcbE-RRS66P=|AhwJj6v&L=Z&MszxxL#vM-5)Dt8a)3C}S!o|fM1)=a#OS};n
z4|HD8re>0Dw~&*kU}`E>Mb4BRflNu;odMdNApjIv_#$g}0E>a>P!35CFcH{vv634)
zl#~@PqjDVfY)j@)0T_UkF?vzBPM{FjdO2%|$ACFN08BnF>6AvcO<~dENn~ebAiwB`
zb>Ih|2#8*ZHN;0iA@CBI=I4Q`X#+tJGZT+t7+fUHKq;`{FR_ML2UGwaFgf=FrfFc9
z0K%vDK66_K9tLIr-oNCY<P=Z>R9|44W3XZRfUAJb|C_6@yMb$g#D8;{3=W%sGQj!Q
z*wq~Za)2$I7Xi9~DZpcY?Pa0?d<U2>2tph{5cv^M4zzulww=cTJ0Jkh{GZtu{}<^&
V0dzR3C*%MC002ovPDHLkV1n%yJ|zGE
--- a/browser/base/content/aboutHome.css
+++ b/browser/base/content/aboutHome.css
@@ -249,16 +249,36 @@ body[dir=rtl] #searchSubmit:active {
 }
 
 #snippets:hover:active {
   background-color: rgb(210,210,210);
   box-shadow: 0 2px 3px rgba(0,0,0,.3) inset,
               0 1px 0 rgba(255,255,255,.5);
 }
 
+#defaultSnippet1,
+#defaultSnippet2 {
+  display: table-row;
+  text-align: start;
+}
+
+#defaultSnippet1::before,
+#defaultSnippet2::before {
+  display: table-cell;
+  vertical-align: middle;
+  -moz-padding-end: 1em;
+}
+
+#defaultSnippet1::before {
+  content: url("chrome://browser/content/aboutHome-snippet1.png");
+}
+#defaultSnippet2::before {
+  content: url("chrome://browser/content/aboutHome-snippet2.png");
+}
+
 #sessionRestoreContainer {
   padding-top: 1.5%;
   text-align: center;
 }
 
 @media all and (max-height: 370px) {
   #sessionRestoreContainer {
     position: relative;
--- a/browser/base/content/aboutHome.js
+++ b/browser/base/content/aboutHome.js
@@ -136,18 +136,18 @@ const SEARCH_ENGINES = {
 };
 
 // The process of adding a new default snippet involves:
 //   * add a new entity to aboutHome.dtd
 //   * add a <span/> for it in aboutHome.xhtml
 //   * add an entry here in the proper ordering (based on spans)
 // The <a/> part of the snippet will be linked to the corresponding url.
 const DEFAULT_SNIPPETS_URLS = [
-  "http://www.mozilla.com/firefox/4.0/features"
-, "https://addons.mozilla.org/firefox/?src=snippet"
+  "http://www.mozilla.com/firefox/features/?WT.mc_ID=default1"
+, "https://addons.mozilla.org/firefox/?src=snippet&WT.mc_ID=default2"
 ];
 
 const SNIPPETS_UPDATE_INTERVAL_MS = 86400000; // 1 Day.
 
 let gSearchEngine;
 
 function onLoad(event)
 {
--- a/browser/base/content/aboutHome.xhtml
+++ b/browser/base/content/aboutHome.xhtml
@@ -82,18 +82,18 @@
           <input id="searchSubmit" type="submit" value="&abouthome.searchEngineButton.label;" />
         </div>
       </form>
     </div>
 
     <div id="contentContainer">
       <div id="snippetContainer">
         <div id="defaultSnippets" hidden="true">
-          <span>&abouthome.defaultSnippet1.v1;</span>
-          <span>&abouthome.defaultSnippet2.v1;</span>
+          <span id="defaultSnippet1">&abouthome.defaultSnippet1.v1;</span>
+          <span id="defaultSnippet2">&abouthome.defaultSnippet2.v1;</span>
         </div>
         <div id="snippets"/>
       </div>
 
       <div id="sessionRestoreContainer">
         <button id="restorePreviousSession">&historyRestoreLastSession.label;</button>
       </div>
     </div>
--- a/browser/base/content/browser-menubar.inc
+++ b/browser/base/content/browser-menubar.inc
@@ -381,16 +381,17 @@
                           label="&showAllHistoryCmd2.label;"
 #ifndef XP_MACOSX
                           key="showAllHistoryKb"
 #endif
                           command="Browser:ShowAllHistory"/>
                 <menuseparator id="showAllHistorySeparator"/>
 #ifdef MOZ_SERVICES_SYNC
                 <menuitem id="sync-tabs-menuitem"
+                          class="syncTabsMenuItem"
                           label="&syncTabsMenu.label;"
                           oncommand="BrowserOpenSyncTabs();"
                           disabled="true"/>
 #endif
                 <menuitem id="historyRestoreLastSession"
                           class="restoreLastSession"
                           label="&historyRestoreLastSession.label;"
                           oncommand="restoreLastSession();"
--- a/browser/base/content/browser-places.js
+++ b/browser/base/content/browser-places.js
@@ -654,18 +654,21 @@ HistoryMenu.prototype = {
     m.setAttribute("label", gNavigatorBundle.getString("menuRestoreAllWindows.label"));
     m.setAttribute("oncommand",
       "for (var i = 0; i < " + undoItems.length + "; i++) undoCloseWindow();");
   },
 
   toggleTabsFromOtherComputers: function PHM_toggleTabsFromOtherComputers() {
     // This is a no-op if MOZ_SERVICES_SYNC isn't defined
 #ifdef MOZ_SERVICES_SYNC
-    // enable/disable the Tabs From Other Computers menu
-    let menuitem = document.getElementById("sync-tabs-menuitem");
+    // Enable/disable the Tabs From Other Computers menu. Some of the menus handled
+    // by HistoryMenu do not have this menuitem.
+    let menuitem = this._rootElt.getElementsByClassName("syncTabsMenuItem")[0];
+    if (!menuitem)
+      return;
 
     // If Sync isn't configured yet, then don't show the menuitem.
     if (Weave.Status.checkSetup() == Weave.CLIENT_NOT_CONFIGURED ||
         Weave.Svc.Prefs.get("firstSync", "") == "notReady") {
       menuitem.setAttribute("hidden", true);
       return;
     }
 
--- a/browser/base/content/browser-tabview.js
+++ b/browser/base/content/browser-tabview.js
@@ -350,33 +350,31 @@ let TabView = {
         event.preventDefault();
 
         self._initFrame(function() {
           let groupItems = self._window.GroupItems;
           let tabItem = groupItems.getNextGroupItemTab(event.shiftKey);
           if (!tabItem)
             return;
 
-          // Switch to the new tab, and close the old group if it's now empty.
-          let oldGroupItem = groupItems.getActiveGroupItem();
+          // Switch to the new tab
           window.gBrowser.selectedTab = tabItem.tab;
-          oldGroupItem.closeIfEmpty();
         });
       }
     }, true);
   },
 
   // ----------
   // Prepares the tab view for undo close tab.
   prepareUndoCloseTab: function(blankTabToRemove) {
     if (this._window) {
       this._window.UI.restoredClosedTab = true;
 
-      if (blankTabToRemove)
-        blankTabToRemove._tabViewTabIsRemovedAfterRestore = true;
+      if (blankTabToRemove && blankTabToRemove._tabViewTabItem)
+        blankTabToRemove._tabViewTabItem.isRemovedAfterRestore = true;
     }
   },
 
   // ----------
   // Cleans up the tab view after undo close tab.
   afterUndoCloseTab: function () {
     if (this._window)
       this._window.UI.restoredClosedTab = false;
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -4361,20 +4361,16 @@ var XULBrowserWindow = {
           this.throbberElement.removeAttribute("busy");
 
         this.stopCommand.setAttribute("disabled", "true");
         CombinedStopReload.switchToReload(aRequest instanceof Ci.nsIRequest);
       }
     }
   },
 
-  onLocationChange2: function (aWebProgress, aRequest, aLocationURI, aFlags) {
-    onLocationChange(aWebProgress, aRequest, aLocationURI);
-  },
-
   onLocationChange: function (aWebProgress, aRequest, aLocationURI) {
     var location = aLocationURI ? aLocationURI.spec : "";
     this._hostChanged = true;
 
     // Hide the form invalid popup.
     if (gFormSubmitObserver.panelIsOpen()) {
       gFormSubmitObserver.panel.hidePopup();
     }
@@ -5092,16 +5088,20 @@ var TabsInTitlebar = {
       if (!(condition in this._disallowed)) {
         this._disallowed[condition] = null;
         this._update();
       }
     }
 #endif
   },
 
+  get enabled() {
+    return document.documentElement.getAttribute("tabsintitlebar") == "true";
+  },
+
 #ifdef CAN_DRAW_IN_TITLEBAR
   observe: function (subject, topic, data) {
     if (topic == "nsPref:changed")
       this._readPref();
   },
 
   _initialized: false,
   _disallowed: {},
@@ -5117,18 +5117,17 @@ var TabsInTitlebar = {
       return;
 
     let allowed = true;
     for (let something in this._disallowed) {
       allowed = false;
       break;
     }
 
-    let docElement = document.documentElement;
-    if (allowed == (docElement.getAttribute("tabsintitlebar") == "true"))
+    if (allowed == this.enabled)
       return;
 
     function $(id) document.getElementById(id);
     let titlebar = $("titlebar");
 
     if (allowed) {
       function rect(ele)   ele.getBoundingClientRect();
 
@@ -5139,30 +5138,28 @@ var TabsInTitlebar = {
       this._sizePlaceholder("appmenu-button", rect(appmenuButtonBox).width);
       this._sizePlaceholder("caption-buttons", rect(captionButtonsBox).width);
 
       let tabsToolbarRect = rect(tabsToolbar);
       let titlebarTop = rect($("titlebar-content")).top;
       titlebar.style.marginBottom = - Math.min(tabsToolbarRect.top - titlebarTop,
                                                tabsToolbarRect.height) + "px";
 
-      docElement.setAttribute("tabsintitlebar", "true");
+      document.documentElement.setAttribute("tabsintitlebar", "true");
 
       if (!this._draghandle) {
         let tmp = {};
         Components.utils.import("resource://gre/modules/WindowDraggingUtils.jsm", tmp);
         this._draghandle = new tmp.WindowDraggingElement(tabsToolbar, window);
         this._draghandle.mouseDownCheck = function () {
-          return !this._dragBindingAlive &&
-                 this.ownerDocument.documentElement
-                     .getAttribute("tabsintitlebar") == "true";
+          return !this._dragBindingAlive && TabsInTitlebar.enabled;
         };
       }
     } else {
-      docElement.removeAttribute("tabsintitlebar");
+      document.documentElement.removeAttribute("tabsintitlebar");
 
       titlebar.style.marginBottom = "";
     }
   },
 
   _sizePlaceholder: function (type, width) {
     Array.forEach(document.querySelectorAll(".titlebar-placeholder[type='"+ type +"']"),
                   function (node) { node.width = width; });
--- a/browser/base/content/syncQuota.js
+++ b/browser/base/content/syncQuota.js
@@ -88,17 +88,17 @@ let gSyncQuota = {
   onAccept: function onAccept() {
     let engines = gUsageTreeView.getEnginesToDisable();
     for each (let engine in engines) {
       Weave.Engines.get(engine).enabled = false;
     }
     if (engines.length) {
       // The 'Weave' object will disappear once the window closes.
       let Service = Weave.Service;
-      Weave.Utils.delay(function() Service.sync(), 0);
+      Weave.Utils.nextTick(function() { Service.sync(); });
     }
     return true;
   },
 
   convertKB: function convertKB(value) {
     return DownloadUtils.convertByteUnits(value * 1024);
   }
 
--- a/browser/base/content/syncSetup.js
+++ b/browser/base/content/syncSetup.js
@@ -67,16 +67,17 @@ Cu.import("resource://gre/modules/Servic
 Cu.import("resource://gre/modules/PlacesUtils.jsm");
 Cu.import("resource://gre/modules/PluralForm.jsm");
 
 var gSyncSetup = {
   QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports,
                                          Ci.nsIWebProgressListener,
                                          Ci.nsISupportsWeakReference]),
 
+  haveCaptcha: true,
   captchaBrowser: null,
   wizard: null,
   _disabledSites: [],
 
   status: {
     password: false,
     email: false,
     server: false
@@ -138,16 +139,17 @@ var gSyncSetup = {
                                            .getAttribute("accesskey");
   },
 
   startNewAccountSetup: function () {
     if (!Weave.Utils.ensureMPUnlocked())
       return false;
     this._settingUpNew = true;
     this.wizard.pageIndex = NEW_ACCOUNT_START_PAGE;
+    this.loadCaptcha();
   },
 
   useExistingAccount: function () {
     if (!Weave.Utils.ensureMPUnlocked())
       return false;
     this._settingUpNew = false;
     this.wizard.pageIndex = EXISTING_ACCOUNT_CONNECT_PAGE;
   },
@@ -266,18 +268,19 @@ var gSyncSetup = {
         let hasUser = document.getElementById("existingAccountName").value != "";
         let hasPass = document.getElementById("existingPassword").value != "";
         let hasKey = document.getElementById("existingPassphrase").value != "";
 
         if (hasUser && hasPass && hasKey) {
           if (this._usingMainServers)
             return true;
 
-          if (this._validateServer(document.getElementById("existingServer"), false))
+          if (this._validateServer(document.getElementById("existingServer"))) {
             return true;
+          }
         }
         return false;
     }
     // Default, e.g. wizard's special page -1 etc.
     return true;
   },
 
   onEmailInput: function () {
@@ -360,16 +363,21 @@ var gSyncSetup = {
         break;
       case NEW_ACCOUNT_PP_PAGE:
         document.getElementById("saveSyncKeyButton").focus();
         let el = document.getElementById("weavePassphrase");
         if (!el.value)
           this.onPassphraseGenerate();
         this.checkFields();
         break;
+      case NEW_ACCOUNT_CAPTCHA_PAGE:
+        if (!this.haveCaptcha) {
+          gSyncSetup.wizard.advance();
+        }
+        break;
       case NEW_ACCOUNT_START_PAGE:
         this.wizard.getButton("extra1").hidden = false;
         this.wizard.getButton("next").hidden = false;
         this.wizard.getButton("back").hidden = false;
         this.onServerCommand();
         this.wizard.canRewind = true;
         this.checkFields();
         break;
@@ -473,22 +481,16 @@ var gSyncSetup = {
           this._handleNoScript(false);
           this.wizard.pageIndex = SETUP_SUCCESS_PAGE;
           return false;
         }
 
         image.setAttribute("status", "error");
         label.value = Weave.Utils.getErrorString(error);
         return false;
-      case NEW_ACCOUNT_PP_PAGE:
-        // Time to load the captcha.
-        // First check for NoScript and whitelist the right sites.
-        this._handleNoScript(true);
-        this.captchaBrowser.loadURI(Weave.Service.miscAPI + "captcha_html");
-        break;
       case EXISTING_ACCOUNT_LOGIN_PAGE:
         Weave.Service.account = Weave.Utils.normalizeAccount(
           document.getElementById("existingAccountName").value);
         Weave.Service.password = document.getElementById("existingPassword").value;
         let pp = document.getElementById("existingPassphrase").value;
         Weave.Service.passphrase = Weave.Utils.normalizePassphrase(pp);
         if (Weave.Service.login())
           this.wizard.pageIndex = SETUP_SUCCESS_PAGE;
@@ -548,19 +550,16 @@ var gSyncSetup = {
       Weave.Service.persistLogin();
       Weave.Svc.Obs.notify("weave:service:setup-complete");
       if (this._settingUpNew)
         gSyncUtils.openFirstClientFirstrun();
       else
         gSyncUtils.openAddedClientFirstrun();
     }
 
-    if (!Weave.Service.isLoggedIn)
-      Weave.Service.login();
-
     Weave.Service.syncOnIdle(1);
   },
 
   onWizardCancel: function () {
     if (this._resettingSync)
       return;
 
     if (this.wizard.pageIndex == SETUP_SUCCESS_PAGE) {
@@ -710,16 +709,19 @@ var gSyncSetup = {
       control.value = "";
       control.inputField.focus();
       // checkServer() will call checkAccount() and checkFields().
       this.checkServer();
       return;
     }
     control.removeAttribute("editable");
     Weave.Svc.Prefs.reset("serverURL");
+    if (this._settingUpNew) {
+      this.loadCaptcha();
+    }
     this.checkAccount();
     this.status.server = true;
     document.getElementById("serverFeedbackRow").hidden = true;
     this.checkFields();
   },
 
   onServerInput: function () {
     // Check custom server validity when the user stops typing for 1 second.
@@ -732,61 +734,63 @@ var gSyncSetup = {
 
   checkServer: function () {
     delete this._checkServerTimer;
     let el = document.getElementById("server");
     let valid = false;
     let feedback = document.getElementById("serverFeedbackRow");
     let str = "";
     if (el.value) {
-      valid = this._validateServer(el, true);
+      valid = this._validateServer(el);
       let str = valid ? "" : "serverInvalid.label";
       this._setFeedbackMessage(feedback, valid, str);
     }
     else
       this._setFeedbackMessage(feedback, true);
 
     // Recheck account against the new server.
     if (valid)
       this.checkAccount();
 
     this.status.server = valid;
     this.checkFields();
   },
 
-  // xxxmpc - checkRemote is a hack, we can't verify a minimal server is live
-  // without auth, so we won't validate in the existing-server case.
-  _validateServer: function (element, checkRemote) {
+  _validateServer: function (element) {
     let valid = false;
     let val = element.value;
     if (!val)
       return false;
 
     let uri = Weave.Utils.makeURI(val);
 
     if (!uri)
       uri = Weave.Utils.makeURI("https://" + val);
 
-    if (uri && checkRemote) {
+    if (uri && this._settingUpNew) {
       function isValid(uri) {
         Weave.Service.serverURL = uri.spec;
         let check = Weave.Service.checkAccount("a");
         return (check == "available" || check == "notAvailable");
       }
 
       if (uri.schemeIs("http")) {
         uri.scheme = "https";
         if (isValid(uri))
           valid = true;
         else
           // setting the scheme back to http
           uri.scheme = "http";
       }
       if (!valid)
         valid = isValid(uri);
+
+      if (valid) {
+        this.loadCaptcha();
+      }
     }
     else if (uri) {
       valid = true;
       Weave.Service.serverURL = uri.spec;
     }
 
     if (valid)
       element.value = Weave.Service.serverURL;
@@ -944,28 +948,44 @@ var gSyncSetup = {
       } catch(e) {}
 
       if (!str)
         str = Weave.Utils.getErrorString(string);
     }
     this._setFeedback(element, success, str);
   },
 
+  loadCaptcha: function loadCaptcha() {
+    // First check for NoScript and whitelist the right sites.
+    this._handleNoScript(true);
+    this.captchaBrowser.loadURI(Weave.Service.miscAPI + "captcha_html");
+  },
+
   onStateChange: function(webProgress, request, stateFlags, status) {
     // We're only looking for the end of the frame load
     if ((stateFlags & Ci.nsIWebProgressListener.STATE_STOP) == 0)
       return;
     if ((stateFlags & Ci.nsIWebProgressListener.STATE_IS_NETWORK) == 0)
       return;
     if ((stateFlags & Ci.nsIWebProgressListener.STATE_IS_WINDOW) == 0)
       return;
 
     // If we didn't find the captcha, assume it's not needed and move on
-    if (request.QueryInterface(Ci.nsIHttpChannel).responseStatus == 404)
-      this.onWizardAdvance();
+    if (request.QueryInterface(Ci.nsIHttpChannel).responseStatus == 404) {
+      this.haveCaptcha = false;
+      // Hide the browser just in case we end up displaying the captcha page
+      // due to a sign up error.
+      this.captchaBrowser.hidden = true;
+      if (this.wizard.pageIndex == NEW_ACCOUNT_CAPTCHA_PAGE) {
+        this.onWizardAdvance();
+      }
+    } else {
+      this.haveCaptcha = true;
+      this.captchaBrowser.hidden = false;
+    }
   },
   onProgressChange: function() {},
   onStatusChange: function() {},
   onSecurityChange: function() {},
   onLocationChange: function () {}
 }
 
 // onWizardAdvance() and onPageShow() are run before init(), so we'll set
--- a/browser/base/content/syncSetup.xul
+++ b/browser/base/content/syncSetup.xul
@@ -224,17 +224,18 @@
                 label="&button.syncKeyBackup.save.label;"
                 accesskey="&button.syncKeyBackup.save.accesskey;"
                 oncommand="gSyncUtils.passphraseSave('weavePassphrase');"/>
       </hbox>
     </groupbox>
   </wizardpage>
 
   <wizardpage label="&setup.captchaPage2.title.label;"
-              onextra1="gSyncSetup.onSyncOptions()">
+              onextra1="gSyncSetup.onSyncOptions()"
+              onpageshow="gSyncSetup.onPageShow();">
     <vbox flex="1" align="center">
       <browser height="150"
                width="450"
                id="captcha"
                type="content"
                disablehistory="true"/>
       <spacer flex="1"/>
       <hbox id="captchaFeedback" hidden="true">
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -1677,16 +1677,20 @@
             // steps.
             var panel = browser.parentNode.parentNode;
 
             // This will unload the document. An unload handler could remove
             // dependant tabs, so it's important that the tabbrowser is now in
             // a consistent state (tab removed, tab positions updated, etc.).
             panel.removeChild(browser.parentNode);
 
+            // Release the browser in case something is erroneously holding a
+            // reference to the tab after its removal.
+            aTab.linkedBrowser = null;
+
             // As the browser is removed, the removal of a dependent document can
             // cause the whole window to close. So at this point, it's possible
             // that the binding is destructed.
             if (this.mTabBox) {
               let selectedPanel = this.mTabBox.selectedPanel;
 
               this.mPanelContainer.removeChild(panel);
 
@@ -3198,29 +3202,34 @@
 
         if (tab.getAttribute("fadein") == "true")
           this._handleNewTab(tab);
         else if (tab.closing)
           this.tabbrowser._endRemoveTab(tab);
       ]]></handler>
 
       <handler event="dblclick"><![CDATA[
-#ifdef MOZ_WIDGET_GTK2
-        // Disable this on GTK2 when the menubar is draggable, since (a)
-        // the menubar and tabbbar have unified appearance and should
-        // thus not have different behavior (though this condition alone
-        // applies to more cases) and (b) it interacts badly with the
-        // drag handling that we use for dragging either one.
-        if (this.parentNode._dragBindingAlive)
+#ifndef XP_MACOSX
+        // When the tabbar has an unified appearance with the titlebar
+        // and menubar, a double-click in it should have the same behavior
+        // as double-clicking the titlebar
+        if (TabsInTitlebar.enabled ||
+            (TabsOnTop.enabled && this.parentNode._dragBindingAlive))
           return;
 #endif
+
+        if (event.button != 0 ||
+            event.originalTarget.localName != "box")
+          return;
+
         // See hack note in the tabbrowser-close-tab-button binding
-        if (!this._blockDblClick && event.button == 0 &&
-            event.originalTarget.localName == "box")
+        if (!this._blockDblClick)
           BrowserOpenTab();
+
+        event.preventDefault();
       ]]></handler>
 
       <handler event="click"><![CDATA[
         if (event.button != 1)
           return;
 
         if (event.target.localName == "tab") {
           if (this.childNodes.length > 1 || !this._closeWindowWithLastTab)
--- a/browser/base/content/tabview/drag.js
+++ b/browser/base/content/tabview/drag.js
@@ -277,21 +277,16 @@ Drag.prototype = {
   // Called in response to an <Item> draggable "stop" event.
   //
   // Parameters:
   //  immediately - bool for doing the pushAway immediately, without animation
   stop: function Drag_stop(immediately) {
     Trenches.hideGuides();
     this.item.isDragging = false;
 
-    if (this.parent && this.parent != this.item.parent &&
-       this.parent.isEmpty()) {
-      this.parent.close();
-    }
-
     if (this.parent && this.parent.expanded)
       this.parent.arrange();
 
     if (this.item.parent)
       this.item.parent.arrange();
 
     if (!this.item.parent) {
       this.item.setZ(drag.zIndex);
--- a/browser/base/content/tabview/groupitems.js
+++ b/browser/base/content/tabview/groupitems.js
@@ -59,16 +59,17 @@
 //     to <add> along with the elements provided.
 //
 // Possible options:
 //   id - specifies the groupItem's id; otherwise automatically generated
 //   userSize - see <Item.userSize>; default is null
 //   bounds - a <Rect>; otherwise based on the locations of the provided elements
 //   container - a DOM element to use as the container for this groupItem; otherwise will create
 //   title - the title for the groupItem; otherwise blank
+//   focusTitle - focus the title's input field after creation
 //   dontPush - true if this groupItem shouldn't push away or snap on creation; default is false
 //   immediately - true if we want all placement immediately, not with animation
 function GroupItem(listOfEls, options) {
   if (!options)
     options = {};
 
   this._inited = false;
   this._uninited = false;
@@ -80,20 +81,16 @@ function GroupItem(listOfEls, options) {
   this.expanded = null;
   this.hidden = false;
   this.fadeAwayUndoButtonDelay = 15000;
   this.fadeAwayUndoButtonDuration = 300;
 
   this.keepProportional = false;
   this._frozenItemSizeData = {};
 
-  // Double click tracker
-  this._lastClick = 0;
-  this._lastClickPositions = null;
-
   // Variable: _activeTab
   // The <TabItem> for the groupItem's active tab.
   this._activeTab = null;
 
   if (Utils.isPoint(options.userSize))
     this.userSize = new Point(options.userSize);
 
   var self = this;
@@ -213,22 +210,23 @@ function GroupItem(listOfEls, options) {
       self.lastMouseDownTarget = (Utils.isLeftClick(e) ? e.target : null);
     })
     .mouseup(function(e) {
       var same = (e.target == self.lastMouseDownTarget);
       self.lastMouseDownTarget = null;
       if (!same)
         return;
 
-      if (!self.isDragging) {
-        self.$titleShield.hide();
-        (self.$title)[0].focus();
-      }
+      if (!self.isDragging)
+        self.focusTitle();
     });
 
+  if (options.focusTitle)
+    this.focusTitle();
+
   // ___ Stack Expander
   this.$expander = iQ("<div/>")
     .addClass("stackExpander")
     .appendTo($container)
     .hide();
 
   // ___ app tabs: create app tab tray and populate it
   let appTabTrayContainer = iQ("<div/>")
@@ -297,17 +295,19 @@ GroupItem.prototype = Utils.extend(new I
   // Function: setActiveTab
   // Sets the active <TabItem> for this groupItem; can be null, but only
   // if there are no children.
   setActiveTab: function GroupItem_setActiveTab(tab) {
     Utils.assertThrow((!tab && this._children.length == 0) || tab.isATabItem,
         "tab must be null (if no children) or a TabItem");
 
     this._activeTab = tab;
-    this.arrange({immediately: true});
+
+    if (this.isStacked())
+      this.arrange({immediately: true});
   },
 
   // -----------
   // Function: getActiveTab
   // Gets the active <TabItem> for this groupItem; can be null, but only
   // if there are no children.
   getActiveTab: function GroupItem_getActiveTab() {
     return this._activeTab;
@@ -400,16 +400,24 @@ GroupItem.prototype = Utils.extend(new I
     // The * 6 multiplier calculation is assuming that characters in the title
     // are approximately 6 pixels wide. Bug 586545
     var css = {width: w};
     this.$title.css(css);
     this.$titleShield.css(css);
   },
 
   // ----------
+  // Function: focusTitle
+  // Hide the title's shield and focus the underlying input field.
+  focusTitle: function GroupItem_focusTitle() {
+    this.$titleShield.hide();
+    this.$title[0].focus();
+  },
+
+  // ----------
   // Function: adjustAppTabTray
   // Used to adjust the appTabTray size, to split the appTabIcons across
   // multiple columns when needed - if the groupItem size is too small.
   //
   // Parameters:
   //   arrangeGroup - rearrange the groupItem if the number of appTab columns
   //   changes. If true, then this.arrange() is called, otherwise not.
   adjustAppTabTray: function GroupItem_adjustAppTabTray(arrangeGroup) {
@@ -632,17 +640,17 @@ GroupItem.prototype = Utils.extend(new I
   // Closes the groupItem, removing (but not closing) all of its children.
   //
   // Parameters:
   //   options - An object with optional settings for this call.
   //
   // Options:
   //   immediately - (bool) if true, no animation will be used
   close: function GroupItem_close(options) {
-    this.removeAll({dontClose: true});
+    this.removeAll();
     GroupItems.unregister(this);
 
     // remove unfreeze event handlers, if item size is frozen
     this._unfreezeItemSize({dontArrange: true});
 
     let self = this;
     let destroyGroup = function () {
       iQ(self.container).remove();
@@ -707,31 +715,16 @@ GroupItem.prototype = Utils.extend(new I
   _makeClosestTabActive: function GroupItem__makeClosestTabActive() {
     let closeCenter = this.getBounds().center();
     // Find closest tab to make active
     let closestTabItem = UI.getClosestTab(closeCenter);
     UI.setActive(closestTabItem);
   },
 
   // ----------
-  // Function: closeIfEmpty
-  // Closes the group if it's empty, has no title, is closable, and
-  // autoclose is enabled (see pauseAutoclose()). Returns true if the close
-  // occurred and false otherwise.
-  closeIfEmpty: function() {
-    if (!this._children.length && !this.getTitle() &&
-        !GroupItems.getUnclosableGroupItemId() &&
-        !GroupItems._autoclosePaused) {
-      this.close();
-      return true;
-    }
-    return false;
-  },
-
-  // ----------
   // Function: _unhide
   // Shows the hidden group.
   _unhide: function GroupItem__unhide() {
     let self = this;
 
     this._cancelFadeAwayUndoButtonTimer();
     this.hidden = false;
     this.$undoContainer.remove();
@@ -771,17 +764,17 @@ GroupItem.prototype = Utils.extend(new I
       return (groupItem != self && groupItem.getChildren().length);
     });
     if (!gBrowser._numPinnedTabs && !GroupItems.getOrphanedTabs().length &&
         !remainingGroups.length) {
       let emptyGroups = GroupItems.groupItems.filter(function (groupItem) {
         return (groupItem != self && !groupItem.getChildren().length);
       });
       let group = (emptyGroups.length ? emptyGroups[0] : GroupItems.newGroup());
-      group.newTab();
+      group.newTab(null, { closedLastTab: true });
     }
 
     this.destroy();
   },
 
   // ----------
   // Function: destroy
   // Close all tabs linked to children (tabItems), removes all children and 
@@ -994,18 +987,17 @@ GroupItem.prototype = Utils.extend(new I
 
       if (!wasAlreadyInThisGroupItem) {
         item.droppable(false);
         item.groupItemData = {};
 
         item.addSubscriber(this, "close", function() {
           let count = self._children.length;
           let dontArrange = self.expanded || !self.shouldStack(count);
-          let dontClose = !item.closedManually && gBrowser._numPinnedTabs > 0;
-          self.remove(item, {dontArrange: dontArrange, dontClose: dontClose});
+          self.remove(item, {dontArrange: dontArrange});
 
           if (dontArrange)
             self._freezeItemSize(count);
 
           if (self._children.length > 0 && self._activeTab)
             UI.setActive(self);
         });
 
@@ -1042,17 +1034,16 @@ GroupItem.prototype = Utils.extend(new I
   // Parameters:
   //
   //   a - The item to remove. Can be an <Item>, a DOM element or an iQ object.
   //       The latter two must refer to the container of an <Item>.
   //   options - An optional object with settings for this call. See below.
   //
   // Possible options: 
   //   dontArrange - don't rearrange the remaining items
-  //   dontClose - don't close the group even if it normally would
   //   immediately - don't animate
   remove: function GroupItem_remove(a, options) {
     try {
       var $el;
       var item;
 
       if (a.isAnItem) {
         item = a;
@@ -1091,25 +1082,17 @@ GroupItem.prototype = Utils.extend(new I
         item.setBounds(item.getBounds(), true, {force: true});
 
       item.droppable(true);
       item.removeSubscriber(this, "close");
 
       if (typeof item.setResizable == 'function')
         item.setResizable(true, options.immediately);
 
-      // if a blank tab is selected while restoring a tab the blank tab gets
-      // removed. we need to keep the group alive for the restored tab.
-      if (item.tab._tabViewTabIsRemovedAfterRestore)
-        options.dontClose = true;
-
-      let closed = options.dontClose ? false : this.closeIfEmpty();
-      if (closed)
-        this._makeClosestTabActive();
-      else if (!options.dontArrange) {
+      if (!options.dontArrange) {
         this.arrange({animate: !options.immediately});
         this._unfreezeItemSize({dontArrange: true});
       }
 
       this._sendToSubscribers("childRemoved",{ groupItemId: this.id, item: item });
     } catch(e) {
       Utils.log(e);
     }
@@ -1263,26 +1246,25 @@ GroupItem.prototype = Utils.extend(new I
       data.lastItemCount = itemCount;
 
       // unfreeze item size when tabview is hidden
       data.onTabViewHidden = function () self._unfreezeItemSize();
       window.addEventListener('tabviewhidden', data.onTabViewHidden, false);
 
       // we don't need to observe mouse movement when expanded because the
       // tray is closed when we leave it and collapse causes unfreezing
-      if (self.expanded)
-        return;
-
-      // unfreeze item size when cursor is moved out of group bounds
-      data.onMouseMove = function (e) {
-        let cursor = new Point(e.pageX, e.pageY);
-        if (!self.bounds.contains(cursor))
-          self._unfreezeItemSize();
+      if (!self.expanded) {
+        // unfreeze item size when cursor is moved out of group bounds
+        data.onMouseMove = function (e) {
+          let cursor = new Point(e.pageX, e.pageY);
+          if (!self.bounds.contains(cursor))
+            self._unfreezeItemSize();
+        }
+        iQ(window).mousemove(data.onMouseMove);
       }
-      iQ(window).mousemove(data.onMouseMove);
     }
 
     this.arrange({animate: true, count: data.lastItemCount});
   },
 
   // ----------
   // Function: _unfreezeItemSize
   // Unfreezes and updates item size.
@@ -1636,38 +1618,16 @@ GroupItem.prototype = Utils.extend(new I
   },
 
   // ----------
   // Function: _addHandlers
   // Helper routine for the constructor; adds various event handlers to the container.
   _addHandlers: function GroupItem__addHandlers(container) {
     let self = this;
 
-    // Create new tab and zoom in on it after a double click
-    container.mousedown(function(e) {
-      if (!Utils.isLeftClick(e) || self.$titlebar[0] == e.target || 
-          self.$titlebar.contains(e.target)) {
-        self._lastClick = 0;
-        self._lastClickPositions = null;
-        return;
-      }
-      if (Date.now() - self._lastClick <= UI.DBLCLICK_INTERVAL &&
-          (self._lastClickPositions.x - UI.DBLCLICK_OFFSET) <= e.clientX &&
-          (self._lastClickPositions.x + UI.DBLCLICK_OFFSET) >= e.clientX &&
-          (self._lastClickPositions.y - UI.DBLCLICK_OFFSET) <= e.clientY &&
-          (self._lastClickPositions.y + UI.DBLCLICK_OFFSET) >= e.clientY) {
-        self.newTab();
-        self._lastClick = 0;
-        self._lastClickPositions = null;
-      } else {
-        self._lastClick = Date.now();
-        self._lastClickPositions = new Point(e.clientX, e.clientY);
-      }
-    });
-
     var dropIndex = false;
     var dropSpaceTimer = null;
 
     // When the _dropSpaceActive flag is turned on on a group, and a tab is
     // dragged on top, a space will open up.
     this._dropSpaceActive = false;
 
     this.dropOptions.over = function GroupItem_dropOptions_over(event) {
@@ -1737,17 +1697,17 @@ GroupItem.prototype = Utils.extend(new I
 
       if (dropSpaceTimer) {
         clearTimeout(dropSpaceTimer);
         dropSpaceTimer = null;
       }
       self.arrange();
       var groupItem = drag.info.item.parent;
       if (groupItem)
-        groupItem.remove(drag.info.$el, {dontClose: true});
+        groupItem.remove(drag.info.$el);
       iQ(this.container).removeClass("acceptsDrop");
     }
 
     this.draggable();
     this.droppable(true);
 
     this.$expander.click(function() {
       self.expand();
@@ -1776,24 +1736,26 @@ GroupItem.prototype = Utils.extend(new I
       immediately ? this.$resizer.hide() : this.$resizer.fadeOut();
       this.resizable(false);
     }
   },
 
   // ----------
   // Function: newTab
   // Creates a new tab within this groupItem.
-  newTab: function GroupItem_newTab(url) {
-    UI.setActive(this, { dontSetActiveTabInGroup: true });
-    let newTab = gBrowser.loadOneTab(url || "about:blank", {inBackground: true});
+  // Parameters:
+  //  url - the new tab should open this url as well
+  //  options - the options object
+  //    closedLastTab - boolean indicates the last tab has just been closed
+  newTab: function GroupItem_newTab(url, options) {
+    if (options && options.closedLastTab)
+      UI.closedLastTabInTabView = true;
 
-    // TabItems will have handled the new tab and added the tabItem property.
-    // We don't have to check if it's an app tab (and therefore wouldn't have a
-    // TabItem), since we've just created it.
-    newTab._tabViewTabItem.zoomIn(!url);
+    UI.setActive(this, { dontSetActiveTabInGroup: true });
+    gBrowser.loadOneTab(url || "about:blank", { inBackground: false });
   },
 
   // ----------
   // Function: reorderTabItemsBasedOnTabOrder
   // Reorders the tabs in a groupItem based on the arrangment of the tabs
   // shown in the tab bar. It does it by sorting the children
   // of the groupItem by the positions of their respective tabs in the
   // tab bar.
@@ -1869,17 +1831,16 @@ let GroupItems = {
   _inited: false,
   _activeGroupItem: null,
   _activeOrphanTab: null,
   _cleanupFunctions: [],
   _arrangePaused: false,
   _arrangesPending: [],
   _removingHiddenGroups: false,
   _delayedModUpdates: [],
-  _autoclosePaused: false,
   minGroupHeight: 110,
   minGroupWidth: 125,
 
   // ----------
   // Function: toString
   // Prints [GroupItems] for debug use
   toString: function GroupItems_toString() {
     return "[GroupItems count=" + this.groupItems.length + "]";
@@ -2641,26 +2602,10 @@ let GroupItems = {
   // Basic measure rules. Assures that item is a minimum size.
   calcValidSize: function GroupItems_calcValidSize(size, options) {
     Utils.assert(Utils.isPoint(size), 'input is a Point');
     Utils.assert((size.x>0 || size.y>0) && (size.x!=0 && size.y!=0), 
       "dimensions are valid:"+size.x+","+size.y);
     return new Point(
       Math.max(size.x, GroupItems.minGroupWidth),
       Math.max(size.y, GroupItems.minGroupHeight));
-  },
-
-  // ----------
-  // Function: pauseAutoclose()
-  // Temporarily disable the behavior that closes groups when they become
-  // empty. This is used when entering private browsing, to avoid trashing the
-  // user's groups while private browsing is shuffling things around.
-  pauseAutoclose: function GroupItems_pauseAutoclose() {
-    this._autoclosePaused = true;
-  },
-
-  // ----------
-  // Function: unpauseAutoclose()
-  // Re-enables the auto-close behavior.
-  resumeAutoclose: function GroupItems_resumeAutoclose() {
-    this._autoclosePaused = false;
   }
 };
--- a/browser/base/content/tabview/items.js
+++ b/browser/base/content/tabview/items.js
@@ -174,17 +174,17 @@ Item.prototype = {
     };
 
     // ___ drop
     this.dropOptions = {
       over: function() {},
       out: function() {
         let groupItem = drag.info.item.parent;
         if (groupItem)
-          groupItem.remove(drag.info.$el, {dontClose: true});
+          groupItem.remove(drag.info.$el);
         iQ(this.container).removeClass("acceptsDrop");
       },
       drop: function(event) {
         iQ(this.container).removeClass("acceptsDrop");
       },
       // Function: dropAcceptFunction
       // Given a DOM element, returns true if it should accept tabs being dropped on it.
       // Private to this file.
--- a/browser/base/content/tabview/modules/AllTabs.jsm
+++ b/browser/base/content/tabview/modules/AllTabs.jsm
@@ -69,36 +69,36 @@ let AllTabs = {
    *        "close", "move", "open", "select", "pinned", "unpinned".
    * @param callback
    *        Callback that gets called with the tab as the first argument and
    *        the event as the second argument.
    * @usage AllTabs.register("change", function handleChange(tab, event) {});
    */
   register: function register(eventName, callback) {
     // Either add additional callbacks or create the first entry
-    let listeners = eventListeners[eventName];
+    let listeners = eventListeners[events[eventName]];
     if (listeners)
       listeners.push(callback);
     else
-      eventListeners[eventName] = [callback];
+      eventListeners[events[eventName]] = [callback];
   },
 
   /**
    * Remove a callback for a given tab event.
    *
    * @param eventName
    *        Name of the corresponding Tab* Event; one of "attrModified",
    *        "close", "move", "open", "select", "pinned", "unpinned".
    * @param callback
    *        The callback given for the original AllTabs.register call.
    * @usage AllTabs.unregister("close", handleClose);
    */
   unregister: function unregister(eventName, callback) {
     // Nothing to remove for this event
-    let listeners = eventListeners[eventName];
+    let listeners = eventListeners[events[eventName]];
     if (!listeners)
       return;
 
     // Can only remove a callback if we have it
     let index = listeners.indexOf(callback);
     if (index == -1)
       return;
 
@@ -109,41 +109,60 @@ let AllTabs = {
 __defineGetter__("browserWindows", function browserWindows() {
   let browserWindows = [];
   let windows = Services.wm.getEnumerator("navigator:browser");
   while (windows.hasMoreElements())
     browserWindows.push(windows.getNext());
   return browserWindows;
 });
 
-let events = ["attrModified", "close", "move", "open", "select", "pinned", "unpinned"];
+let events = {
+  attrModified: "TabAttrModified",
+  close:        "TabClose",
+  move:         "TabMove",
+  open:         "TabOpen",
+  select:       "TabSelect",
+  pinned:       "TabPinned",
+  unpinned:     "TabUnpinned"
+};
 let eventListeners = {};
 
 function registerBrowserWindow(browserWindow) {
-  events.forEach(function(eventName) {
-    let tabEvent = "Tab" + eventName[0].toUpperCase() + eventName.slice(1);
-    browserWindow.addEventListener(tabEvent, function(event) {
-      // Make sure we've gotten listeners before trying to call
-      let listeners = eventListeners[eventName];
-      if (!listeners)
-        return;
+  for each (let event in events)
+    browserWindow.addEventListener(event, tabEventListener, true);
+
+  browserWindow.addEventListener("unload", unregisterBrowserWindow, false);
+}
 
-      let tab = event.target;
+function unregisterBrowserWindow(unloadEvent) {
+  let browserWindow = unloadEvent.currentTarget;
+
+  for each (let event in events)
+    browserWindow.removeEventListener(event, tabEventListener, true);
+
+  browserWindow.removeEventListener("unload", unregisterBrowserWindow, false);
+}
 
-      // Make a copy of the listeners, so it can't change as we call back
-      listeners.slice().forEach(function(callback) {
-        try {
-          callback(tab, event);
-        }
-        // Don't let failing callbacks stop us but report the failure
-        catch(ex) {
-          Cu.reportError(ex);
-        }
-      });
-    }, true);
+function tabEventListener(event) {
+  // Make sure we've gotten listeners before trying to call
+  let listeners = eventListeners[event.type];
+  if (!listeners)
+    return;
+
+  let tab = event.target;
+
+  // Make a copy of the listeners, so it can't change as we call back
+  listeners.slice().forEach(function (callback) {
+    try {
+      callback(tab, event);
+    }
+    // Don't let failing callbacks stop us but report the failure
+    catch (ex) {
+      Cu.reportError(ex);
+    }
   });
 }
 
 function observer(subject, topic, data) {
   switch (topic) {
     case "domwindowopened":
       subject.addEventListener("load", function() {
         subject.removeEventListener("load", arguments.callee, false);
--- a/browser/base/content/tabview/tabitems.js
+++ b/browser/base/content/tabview/tabitems.js
@@ -119,17 +119,18 @@ function TabItem(tab, options) {
 
     var phantom = $target.data("phantomGroupItem");
 
     var groupItem = drag.info.item.parent;
     if (groupItem) {
       groupItem.add(drag.info.$el);
     } else {
       phantom.removeClass("phantom acceptsDrop");
-      new GroupItem([$target, drag.info.$el], {container:phantom, bounds:phantom.bounds()});
+      let opts = {container:phantom, bounds:phantom.bounds(), focusTitle: true};
+      new GroupItem([$target, drag.info.$el], opts);
     }
   };
 
   this.dropOptions.over = function(e) {
     var $target = this.$container;
     this.isDropTarget = true;
 
     $target.removeClass("acceptsDrop");
@@ -374,17 +375,17 @@ TabItem.prototype = Utils.extend(new Ite
         //   Bug 645653 - Middle-click on reload button to duplicate orphan tabs does not create a group
         //   Bug 643119 - Ctrl+Drag to duplicate does not work for orphaned tabs
         //   ... (and any other way of duplicating a non-blank orphaned tab).
         if (GroupItems.getActiveGroupItem() == null)
           GroupItems.newTab(self, {immediately: true});
       }
     } else {
       // create tab by double click is handled in UI_init().
-      if (!TabItems.creatingNewOrphanTab)
+      if (!UI.creatingNewOrphanTab)
         GroupItems.newTab(self, {immediately: true});
     }
 
     self._reconnected = true;
     self.save();
     self._sendToSubscribers("reconnected");
   },
   
@@ -558,17 +559,17 @@ TabItem.prototype = Utils.extend(new Ite
       if (this.tab._tabViewTabItem.parent) {
         group = this.tab._tabViewTabItem.parent;
       } else {
         let emptyGroups = GroupItems.groupItems.filter(function (groupItem) {
           return (!groupItem.getChildren().length);
         });
         group = (emptyGroups.length ? emptyGroups[0] : GroupItems.newGroup());
       }
-      group.newTab();
+      group.newTab(null, { closedLastTab: true });
     }
     // when "TabClose" event is fired, the browser tab is about to close and our 
     // item "close" is fired before the browser tab actually get closed. 
     // Therefore, we need "tabRemoved" event below.
     gBrowser.removeTab(this.tab);
     let tabNotClosed = 
       Array.some(gBrowser.tabs, function(tab) { return tab == this.tab; }, this);
     if (!tabNotClosed)
@@ -660,16 +661,18 @@ TabItem.prototype = Utils.extend(new Ite
       if (tab != gBrowser.selectedTab) {
         UI.onTabSelect(gBrowser.selectedTab);
       } else { 
         if (isNewBlankTab)
           gWindow.gURLBar.focus();
       }
       if (self.parent && self.parent.expanded)
         self.parent.collapse();
+
+      self._sendToSubscribers("zoomedIn");
     }
 
     let animateZoom = gPrefBranch.getBoolPref("animate_zoom");
     if (animateZoom) {
       let transform = this.getZoomTransform();
       TabItems.pausePainting();
 
       if (this.parent && this.parent.expanded)
@@ -798,17 +801,16 @@ let TabItems = {
   paintingPaused: 0,
   _tabsWaitingForUpdate: null,
   _heartbeat: null, // see explanation at startHeartbeat() below
   _heartbeatTiming: 200, // milliseconds between calls
   _maxTimeForUpdating: 200, // milliseconds that consecutive updates can take
   _lastUpdateTime: Date.now(),
   _eventListeners: [],
   _pauseUpdateForTest: false,
-  creatingNewOrphanTab: false,
   tempCanvas: null,
   _reconnectingPaused: false,
   tabItemPadding: {},
 
   // ----------
   // Function: toString
   // Prints [TabItems count=count] for debug use
   toString: function TabItems_toString() {
@@ -1075,16 +1077,19 @@ let TabItems = {
         UI.setActive(null, { onlyRemoveActiveTab: true });
 
       this.unregister(tab._tabViewTabItem);
       tab._tabViewTabItem._sendToSubscribers("close");
       tab._tabViewTabItem.$container.remove();
       tab._tabViewTabItem.removeTrenches();
       Items.unsquish(null, tab._tabViewTabItem);
 
+      tab._tabViewTabItem.tab = null;
+      tab._tabViewTabItem.tabCanvas.tab = null;
+      tab._tabViewTabItem.tabCanvas = null;
       tab._tabViewTabItem = null;
       Storage.saveTab(tab, null);
 
       this._tabsWaitingForUpdate.remove(tab);
     } catch(e) {
       Utils.log(e);
     }
   },
--- a/browser/base/content/tabview/ui.js
+++ b/browser/base/content/tabview/ui.js
@@ -134,16 +134,24 @@ let UI = {
   // Variable: _browserKeys
   // Used to keep track of allowed browser keys.
   _browserKeys: null,
 
   // Variable: ignoreKeypressForSearch
   // Used to prevent keypress being handled after quitting search mode.
   ignoreKeypressForSearch: false,
 
+  // Variable: creatingNewOrphanTab
+  // Used to keep track of whether we are creating a new oprhan tab or not.
+  creatingNewOrphanTab: false,
+
+  // Variable: _lastOpenedTab
+  // Used to keep track of the last opened tab.
+  _lastOpenedTab: null,
+
   // ----------
   // Function: toString
   // Prints [UI] for debug use
   toString: function UI_toString() {
     return "[UI]";
   },
 
   // ----------
@@ -191,30 +199,31 @@ let UI = {
           } else {
             // Create an orphan tab on double click
             if (Date.now() - self._lastClick <= self.DBLCLICK_INTERVAL && 
                 (self._lastClickPositions.x - self.DBLCLICK_OFFSET) <= e.clientX &&
                 (self._lastClickPositions.x + self.DBLCLICK_OFFSET) >= e.clientX &&
                 (self._lastClickPositions.y - self.DBLCLICK_OFFSET) <= e.clientY &&
                 (self._lastClickPositions.y + self.DBLCLICK_OFFSET) >= e.clientY) {
               self.setActive(null);
-              TabItems.creatingNewOrphanTab = true;
-
-              let newTab =
-                gBrowser.loadOneTab("about:blank", { inBackground: true });
+              self.creatingNewOrphanTab = true;
 
               let box =
                 new Rect(e.clientX - Math.floor(TabItems.tabWidth/2),
                          e.clientY - Math.floor(TabItems.tabHeight/2),
                          TabItems.tabWidth, TabItems.tabHeight);
+              let newTab =
+                gBrowser.loadOneTab("about:blank", { inBackground: false });
+
               newTab._tabViewTabItem.setBounds(box, true);
               newTab._tabViewTabItem.pushAway(true);
               self.setActive(newTab._tabViewTabItem);
 
-              TabItems.creatingNewOrphanTab = false;
+              self.creatingNewOrphanTab = false;
+              // the bounds of tab item is set and we can zoom in now.
               newTab._tabViewTabItem.zoomIn(true);
 
               self._lastClick = 0;
               self._lastClickPositions = null;
               gTabView.firstUseExperienced = true;
             } else {
               self._lastClick = Date.now();
               self._lastClickPositions = new Point(e.clientX, e.clientY);
@@ -509,26 +518,19 @@ let UI = {
 #ifdef XP_MACOSX
     this.setTitlebarColors(true);
 #endif
     let event = document.createEvent("Events");
     event.initEvent("tabviewshown", true, false);
 
     Storage.saveVisibilityData(gWindow, "true");
 
-    // Close the active group if it was empty. This will happen when the
-    // user returns to Panorama after looking at an app tab, having
-    // closed all other tabs. (If the user is looking at an orphan tab, then
-    // there is no active group for the purposes of this check.)
     let activeGroupItem = null;
-    if (!UI.getActiveOrphanTab()) {
+    if (!UI.getActiveOrphanTab())
       activeGroupItem = GroupItems.getActiveGroupItem();
-      if (activeGroupItem && activeGroupItem.closeIfEmpty())
-        activeGroupItem = null;
-    }
 
     if (zoomOut && currentTab && currentTab._tabViewTabItem) {
       item = currentTab._tabViewTabItem;
       // If there was a previous currentTab we want to animate
       // its thumbnail (canvas) for the zoom out.
       // Note that we start the animation on the chrome thread.
 
       // Zoom out!
@@ -624,20 +626,18 @@ let UI = {
   },
 #endif
 
   // ----------
   // Function: storageBusy
   // Pauses the storage activity that conflicts with sessionstore updates and 
   // private browsing mode switches. Calls can be nested. 
   storageBusy: function UI_storageBusy() {
-    if (!this._storageBusyCount) {
+    if (!this._storageBusyCount)
       TabItems.pauseReconnecting();
-      GroupItems.pauseAutoclose();
-    }
     
     this._storageBusyCount++;
   },
   
   // ----------
   // Function: storageReady
   // Resumes the activity paused by storageBusy, and updates for any new group
   // information in sessionstore. Calls can be nested. 
@@ -645,17 +645,16 @@ let UI = {
     this._storageBusyCount--;
     if (!this._storageBusyCount) {
       let hasGroupItemsData = GroupItems.load();
       if (!hasGroupItemsData)
         this.reset();
   
       TabItems.resumeReconnecting();
       GroupItems._updateTabBar();
-      GroupItems.resumeAutoclose();
     }
   },
 
   // ----------
   // Function: _addTabActionHandlers
   // Adds handlers to handle tab actions.
   _addTabActionHandlers: function UI__addTabActionHandlers() {
     var self = this;
@@ -722,16 +721,18 @@ let UI = {
     // TabOpen
     this._eventListeners.open = function(tab) {
       if (tab.ownerDocument.defaultView != gWindow)
         return;
 
       // if it's an app tab, add it to all the group items
       if (tab.pinned)
         GroupItems.addAppTab(tab);
+      else if (self.isTabViewVisible())
+        self._lastOpenedTab = tab;
     };
     
     // TabClose
     this._eventListeners.close = function(tab) {
       if (tab.ownerDocument.defaultView != gWindow)
         return;
 
       // if it's an app tab, remove it from all the group items
@@ -768,18 +769,19 @@ let UI = {
           // an un-named groupItem, which means that the groupItem is gone (null) and
           // there are no visible tabs. 
           let closingUnnamedGroup = (groupItem == null &&
               gBrowser.visibleTabs.length <= 1); 
 
           // 3) When a blank tab is active while restoring a closed tab the
           // blank tab gets removed. The active group is not closed as this is
           // where the restored tab goes. So do not show the TabView.
+          let tabItem = tab && tab._tabViewTabItem;
           let closingBlankTabAfterRestore =
-            (tab && tab._tabViewTabIsRemovedAfterRestore);
+            (tabItem && tabItem.isRemovedAfterRestore);
 
           if ((closingLastOfGroup || closingUnnamedGroup) &&
               !closingBlankTabAfterRestore) {
             // for the tab focus event to pick up.
             self._closedLastVisibleTab = true;
             self.showTabView();
           }
         }
@@ -856,57 +858,62 @@ let UI = {
     else
       gBrowser.selectedTab = xulTab;
   },
 
   // ----------
   // Function: onTabSelect
   // Called when the user switches from one tab to another outside of the TabView UI.
   onTabSelect: function UI_onTabSelect(tab) {
-    let currentTab = this._currentTab;
     this._currentTab = tab;
 
-    // if the last visible tab has just been closed, don't show the chrome UI.
-    if (this.isTabViewVisible() &&
-        (this._closedLastVisibleTab || this._closedSelectedTabInTabView ||
-         this.restoredClosedTab)) {
-      if (this.restoredClosedTab) {
-        // when the tab view UI is being displayed, update the thumb for the 
-        // restored closed tab after the page load
-        tab.linkedBrowser.addEventListener("load", function (event) {
-          tab.linkedBrowser.removeEventListener("load", arguments.callee, true);
-          TabItems._update(tab);
-        }, true);
+    if (this.isTabViewVisible()) {
+      if (!this.restoredClosedTab && this._lastOpenedTab == tab && 
+        tab._tabViewTabItem) {
+        if (!this.creatingNewOrphanTab)
+          tab._tabViewTabItem.zoomIn(true);
+        this._lastOpenedTab = null;
+        return;
       }
-      this._closedLastVisibleTab = false;
-      this._closedSelectedTabInTabView = false;
-      this.restoredClosedTab = false;
-      return;
+      if (this._closedLastVisibleTab ||
+          (this._closedSelectedTabInTabView && !this.closedLastTabInTabView) ||
+          this.restoredClosedTab) {
+        if (this.restoredClosedTab) {
+          // when the tab view UI is being displayed, update the thumb for the 
+          // restored closed tab after the page load
+          tab.linkedBrowser.addEventListener("load", function (event) {
+            tab.linkedBrowser.removeEventListener("load", arguments.callee, true);
+            TabItems._update(tab);
+          }, true);
+        }
+        this._closedLastVisibleTab = false;
+        this._closedSelectedTabInTabView = false;
+        this.closedLastTabInTabView = false;
+        this.restoredClosedTab = false;
+        return;
+      }
     }
     // reset these vars, just in case.
     this._closedLastVisibleTab = false;
     this._closedSelectedTabInTabView = false;
+    this.closedLastTabInTabView = false;
     this.restoredClosedTab = false;
+    this._lastOpenedTab = null;
 
     // if TabView is visible but we didn't just close the last tab or
     // selected tab, show chrome.
     if (this.isTabViewVisible())
       this.hideTabView();
 
     // another tab might be selected when hideTabView() is invoked so a
     // validation is needed.
     if (this._currentTab != tab)
       return;
 
-    let oldItem = null;
     let newItem = null;
-
-    if (currentTab && currentTab._tabViewTabItem)
-      oldItem = currentTab._tabViewTabItem;
-
     // update the tab bar for the new tab's group
     if (tab && tab._tabViewTabItem) {
       if (!TabItems.reconnectingPaused()) {
         newItem = tab._tabViewTabItem;
         GroupItems.updateActiveGroupItemAndTabBar(newItem);
       }
     } else {
       // No tabItem; must be an app tab. Base the tab bar on the current group.
@@ -1316,17 +1323,18 @@ let UI = {
         // to that groupItem.
         var tabs = GroupItems.getOrphanedTabs();
         var insideTabs = [];
         for each(let tab in tabs) {
           if (bounds.contains(tab.bounds))
             insideTabs.push(tab);
         }
 
-        var groupItem = new GroupItem(insideTabs,{bounds:bounds});
+        let opts = {bounds: bounds, focusTitle: true};
+        let groupItem = new GroupItem(insideTabs, opts);
         self.setActive(groupItem);
         phantom.remove();
         dragOutInfo = null;
         gTabView.firstUseExperienced = true;
       } else {
         collapse();
       }
     }
@@ -1493,24 +1501,24 @@ let UI = {
       hideSearch(null);
     }
 
     if (!zoomedIn) {
       let unhiddenGroups = GroupItems.groupItems.filter(function(groupItem) {
         return (!groupItem.hidden && groupItem.getChildren().length > 0);
       });
       // no pinned tabs, no visible groups and no orphaned tabs: open a new
-      // group. open a blank tab and return
+      // group, a blank tab and return
       if (!unhiddenGroups.length && !GroupItems.getOrphanedTabs().length) {
         let emptyGroups = GroupItems.groupItems.filter(function (groupItem) {
           return (!groupItem.hidden && !groupItem.getChildren().length);
         });
         let group = (emptyGroups.length ? emptyGroups[0] : GroupItems.newGroup());
         if (!gBrowser._numPinnedTabs) {
-          group.newTab();
+          group.newTab(null, { closedLastTab: true });
           return;
         }
       }
 
       // If there's an active TabItem, zoom into it. If not (for instance when the
       // selected tab is an app tab), just go there.
       let activeTabItem = this.getActiveTab();
       if (!activeTabItem) {
--- a/browser/base/content/test/Makefile.in
+++ b/browser/base/content/test/Makefile.in
@@ -167,16 +167,17 @@ endif
                  browser_bug598923.js \
                  browser_bug599325.js \
                  browser_bug609700.js \
                  browser_bug616836.js \
                  browser_bug623893.js \
                  browser_bug624734.js \
                  browser_bug647886.js \
                  browser_bug655584.js \
+                 browser_bug664672.js \
                  browser_findbarClose.js \
                  browser_keywordBookmarklets.js \
                  browser_contextSearchTabPosition.js \
                  browser_ctrlTab.js \
                  browser_customize_popupNotification.js \
                  browser_disablechrome.js \
                  browser_discovery.js \
                  browser_duplicateIDs.js \
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/browser_bug664672.js
@@ -0,0 +1,19 @@
+function test() {
+  waitForExplicitFinish();
+
+  var tab = gBrowser.addTab();
+
+  tab.addEventListener("TabClose", function () {
+    tab.removeEventListener("TabClose", arguments.callee, false);
+
+    ok(tab.linkedBrowser, "linkedBrowser should still exist during the TabClose event");
+
+    executeSoon(function () {
+      ok(!tab.linkedBrowser, "linkedBrowser should be gone after the TabClose event");
+
+      finish();
+    });
+  }, false);
+
+  gBrowser.removeTab(tab);
+}
--- a/browser/base/content/test/browser_visibleTabs.js
+++ b/browser/base/content/test/browser_visibleTabs.js
@@ -125,9 +125,12 @@ function test() {
   is(gBrowser.tabs.length, 2, "still have 2 open tabs");
 
   // Close the last visible tab and make sure we still get a visible tab
   gBrowser.removeTab(testTab);
   is(gBrowser.visibleTabs.length, 1, "only orig is left and visible");
   is(gBrowser.tabs.length, 1, "sanity check that it matches");
   is(gBrowser.selectedTab, origTab, "got the orig tab");
   is(origTab.hidden, false, "and it's not hidden -- visible!");
+
+  if (tabViewWindow)
+    tabViewWindow.GroupItems.groupItems[0].close();
 }
--- a/browser/base/content/test/tabview/Makefile.in
+++ b/browser/base/content/test/tabview/Makefile.in
@@ -80,16 +80,17 @@ include $(topsrcdir)/config/rules.mk
                  browser_tabview_bug599626.js \
                  browser_tabview_bug600645.js \
                  browser_tabview_bug600812.js \
                  browser_tabview_bug602432.js \
                  browser_tabview_bug604098.js \
                  browser_tabview_bug604699.js \
                  browser_tabview_bug606657.js \
                  browser_tabview_bug606905.js \
+                 browser_tabview_bug607108.js \
                  browser_tabview_bug608037.js \
                  browser_tabview_bug608184.js \
                  browser_tabview_bug608158.js \
                  browser_tabview_bug608405.js \
                  browser_tabview_bug610208.js \
                  browser_tabview_bug610242.js \
                  browser_tabview_bug612470.js \
                  browser_tabview_bug613541.js \
@@ -143,16 +144,18 @@ include $(topsrcdir)/config/rules.mk
                  browser_tabview_bug649307.js \
                  browser_tabview_bug649319.js \
                  browser_tabview_bug650573.js \
                  browser_tabview_bug651311.js \
                  browser_tabview_bug654941.js \
                  browser_tabview_bug655269.js \
                  browser_tabview_bug656778.js \
                  browser_tabview_bug656913.js \
+                 browser_tabview_bug662266.js \
+                 browser_tabview_bug665502.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 \
                  browser_tabview_orphaned_tabs.js \
--- a/browser/base/content/test/tabview/browser_tabview_bug587276.js
+++ b/browser/base/content/test/tabview/browser_tabview_bug587276.js
@@ -31,57 +31,60 @@ function test2() {
   });
   EventUtils.synthesizeKey("f", { accelKey: true }, contentWindow);
 }
 
 function test3() {
   ok(!contentWindow.isSearchEnabled(), "The search is disabled")
 
   is(gBrowser.tabs.length, 1, "There is one tab before cmd/ctrl + t is pressed");
-  EventUtils.synthesizeKey("t", { accelKey: true }, contentWindow);
-  is(gBrowser.tabs.length, 2, "There are two tabs after cmd/ctrl + t is pressed");
+
+  whenTabViewIsHidden(function() { 
+    is(gBrowser.tabs.length, 2, "There are two tabs after cmd/ctrl + t is pressed");
 
-  gBrowser.tabs[0].linkedBrowser.loadURI("about:robots");
-  gBrowser.tabs[1].linkedBrowser.loadURI("http://example.com/");
+    gBrowser.tabs[0].linkedBrowser.loadURI("about:robots");
+    gBrowser.tabs[1].linkedBrowser.loadURI("http://example.com/");
 
-  afterAllTabsLoaded(function () {
-    showTabView(test4);
+    afterAllTabsLoaded(function () {
+      showTabView(test4);
+    });
   });
+  EventUtils.synthesizeKey("t", { accelKey: true }, contentWindow);
 }
 
 function test4() {
   is(gBrowser.tabs.length, 2, "There are two tabs");
-  
+
   let onTabClose = function() {
     gBrowser.tabContainer.removeEventListener("TabClose", onTabClose, true);
     executeSoon(function() {
       is(gBrowser.tabs.length, 1, "There is one tab after removing one");
 
       EventUtils.synthesizeKey("T", { accelKey: true, shiftKey: true }, contentWindow);
       is(gBrowser.tabs.length, 2, "There are two tabs after restoring one");
 
       gBrowser.tabs[0].linkedBrowser.loadURI("about:blank");
-      gBrowser.removeTab(gBrowser.tabs[1]);
+      gBrowser.selectedTab = gBrowser.tabs[0];
       test8();
     });
   };
   gBrowser.tabContainer.addEventListener("TabClose", onTabClose, true);
   gBrowser.removeTab(gBrowser.tabs[1]);
 }
 
 // below key combination shouldn't trigger actions in tabview UI
 function test8() {
-  let newTab = gBrowser.loadOneTab("about:blank", { inBackground: true });
+  showTabView(function() {
+    is(gBrowser.tabs.length, 2, "There are two tabs before cmd/ctrl + w is pressed");
+    EventUtils.synthesizeKey("w", { accelKey: true }, contentWindow);
+    is(gBrowser.tabs.length, 2, "There are two tabs after cmd/ctrl + w is pressed");
 
-  is(gBrowser.tabs.length, 2, "There are two tabs before cmd/ctrl + w is pressed");
-  EventUtils.synthesizeKey("w", { accelKey: true }, contentWindow);
-  is(gBrowser.tabs.length, 2, "There are two tabs after cmd/ctrl + w is pressed");
-
-  gBrowser.removeTab(newTab);
-  test9();
+    gBrowser.removeTab(gBrowser.tabs[1]);
+    test9();
+  });
 }
 
 function test9() {
   let zoomLevel = ZoomManager.zoom;
   EventUtils.synthesizeKey("+", { accelKey: true }, contentWindow);
   is(ZoomManager.zoom, zoomLevel, "The zoom level remains unchanged after cmd/ctrl + + is pressed");
 
   EventUtils.synthesizeKey("-", { accelKey: true }, contentWindow);
--- a/browser/base/content/test/tabview/browser_tabview_bug587990.js
+++ b/browser/base/content/test/tabview/browser_tabview_bug587990.js
@@ -1,69 +1,31 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
-let newTab;
-let win;
+function test() {
+  let newTab;
 
-function test() {
-  waitForExplicitFinish();
-
-  win = window.openDialog(getBrowserURL(), "_blank", "all,dialog=no", "about:blank");
-
-  let onLoad = function() {
-    win.removeEventListener("load", onLoad, false);
+  let onLoad = function (win) {
+    registerCleanupFunction(function () win.close());
 
     newTab = win.gBrowser.addTab();
 
-    let onTabViewFrameInitialized = function() {
-      win.removeEventListener(
-        "tabviewframeinitialized", onTabViewFrameInitialized, false);
+    let popup = win.document.getElementById("context_tabViewMenuPopup");
+    win.TabView.updateContextMenu(newTab, popup);
+  };
 
-      win.addEventListener("tabviewshown", onTabViewWindowLoaded, false);
-      win.TabView.toggle();
-    }
-    win.addEventListener(
-      "tabviewframeinitialized", onTabViewFrameInitialized, false);
-    win.TabView.updateContextMenu(
-      newTab, win.document.getElementById("context_tabViewMenuPopup"));
-  }
-  win.addEventListener("load", onLoad, false);
-}
-
-function onTabViewWindowLoaded() {
-  win.removeEventListener("tabviewshown", onTabViewWindowLoaded, false);
-
-  ok(win.TabView.isVisible(), "Tab View is visible");
-
-  let contentWindow = win.document.getElementById("tab-view").contentWindow;
-
-  is(contentWindow.GroupItems.groupItems.length, 1, "Has only one group");
-
-  let groupItem = contentWindow.GroupItems.groupItems[0];
-  let tabItems = groupItem.getChildren();
+  let onShow = function (win) {
+    let cw = win.TabView.getContentWindow();
+    is(cw.GroupItems.groupItems.length, 1, "Has only one group");
 
-  is(tabItems[tabItems.length - 1].tab, newTab, "The new tab exists in the group");
+    let groupItem = cw.GroupItems.groupItems[0];
+    let tabItems = groupItem.getChildren();
 
-  win.gBrowser.removeTab(newTab);
-  whenWindowObservesOnce(win, "domwindowclosed", function() {
-    finish();
-  });
-  win.close();
-}
+    let tab = tabItems[tabItems.length - 1].tab;
+    is(tab, newTab, "The new tab exists in the group");
 
-function whenWindowObservesOnce(win, topic, func) {
-    let windowWatcher = Components.classes["@mozilla.org/embedcomp/window-watcher;1"]
-      .getService(Components.interfaces.nsIWindowWatcher);
-    let origWin = win;
-    let origTopic = topic;
-    let origFunc = func;        
-    function windowObserver(aSubject, aTopic, aData) {
-      let theWin = aSubject.QueryInterface(Ci.nsIDOMWindow);
-      if (origWin && theWin != origWin)
-        return;
-      if(aTopic == origTopic) {
-          windowWatcher.unregisterNotification(windowObserver);
-          origFunc.apply(this, []);
-      }
-    }
-    windowWatcher.registerNotification(windowObserver);
+    finish();
+  };
+
+  waitForExplicitFinish();
+  newWindowWithTabView(onShow, onLoad);
 }
--- a/browser/base/content/test/tabview/browser_tabview_bug589324.js
+++ b/browser/base/content/test/tabview/browser_tabview_bug589324.js
@@ -1,13 +1,11 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
-const ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);
-
 const DUMMY_PAGE_URL = "http://mochi.test:8888/browser/browser/base/content/test/tabview/dummy_page.html";
 const DUMMY_PAGE_URL_2 = "http://mochi.test:8888/";
 
 let state = {
   windows: [{
     tabs: [{
       entries: [{ url: DUMMY_PAGE_URL }],
       hidden: true,
@@ -49,20 +47,17 @@ function test() {
   registerCleanupFunction(function () {
     Services.prefs.clearUserPref("browser.sessionstore.restore_hidden_tabs");
   });
 
   Services.prefs.setBoolPref("browser.sessionstore.restore_hidden_tabs", false);
 
   testTabSwitchAfterRestore(function () {
     Services.prefs.setBoolPref("browser.sessionstore.restore_hidden_tabs", true);
-
-    testTabSwitchAfterRestore(function () {
-      waitForFocus(finish);
-    });
+    testTabSwitchAfterRestore(finish);
   });
 }
 
 function testTabSwitchAfterRestore(callback) {
   newWindowWithState(state, function (win) {
     registerCleanupFunction(function () win.close());
 
     let [firstTab, secondTab] = win.gBrowser.tabs;
@@ -87,35 +82,8 @@ function testTabSwitchAfterRestore(callb
 
       callback();
     }, false);
 
     // switch to another tab
     win.switchToTabHavingURI(DUMMY_PAGE_URL);
   });
 }
-
-function newWindowWithState(state, callback) {
-  let opts = "chrome,all,dialog=no,height=800,width=800";
-  let win = window.openDialog(getBrowserURL(), "_blank", opts);
-
-  whenWindowLoaded(win, function () {
-    ss.setWindowState(win, JSON.stringify(state), true);
-  });
-
-  whenWindowStateReady(win, function () {
-    afterAllTabsLoaded(function () callback(win), win);
-  });
-}
-
-function whenWindowLoaded(win, callback) {
-  win.addEventListener("load", function onLoad() {
-    win.removeEventListener("load", onLoad, false);
-    executeSoon(callback);
-  }, false);
-}
-
-function whenWindowStateReady(win, callback) {
-  win.addEventListener("SSWindowStateReady", function onReady() {
-    win.removeEventListener("SSWindowStateReady", onReady, false);
-    executeSoon(callback);
-  }, false);
-}
--- a/browser/base/content/test/tabview/browser_tabview_bug590606.js
+++ b/browser/base/content/test/tabview/browser_tabview_bug590606.js
@@ -67,13 +67,11 @@ function testGroupSwitch(contentWindow, 
   // switch to groupItemOne
   tabItem = contentWindow.GroupItems.getNextGroupItemTab(false);
   if (tabItem)
     gBrowser.selectedTab = tabItem.tab;
   is(gBrowser.selectedTab, groupItemOne.getChild(1).tab,
     "The currently selected tab should be the second tab in the groupItemOne");
 
   // cleanup.
-  gBrowser.removeTab(groupItemTwo.getChild(0).tab);
   gBrowser.removeTab(newTabOne);
-
-  finish();
+  closeGroupItem(groupItemTwo, finish);
 }
--- a/browser/base/content/test/tabview/browser_tabview_bug595943.js
+++ b/browser/base/content/test/tabview/browser_tabview_bug595943.js
@@ -53,23 +53,25 @@ function onTabViewWindowLoaded() {
     ok(!TabView.isVisible(), "Tab View remains hidden");
   
     // clean up
     gBrowser.selectedTab = originalTab;
     
     gBrowser.unpinTab(appXulTab);
     gBrowser.removeTab(appXulTab);
 
-    ok(groupItem.closeIfEmpty(), "the second group was empty");
+    ok(!groupItem.getChildren().length, "the second group is empty");
 
-    // Verify ending state
-    is(gBrowser.tabs.length, 1, "we finish with one tab");
-    is(contentWindow.GroupItems.groupItems.length, 1,
-       "we finish with one group");
-    ok(!TabView.isVisible(), "we finish with Tab View hidden");
-      
-    finish();
+    closeGroupItem(groupItem, function () {
+      // Verify ending state
+      is(gBrowser.tabs.length, 1, "we finish with one tab");
+      is(contentWindow.GroupItems.groupItems.length, 1,
+         "we finish with one group");
+      ok(!TabView.isVisible(), "we finish with Tab View hidden");
+  
+      finish();
+    });
   }
 
   window.addEventListener("tabviewhidden", onTabViewHidden, false);
   EventUtils.sendMouseEvent({ type: "mousedown" }, normalXulTab._tabViewTabItem.container, contentWindow);
   EventUtils.sendMouseEvent({ type: "mouseup" }, normalXulTab._tabViewTabItem.container, contentWindow);
 }
--- a/browser/base/content/test/tabview/browser_tabview_bug598600.js
+++ b/browser/base/content/test/tabview/browser_tabview_bug598600.js
@@ -64,11 +64,11 @@ function test() {
       is(contentWindow.GroupItems.getOrphanedTabs().length, 0, "No orphan tabs");
 
       // clean up and finish
       newWin.close();
 
       finish();
     }
     newWin.addEventListener("tabviewshown", onTabViewShow, false);
-    newWin.TabView.toggle();
+    waitForFocus(function() { newWin.TabView.toggle(); });
   }, false);
 }
--- a/browser/base/content/test/tabview/browser_tabview_bug600812.js
+++ b/browser/base/content/test/tabview/browser_tabview_bug600812.js
@@ -23,22 +23,25 @@ function test() {
 
     let sourceTab = sourceGroup.getChild(0).container;
     EventUtils.synthesizeMouseAtCenter(sourceTab, {type: 'mousedown'}, cw);
 
     let targetTab = targetGroup.getChild(0).container;
     EventUtils.synthesizeMouseAtCenter(targetTab, {type: 'mousemove'}, cw);
     EventUtils.synthesizeMouseAtCenter(targetTab, {type: 'mouseup'}, cw);
 
+    is(cw.GroupItems.groupItems.length, 2, 'there are two groupItems');
+    is(sourceGroup.getChildren().length, 0, 'source group has no tabs');
     is(targetGroup.getChildren().length, 2, 'target group has two tabs');
-    is(cw.GroupItems.groupItems.length, 1, 'sourceGroup was closed');
-    isnot(cw.GroupItems.groupItems[0], sourceGroup, 'sourceGroup was closed');
 
     targetGroup.getChild(0).close();
-    hideTabView(finish);
+
+    closeGroupItem(sourceGroup, function () {
+      hideTabView(finish);
+    });
   }
 
   waitForExplicitFinish();
 
   showTabView(function () {
     cw = TabView.getContentWindow();
     afterAllTabsLoaded(testVeryQuickDragAndDrop);
   });
--- a/browser/base/content/test/tabview/browser_tabview_bug604098.js
+++ b/browser/base/content/test/tabview/browser_tabview_bug604098.js
@@ -4,61 +4,49 @@
 let originalTab;
 let orphanedTab;
 let contentWindow;
 let contentElement;
 
 function test() {
   waitForExplicitFinish();
 
+  registerCleanupFunction(function() {
+    if (gBrowser.tabs.length > 1)
+      gBrowser.removeTab(gBrowser.tabs[1]);
+    hideTabView(function() {});
+  });
+
   showTabView(function() {
     contentWindow = TabView.getContentWindow();
     contentElement = contentWindow.document.getElementById("content");
     originalTab = gBrowser.visibleTabs[0];
     test1();
   });
 }
 
 function test1() {
   is(contentWindow.GroupItems.getOrphanedTabs().length, 0, "No orphaned tabs");
 
   whenTabViewIsHidden(function() {
     showTabView(function() {
       is(contentWindow.GroupItems.getOrphanedTabs().length, 1,
          "An orphaned tab is created");
-      orphanedTab = contentWindow.GroupItems.getOrphanedTabs()[0].tab;
-
-      test2();
+      hideTabView(function() {
+        gBrowser.selectedTab = originalTab;
+        finish();
+      });
     });
   });
 
   // first click
   mouseClick(contentElement, 0);
   // second click
   mouseClick(contentElement, 0);
 }
 
-function test2() {
-  let groupItem = createEmptyGroupItem(contentWindow, 300, 300, 200);
-  is(groupItem.getChildren().length, 0, "The group is empty");
-
-  hideTabView(function() {
-    is(groupItem.getChildren().length, 1, "A tab is created inside the group");
-
-    gBrowser.selectedTab = originalTab;
-    gBrowser.removeTab(orphanedTab);
-    gBrowser.removeTab(groupItem.getChildren()[0].tab);
-
-    finish();
-  });
-
-  // first click
-  mouseClick(groupItem.container, 0);
-  // second click
-  mouseClick(groupItem.container, 0);
-}
-
 function mouseClick(targetElement, buttonCode) {
   EventUtils.sendMouseEvent(
     { type: "mousedown", button: buttonCode }, targetElement, contentWindow);
   EventUtils.sendMouseEvent(
     { type: "mouseup", button: buttonCode }, targetElement, contentWindow);
 }
+
--- a/browser/base/content/test/tabview/browser_tabview_bug606905.js
+++ b/browser/base/content/test/tabview/browser_tabview_bug606905.js
@@ -17,16 +17,18 @@ function test() {
 
     // move a tab to another group and check the closebuttons attribute
     TabView._initFrame(function() {
       TabView.moveTabTo(newTabs[newTabs.length - 1], null);
       ok(gBrowser.visibleTabs[0].getBoundingClientRect().width > gBrowser.tabContainer.mTabClipWidth, 
          "Tab width is bigger than tab clip width");
       is(gBrowser.tabContainer.getAttribute("closebuttons"), "alltabs", "Show button on all tabs.")
 
+      let cw = TabView.getContentWindow();
+      let groupItems = cw.GroupItems.groupItems;
+      is(groupItems.length, 2, "there are two groupItems");
+
       // clean up and finish
-      newTabs.forEach(function(tab) {
-        gBrowser.removeTab(tab);
-      });
-      finish();
+      newTabs.forEach(function (tab) gBrowser.removeTab(tab));
+      closeGroupItem(groupItems[1], finish);
     });
   });
 }
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/tabview/browser_tabview_bug607108.js
@@ -0,0 +1,88 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+function test() {
+  let cw;
+
+  let assertNumberOfGroupItems = function (num) {
+    let groupItems = cw.GroupItems.groupItems;
+    is(groupItems.length, num, "number of groupItems is " + num);
+  };
+
+  let dragTabOutOfGroup = function (groupItem) {
+    let tabItem = groupItem.getChild(0);
+    let target = tabItem.container;
+
+    EventUtils.synthesizeMouseAtCenter(target, {type: "mousedown"}, cw);
+    EventUtils.synthesizeMouse(target, 400, 100, {type: "mousemove"}, cw);
+    EventUtils.synthesizeMouseAtCenter(target, {type: "mouseup"}, cw);
+  };
+
+  let testCreateGroup = function (callback) {
+    let content = cw.document.getElementById("content");
+
+    // drag to create a new group
+    EventUtils.synthesizeMouse(content, 350, 50, {type: "mousedown"}, cw);
+    EventUtils.synthesizeMouse(content, 500, 250, {type: "mousemove"}, cw);
+    EventUtils.synthesizeMouse(content, 500, 250, {type: "mouseup"}, cw);
+
+    // enter a title for the new group
+    EventUtils.synthesizeKey("t", {}, cw);
+    EventUtils.synthesizeKey("VK_RETURN", {}, cw);
+
+    assertNumberOfGroupItems(2);
+
+    let groupItem = cw.GroupItems.groupItems[1];
+    is(groupItem.getTitle(), "t", "new groupItem's title is correct");
+
+    groupItem.addSubscriber(groupItem, "close", function () {
+      groupItem.removeSubscriber(groupItem, "close");
+      executeSoon(callback);
+    });
+
+    groupItem.closeAll();
+  };
+
+  let testDropOnOrphan = function (callback) {
+    assertNumberOfGroupItems(1);
+
+    let groupItem = cw.GroupItems.groupItems[0];
+    dragTabOutOfGroup(groupItem);
+    dragTabOutOfGroup(groupItem);
+    assertNumberOfGroupItems(2);
+
+    // enter a title for the new group
+    EventUtils.synthesizeKey("t", {}, cw);
+    EventUtils.synthesizeKey("VK_RETURN", {}, cw);
+
+    groupItem = cw.GroupItems.groupItems[1];
+    is(groupItem.getTitle(), "t", "new groupItem's title is correct");
+    closeGroupItem(groupItem, callback);
+  };
+
+  let onLoad = function (win) {
+    registerCleanupFunction(function () win.close());
+
+    for (let i = 0; i < 2; i++)
+      win.gBrowser.loadOneTab("about:blank", {inBackground: true});
+  };
+
+  let onShow = function (win) {
+    cw = win.TabView.getContentWindow();
+    assertNumberOfGroupItems(1);
+
+    let groupItem = cw.GroupItems.groupItems[0];
+    groupItem.setSize(200, 600, true);
+
+    waitForFocus(function () {
+      testCreateGroup(function () {
+        testDropOnOrphan(function () {
+          waitForFocus(finish);
+        });
+      });
+    }, cw);
+  };
+
+  waitForExplicitFinish();
+  newWindowWithTabView(onShow, onLoad);
+}
--- a/browser/base/content/test/tabview/browser_tabview_bug608037.js
+++ b/browser/base/content/test/tabview/browser_tabview_bug608037.js
@@ -9,50 +9,34 @@ function test() {
 
   tabOne = gBrowser.addTab("http://mochi.test:8888/");
   tabTwo = gBrowser.addTab("http://mochi.test:8888/browser/browser/base/content/test/tabview/dummy_page.html");
 
   afterAllTabsLoaded(function () {
     // make sure the tab one is selected because undoCloseTab() would remove
     // the selected tab if it's a blank tab.
     gBrowser.selectedTab = tabOne;
-    showTabView(onTabViewWindowLoaded);
+    showTabView(onTabViewShown);
   });
 }
 
-function onTabViewWindowLoaded() {
+function onTabViewShown() {
   let contentWindow = TabView.getContentWindow();
   let groupItems = contentWindow.GroupItems.groupItems;
   is(groupItems.length, 1, "There is only one group");
   is(groupItems[0].getChildren().length, 3, "The group has three tab items");
 
   gBrowser.removeTab(tabTwo);
   ok(TabView.isVisible(), "Tab View is still visible after removing a tab");
   is(groupItems[0].getChildren().length, 2, "The group has two tab items");
 
-  tabTwo = undoCloseTab(0);
-  whenTabIsReconnected(tabTwo, function() {
+  restoreTab(function (tabTwo) {
     ok(TabView.isVisible(), "Tab View is still visible after restoring a tab");
     is(groupItems[0].getChildren().length, 3, "The group still has three tab items");
 
     // clean up and finish
     hideTabView(function () {
       gBrowser.removeTab(tabOne);
       gBrowser.removeTab(tabTwo);
       finish();
     });
   });
 }
-
-// ----------
-function whenTabIsReconnected(tab, callback) {
-  let tabItem = tab._tabViewTabItem;
-
-  if (tabItem._reconnected) {
-    callback();
-    return;
-  }
-
-  tabItem.addSubscriber(tabItem, "reconnected", function () {
-    tabItem.removeSubscriber(tabItem, "reconnected");
-    callback();
-  });
-}
--- a/browser/base/content/test/tabview/browser_tabview_bug608184.js
+++ b/browser/base/content/test/tabview/browser_tabview_bug608184.js
@@ -20,17 +20,16 @@ function test() {
     TabView.moveTabTo(newTab, null);
 
     // close the related tab
     gBrowser.removeTab(relatedTab);
 
     is(gBrowser.visibleTabs.length, 1, "The number of visible tabs is 1");
     is(gBrowser.visibleTabs[0], origTab, 
       "The original tab is the only visible tab");
-    isnot(newTab._tabViewTabItem.parent.id, newTabGroupItemId, 
+
+    let groupItem = newTab._tabViewTabItem.parent;
+    isnot(groupItem.id, newTabGroupItemId, 
       "The moved tab item has a new group id");
 
-    // clean up
-    gBrowser.removeTab(newTab);
-
-    finish();
+    closeGroupItem(groupItem, finish);
   });
 }
--- a/browser/base/content/test/tabview/browser_tabview_bug608405.js
+++ b/browser/base/content/test/tabview/browser_tabview_bug608405.js
@@ -31,22 +31,24 @@ function test() {
       is(sourceGroup.getChildren().length, 1, 'setup: source group has one child');
       is(targetGroup.getChildren().length, 1, 'setup: target group has one child');
 
       let tabItem = sourceGroup.getChild(0);
       targetGroup.add(tabItem);
 
       // check state after adding tabItem to targetGroup
       is(tabItem.parent, targetGroup, 'tabItem changed groups');
-      is(cw.GroupItems.groupItems.length, 1, 'source group was closed automatically');
+      is(sourceGroup.getChildren().length, 0, 'source group has no children');
       is(targetGroup.getChildren().length, 2, 'target group has now two children');
 
       // cleanup and finish
-      tabItem.close();
-      hideTabView(finishTest);
+      closeGroupItem(sourceGroup, function () {
+        tabItem.close();
+        hideTabView(finishTest);
+      });
     });
   }
 
   waitForExplicitFinish();
 
   showTabView(function () {
     cw = TabView.getContentWindow();
     testAddChildFromAnotherGroup();
--- a/browser/base/content/test/tabview/browser_tabview_bug612470.js
+++ b/browser/base/content/test/tabview/browser_tabview_bug612470.js
@@ -30,19 +30,16 @@ function test() {
     executeSoon(function () {
       is(win.gBrowser.visibleTabs.length, 2, "There are two tabs displayed");
       win.gBrowser.removeTab(tab);
 
       is(groupItem.getChildren().length, 0, "No tabs are in the new group");
       is(win.gBrowser.visibleTabs.length, 1, "There is one tab displayed");
       is(cw.GroupItems.groupItems.length, 2, "There are two groups still");
 
-      showTabView(function () {
-        is(cw.GroupItems.groupItems.length, 1, "There is now only one group");
-        waitForFocus(finish);
-      }, win);
+      waitForFocus(finish);
     });
   };
 
   waitForExplicitFinish();
 
   newWindowWithTabView(onShow, onLoad);
 }
--- a/browser/base/content/test/tabview/browser_tabview_bug613541.js
+++ b/browser/base/content/test/tabview/browser_tabview_bug613541.js
@@ -15,33 +15,16 @@ function test() {
     cw.UI.setActive(groupItem);
 
     for (let i=0; i<numTabs || 0; i++)
       gBrowser.loadOneTab('about:blank', {inBackground: true});
 
     return groupItem;
   }
 
-  let hideGroupItem = function (groupItem, callback) {
-    groupItem.addSubscriber(groupItem, 'groupHidden', function () {
-      groupItem.removeSubscriber(groupItem, 'groupHidden');
-      callback();
-    });
-    groupItem.closeAll();
-  }
-
-  let closeGroupItem = function (groupItem, callback) {
-    afterAllTabsLoaded(function () {
-      hideGroupItem(groupItem, function () {
-        groupItem.closeHidden();
-        callback();
-      });
-    });
-  }
-
   let tests = [];
 
   let next = function () {
     let test = tests.shift();
 
     if (test) {
       // check that the previous test left things as expected
       if (currentTest) {
@@ -209,59 +192,68 @@ function test() {
   // setup: 1 orphan tab
   // action: exit panorama
   // expected: nothing should happen
   let testOrphanTab1 = function () {
     let groupItem = getGroupItem(0);
     let tabItem = groupItem.getChild(0);
     groupItem.remove(tabItem);
 
-    hideTabView(function () {
+    closeGroupItem(groupItem, function () {
       assertNumberOfGroupItems(0);
-      createGroupItem().add(tabItem);
-      next();
+
+      hideTabView(function () {
+        createGroupItem().add(tabItem);
+        next();
+      });
     });
   }
 
   // setup: 1 orphan tab, 1 non-empty group
   // action: close the group
   // expected: nothing should happen
   let testOrphanTab2 = function () {
     let groupItem = getGroupItem(0);
     let tabItem = groupItem.getChild(0);
     groupItem.remove(tabItem);
 
-    assertNumberOfGroupItems(0);
-    let newGroupItem = createGroupItem(1);
-    assertNumberOfGroupItems(1);
+    closeGroupItem(groupItem, function () {
+      assertNumberOfGroupItems(0);
+
+      let newGroupItem = createGroupItem(1);
+      assertNumberOfGroupItems(1);
 
-    closeGroupItem(newGroupItem, function () {
-      assertNumberOfGroupItems(0);
-      createGroupItem().add(tabItem);
-      hideTabView(next);
+      closeGroupItem(newGroupItem, function () {
+        assertNumberOfGroupItems(0);
+        createGroupItem().add(tabItem);
+        hideTabView(next);
+      });
     });
   }
 
   // setup: 1 orphan tab, 1 non-empty group
   // action: hide the group, exit panorama
   // expected: nothing should happen
   let testOrphanTab3 = function () {
     let groupItem = getGroupItem(0);
     let tabItem = groupItem.getChild(0);
     groupItem.remove(tabItem);
 
-    assertNumberOfGroupItems(0);
-    let newGroupItem = createGroupItem(1);
-    assertNumberOfGroupItems(1);
+    closeGroupItem(groupItem, function () {
+      assertNumberOfGroupItems(0);
+
+      let newGroupItem = createGroupItem(1);
+      assertNumberOfGroupItems(1);
 
-    hideGroupItem(newGroupItem, function () {
-      hideTabView(function () {
-        assertNumberOfGroupItems(0);
-        createGroupItem().add(tabItem);
-        next();
+      hideGroupItem(newGroupItem, function () {
+        hideTabView(function () {
+          assertNumberOfGroupItems(0);
+          createGroupItem().add(tabItem);
+          next();
+        });
       });
     });
   }
 
   // setup: 1 non-empty group, 1 empty group
   // action: close non-empty group
   // expected: empty group is re-used, new tab is created and zoomed into
   let testEmptyGroup1 = function () {
--- a/browser/base/content/test/tabview/browser_tabview_bug616729.js
+++ b/browser/base/content/test/tabview/browser_tabview_bug616729.js
@@ -34,20 +34,16 @@ function test() {
     tests.push([tab2, tab1, tab3]);
     tests.push([tab2, tab3, tab1]);
     tests.push([tab3, tab1, tab2]);
     tests.push([tab3, tab2, tab1]);
     tests.push([tab1, tab2]);
     tests.push([tab2, tab1]);
     tests.push([tab1]);
 
-    // test reordering of empty groups - removes the last tab and causes
-    // the groupItem to close
-    tests.push([]);
-
     while (tests.length) {
       let test = tests.shift();
 
       // prepare
       let items = groupItem.getChildren();
       while (test.length < items.length)
         items[items.length-1].close();
 
@@ -58,17 +54,17 @@ function test() {
       groupItem.reorderTabsBasedOnTabItemOrder();
       assertCorrectItemOrder(items);
 
       // revert to original item order
       items.sort(function (a, b) orig.indexOf(a) - orig.indexOf(b));
       groupItem.reorderTabsBasedOnTabItemOrder();
     }
 
-    testMoveBetweenGroups();
+    closeGroupItem(groupItem, testMoveBetweenGroups);
   }
 
   let testMoveBetweenGroups = function () {
     let groupItem = createGroupItem();
     let groupItem2 = createGroupItem();
     
     afterAllTabsLoaded(function () {
       // move item from group1 to group2
--- a/browser/base/content/test/tabview/browser_tabview_bug622872.js
+++ b/browser/base/content/test/tabview/browser_tabview_bug622872.js
@@ -59,21 +59,18 @@ function part1(win) {
     is(win.gBrowser.tabs.length, 1, "Only one tab again.");
     is(win.gBrowser.tabs[0], originalTab, "That one tab is the original tab.");
 
     let groupItems = contentWindow.GroupItems.groupItems;
     is(groupItems.length, 1, "Only one group");
 
     ok(!contentWindow.UI.getActiveOrphanTab(), "There is no active orphan tab.");
     ok(win.TabView.isVisible(), "Tab View is visible.");
-
-    win.gBrowser.tabContainer.addEventListener("TabSelect", function() {
-      win.gBrowser.tabContainer.removeEventListener("TabSelect", arguments.callee, false);
-      executeSoon(part4);
-    }, false);
+  
+    whenTabViewIsHidden(part4, win);
     win.document.getElementById("cmd_newNavigatorTab").doCommand();
   }
 
   // PART 4: verify it opened in the original group, and go back into Panorama
   let part4 = function part4() {
     ok(!win.TabView.isVisible(), "Tab View is hidden");
 
     is(win.gBrowser.tabs.length, 2, "There are two tabs total now.");
--- a/browser/base/content/test/tabview/browser_tabview_bug624265.js
+++ b/browser/base/content/test/tabview/browser_tabview_bug624265.js
@@ -114,17 +114,18 @@ function test() {
     gBrowser.selectedTab = gBrowser.loadOneTab('http://mochi.test:8888/#3', {inBackground: true});
     gBrowser.loadOneTab('http://mochi.test:8888/#4', {inBackground: true});
 
     afterAllTabsLoaded(function () {
       assertNumberOfVisibleTabs(2);
 
       enterAndLeavePrivateBrowsing(function () {
         assertNumberOfVisibleTabs(2);
-        next();
+        gBrowser.selectedTab = gBrowser.tabs[0];
+        closeGroupItem(cw.GroupItems.groupItems[1], next);
       });
     });
   }
 
   waitForExplicitFinish();
 
   // tests for #624265
   tests.push(testUndoCloseTabs);
--- a/browser/base/content/test/tabview/browser_tabview_bug624847.js
+++ b/browser/base/content/test/tabview/browser_tabview_bug624847.js
@@ -36,30 +36,16 @@ function test() {
   let createTab = function (url) {
     return gBrowser.loadOneTab(url || 'http://mochi.test:8888/', {inBackground: true});
   }
 
   let createBlankTab = function () {
     return createTab('about:blank');
   }
 
-  let restoreTab = function (callback) {
-    let tab = undoCloseTab(0);
-
-    if (tab._tabViewTabItem._reconnected) {
-      afterAllTabsLoaded(callback);
-      return;
-    }
-
-    tab._tabViewTabItem.addSubscriber(tab, 'reconnected', function () {
-      tab._tabViewTabItem.removeSubscriber(tab, 'reconnected');
-      afterAllTabsLoaded(callback);
-    });
-  }
-
   let finishTest = function () {
     prefix = 'finish';
     assertValidPrerequisites();
     finish();
   }
 
   let testUndoCloseWithSelectedBlankTab = function () {
     prefix = 'unpinned';
--- a/browser/base/content/test/tabview/browser_tabview_bug625195.js
+++ b/browser/base/content/test/tabview/browser_tabview_bug625195.js
@@ -28,23 +28,20 @@ function test() {
     ok(tabItems.length, 2, "There are two tabItems in this group");
 
     whenTabViewIsHidden(function() {
       popup(gBrowser.tabs[0]);
 
       ok(!document.getElementById("context_closeTab").disabled, "The 'Close tab' menu item is enabled");
       ok(!document.getElementById("context_openTabInWindow").disabled, "The 'Move to New Window' menu item is enabled");
 
-      let newTabTwo = gBrowser.selectedTab;
       gBrowser.selected = originalTab;
-
       gBrowser.removeTab(newTabOne);
-      gBrowser.removeTab(newTabTwo);
 
-      finish();
+      closeGroupItem(newGroup, finish);
     });
     let newGroup = contentWindow.GroupItems.newGroup();
     newGroup.newTab();
   });
 }
 
 function popup(tab) {
   document.popupNode = tab;
--- a/browser/base/content/test/tabview/browser_tabview_bug626368.js
+++ b/browser/base/content/test/tabview/browser_tabview_bug626368.js
@@ -34,17 +34,19 @@ function test() {
     synthesizeMiddleMouseDrag(tabContainer, 200);
     is(groupItem.getChild(0), tabItem, 'tabItem was not closed');
     ok(bounds.equals(tabItem.getBounds()), 'bounds did not change');
 
     // try to drag and let the mouse stay within tab bounds
     synthesizeMiddleMouseDrag(tabContainer, 10);
     ok(!groupItem.getChild(0), 'tabItem was closed');
 
-    hideTabView(finish);
+    closeGroupItem(groupItem, function () {
+      hideTabView(finish);
+    });
   }
 
   waitForExplicitFinish();
 
   showTabView(function () {
     cw = TabView.getContentWindow();
     afterAllTabsLoaded(testDragAndDropWithMiddleMouseButton);
   });
--- a/browser/base/content/test/tabview/browser_tabview_bug627288.js
+++ b/browser/base/content/test/tabview/browser_tabview_bug627288.js
@@ -10,32 +10,34 @@ function test() {
 
     afterAllTabsLoaded(function () {
       let tabItem = tab._tabViewTabItem;
       let data = tabItem.getStorageData(true);
       gBrowser.removeTab(tab);
 
       cw.TabItems.pauseReconnecting();
       tab = gBrowser.loadOneTab('http://mochi.test:8888/', {inBackground: true});
-      cw.Storage.saveTab(tab, data);
 
-      whenTabAttrModified(tab, function () {
+      afterAllTabsLoaded(function () {
         tabItem = tab._tabViewTabItem;
 
-        // Hook into loadedCachedImageData since loading cached thumbnails 
-        // is asynchronous.
-        tabItem.addSubscriber(tabItem, "loadedCachedImageData", function(item) {
-          item.removeSubscriber(item, "loadedCachedImageData");
+        tabItem.addSubscriber(tabItem, "savedCachedImageData", function () {
+          tabItem.removeSubscriber(tabItem, "savedCachedImageData");
+
+          tabItem.addSubscriber(tabItem, "loadedCachedImageData", function () {
+            tabItem.removeSubscriber(tabItem, "loadedCachedImageData");
 
-          ok(tabItem.isShowingCachedData(), 'tabItem shows cached data');
+            ok(tabItem.isShowingCachedData(), 'tabItem shows cached data');
+            testChangeUrlAfterReconnect();
+          });
 
-          testChangeUrlAfterReconnect();
+          cw.TabItems.resumeReconnecting();
         });
 
-        cw.TabItems.resumeReconnecting();
+        cw.Storage.saveTab(tab, data);
       });
     });
   }
 
   let testChangeUrlAfterReconnect = function () {
     tab.linkedBrowser.loadURI('http://mochi.test:8888/browser/');
 
     whenTabAttrModified(tab, function () {
--- a/browser/base/content/test/tabview/browser_tabview_bug627736.js
+++ b/browser/base/content/test/tabview/browser_tabview_bug627736.js
@@ -20,30 +20,35 @@ function onTabViewWindowLoaded(win) {
       immediately: true,
       bounds: {left: 20, top: 20, width: 400, height: 400}
     });
     contentWindow.UI.setActive(group);
     win.gBrowser.loadOneTab('about:blank', {inBackground: true});
   
     is(group.getChildren().length, 1, "The group has one child now.");
     let tab = group.getChild(0);
-  
+
+    function finalize() {
+      is(contentWindow.GroupItems.getActiveGroupItem(), originalGroup,
+        "The original group is active.");
+      is(contentWindow.UI.getActiveTab(), originalTab._tabViewTabItem,
+        "The original tab is active");
+
+      callback();
+    }
+
     function check() {
       if (groupOrTab == 'group') {
         group.removeSubscriber(group, "groupHidden", check);
         group.closeHidden();
-      } else
+        finalize();
+      } else {
         tab.removeSubscriber(tab, "tabRemoved", check);
-  
-      is(contentWindow.GroupItems.getActiveGroupItem(), originalGroup,
-        "The original group is active.");
-      is(contentWindow.UI.getActiveTab(), originalTab._tabViewTabItem,
-        "The original tab is active");
-  
-      callback();
+        closeGroupItem(group, finalize);
+      }
     }
   
     if (groupOrTab == 'group') {
       group.addSubscriber(group, "groupHidden", check);
       group.closeAll();
     } else {
       tab.addSubscriber(tab, "tabRemoved", check);
       tab.close();
@@ -53,9 +58,9 @@ function onTabViewWindowLoaded(win) {
   // PHASE 1: create a group with a tab and close the group.
   openAndClose("group", function postPhase1() {
     // PHASE 2: create a group with a tab and close the tab.
     openAndClose("tab", function postPhase2() {
       win.close();
       finish();
     });
   });
-}
\ No newline at end of file
+}
--- a/browser/base/content/test/tabview/browser_tabview_bug628270.js
+++ b/browser/base/content/test/tabview/browser_tabview_bug628270.js
@@ -20,30 +20,16 @@ function test() {
         groupItem.close();
     });
   }
 
   let getGroupItem = function (index) {
     return cw.GroupItems.groupItems[index];
   }
 
-  let restoreTab = function (callback) {
-    let tab = undoCloseTab(0);
-
-    if (tab._tabViewTabItem._reconnected) {
-      callback();
-      return;
-    }
-
-    tab._tabViewTabItem.addSubscriber(tab, 'reconnected', function () {
-      tab._tabViewTabItem.removeSubscriber(tab, 'reconnected');
-      afterAllTabsLoaded(callback);
-    });
-  }
-
   let activateFirstGroupItem = function () {
     let activeTabItem = getGroupItem(0).getChild(0);
     cw.GroupItems.updateActiveGroupItemAndTabBar(activeTabItem);
   }
 
   let assertTabViewIsHidden = function () {
     ok(!TabView.isVisible(), prefix + ': tabview is hidden');
   }
@@ -86,19 +72,17 @@ function test() {
 
     gBrowser.removeTab(tabItem.tab);
     assertNumberOfTabsInGroup(groupItem, 1);
 
     restoreTab(function () {
       assertNumberOfTabsInGroup(groupItem, 2);
 
       activateFirstGroupItem();
-      gBrowser.removeTab(gBrowser.tabs[1]);
-      gBrowser.removeTab(gBrowser.tabs[1]);
-      finishTest();
+      closeGroupItem(groupItem, finishTest);
     });
   }
 
   waitForExplicitFinish();
   assertTabViewIsHidden();
   registerCleanupFunction(function () TabView.hide());
 
   showTabView(function () {
--- a/browser/base/content/test/tabview/browser_tabview_bug630157.js
+++ b/browser/base/content/test/tabview/browser_tabview_bug630157.js
@@ -30,17 +30,16 @@ function test() {
     for (let i=0; i<2; i++)
       EventUtils.synthesizeMouseAtCenter(target, {button: button || 0}, cw);
   }
 
   let finishTest = function () {
     let tabItem = gBrowser.tabs[0]._tabViewTabItem;
     cw.GroupItems.updateActiveGroupItemAndTabBar(tabItem);
 
-    gBrowser.removeTab(gBrowser.tabs[1]);
     assertNumberOfGroups(1);
     assertNumberOfTabs(1);
 
     finish();
   }
 
   let testDoubleClick = function () {
     let groupItem = createGroupItem();
@@ -64,19 +63,20 @@ function test() {
 
     // simulate double click with right mouse button
     simulateDoubleClick(container, 2);
     assertNumberOfTabs(1);
 
     // simulate double click with left mouse button
     let container = groupItem.container;
     simulateDoubleClick(container);
-    assertNumberOfTabs(2);
+    assertNumberOfTabs(1);
 
-    whenTabViewIsHidden(finishTest);
+    groupItem.close();
+    hideTabView(finishTest);
   }
 
   waitForExplicitFinish();
   registerCleanupFunction(function () TabView.hide());
 
   showTabView(function () {
     cw = TabView.getContentWindow();
     testDoubleClick();
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/tabview/browser_tabview_bug633190.js
@@ -0,0 +1,86 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+let origTab = gBrowser.visibleTabs[0];
+let contentWindow;
+
+function test() {
+  waitForExplicitFinish();
+
+  test1();
+}
+
+// Open a new tab when the active tab item belongs to a group item.
+function test1() {
+  registerCleanupFunction(function () TabView.hide());
+
+  showTabView(function() {
+    ok(origTab._tabViewTabItem.parent, "The original tab belongs to a group");
+
+    contentWindow = TabView.getContentWindow();
+    contentWindow.UI.setActive(origTab._tabViewTabItem);
+
+    testCreateTabAndThen(test2);
+  });
+}
+
+// Open a new tab when the active tab item is nothing.
+function test2() {
+  showTabView(function() {
+    contentWindow.UI.setActive(null, { onlyRemoveActiveTab: true });
+
+    testCreateTabAndThen(test3);
+  });
+}
+
+// Open a new tab when the active tab item is an orphan tab.
+function test3() {
+  showTabView(function() {
+    let groupItem = origTab._tabViewTabItem.parent;
+    let tabItems = groupItem.getChildren();
+    is(tabItems.length, 3, "There are 3 tab items in the group");
+
+    let lastTabItem = tabItems[tabItems.length - 1];
+    groupItem.remove(lastTabItem);
+
+    let orphanedTabs = contentWindow.GroupItems.getOrphanedTabs();
+    is(orphanedTabs.length, 1, "There should be 1 orphan tab");
+    is(orphanedTabs[0], lastTabItem, "The tab item is the same as the orphan tab");
+
+    contentWindow.UI.setActive(lastTabItem);
+
+    testCreateTabAndThen(function() {
+      hideTabView(finish);
+    });
+  });
+}
+
+function testCreateTabAndThen(callback) {
+  ok(TabView.isVisible(), "Tab View is visible");
+
+  // detect tab open and zoomed in event.
+  let onTabOpen = function(event) {
+    gBrowser.tabContainer.removeEventListener("TabOpen", onTabOpen, false);
+
+    // ensure that the default tabview listener is called before so the 
+    // tab._tabViewTabItem exists
+    executeSoon(function() {
+      let tab = event.target;
+      tabItem = tab._tabViewTabItem;
+      ok(tabItem, "Tab item is available after tab open");
+
+      registerCleanupFunction(function () gBrowser.removeTab(tab))
+
+      tabItem.addSubscriber(tabItem, "zoomedIn", function() {
+        tabItem.removeSubscriber(tabItem, "zoomedIn");
+
+        is(gBrowser.selectedTab, tab,
+          "The selected tab is the same as the newly opened tab");
+        executeSoon(callback);
+      });
+    });
+  }
+  gBrowser.tabContainer.addEventListener("TabOpen", onTabOpen, false);
+  // use the menu item (the same as pressing cmd/ctrl + t)
+  document.getElementById("menu_newNavigatorTab").doCommand();
+}
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/tabview/browser_tabview_bug662266.js
@@ -0,0 +1,39 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+function test() {
+  waitForExplicitFinish();
+
+  newWindowWithTabView(function (win) {
+    registerCleanupFunction(function () win.close());
+
+    for (let i = 0; i < 4; i++)
+      win.gBrowser.loadOneTab("about:blank", {inBackground: true});
+
+    let cw = win.TabView.getContentWindow();
+    let groupItem = cw.GroupItems.groupItems[0];
+    let children = groupItem.getChildren();
+
+    groupItem.setSize(200, 200, true);
+    ok(groupItem.isStacked(), "groupItem is now stacked");
+    is(win.gBrowser.tabs.length, 5, "we have five tabs");
+
+    groupItem.addSubscriber(groupItem, "expanded", function onExpanded() {
+      groupItem.removeSubscriber(groupItem, "expanded");
+
+      ok(groupItem.expanded, "groupItem is expanded");
+      let bounds = children[1].getBounds();
+
+      // remove two tabs and see if the remaining tabs are re-arranged to fill
+      // the resulting gaps
+      for (let i = 0; i < 2; i++) {
+        children[1].close();
+        ok(bounds.equals(children[1].getBounds()), "tabItems were re-arranged");
+      }
+
+      waitForFocus(finish);
+    });
+
+    groupItem.expand();
+  });
+}
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/tabview/browser_tabview_bug665502.js
@@ -0,0 +1,33 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+function test() {
+  waitForExplicitFinish();
+
+  let onLoad = function (win) {
+    for (let i = 0; i < 2; i++)
+      win.gBrowser.addTab();
+  };
+
+  let onShow = function (win) {
+    registerCleanupFunction(function () win.close());
+
+    let cw = win.TabView.getContentWindow();
+    let groupItem = cw.GroupItems.groupItems[0];
+
+    groupItem.setSize(400, 200, true);
+
+    let tabItem = groupItem.getChild(0);
+    let bounds = tabItem.getBounds();
+
+    is(groupItem.getActiveTab(), tabItem, "the first tab is active");
+    tabItem.close();
+
+    is(groupItem.getChildren().indexOf(tabItem), -1, "tabItem got removed");
+    ok(bounds.equals(groupItem.getChild(0).getBounds()), "tabItem bounds didn't change");
+
+    finish();
+  };
+
+  newWindowWithTabView(onShow, onLoad);
+}
--- a/browser/base/content/test/tabview/browser_tabview_dragdrop.js
+++ b/browser/base/content/test/tabview/browser_tabview_dragdrop.js
@@ -80,17 +80,17 @@ function addTest(contentWindow, groupOne
       groupTwo.closeAll();
       // close undo group
       let closeButton = groupTwo.$undoContainer.find(".close");
       EventUtils.sendMouseEvent(
         { type: "click" }, closeButton[0], contentWindow);
     };
     groupTwo.addSubscriber(groupTwo, "close", function() {
       groupTwo.removeSubscriber(groupTwo, "close");
-      finish();  
+      closeGroupItem(groupOne, finish);
     });
     window.addEventListener("tabviewhidden", onTabViewHidden, false);
     gBrowser.selectedTab = originalTab;
   }
   groupTwo.addSubscriber(groupTwo, "childAdded", endGame);
   
   simulateDragDrop(tabItem.container, offsetX, offsetY, contentWindow);
 }
--- a/browser/base/content/test/tabview/browser_tabview_group.js
+++ b/browser/base/content/test/tabview/browser_tabview_group.js
@@ -90,17 +90,17 @@ function testGroupItemWithTabItem(conten
 
       // Now there should only be one tab left, so we need to hide TabView
       // and go into that tab.
       is(gBrowser.tabs.length, 1, "There is only one tab left");
             
       let endGame = function() {
         window.removeEventListener("tabviewhidden", endGame, false);
         ok(!TabView.isVisible(), "Tab View is hidden");
-        finish();
+        closeGroupItem(groupItem, finish);
       };
       window.addEventListener("tabviewhidden", endGame, false);
 
       // after the last selected tabitem is closed, there would be not active
       // tabitem on the UI so we set the active tabitem before toggling the 
       // visibility of tabview
       let tabItems = contentWindow.TabItems.getItems();
       ok(tabItems[0], "A tab item exists");
--- a/browser/base/content/test/tabview/browser_tabview_privatebrowsing.js
+++ b/browser/base/content/test/tabview/browser_tabview_privatebrowsing.js
@@ -17,71 +17,78 @@ function test() {
   showTabView(onTabViewLoadedAndShown);
 }
 
 // -----------
 function onTabViewLoadedAndShown() {
   ok(TabView.isVisible(), "Tab View is visible");
 
   // Establish initial state
-  contentWindow = document.getElementById("tab-view").contentWindow;  
+  contentWindow = document.getElementById("tab-view").contentWindow;
   verifyCleanState("start");
-  
+
   // register a clean up for private browsing just in case
   registerCleanupFunction(function() {
     pb.privateBrowsingEnabled = false;
   });
-  
+
   // create a group
   let box = new contentWindow.Rect(20, 20, 180, 180);
   let groupItem = new contentWindow.GroupItem([], {bounds: box, title: "test1"});
-  let id = groupItem.id; 
+  let id = groupItem.id;
   is(contentWindow.GroupItems.groupItems.length, 2, "we now have two groups");
   registerCleanupFunction(function() {
     contentWindow.GroupItems.groupItem(id).close();
   });
-  
+
   // make it the active group so new tabs will be added to it
   contentWindow.UI.setActive(groupItem);
-  
+
   // collect the group titles
   let count = contentWindow.GroupItems.groupItems.length;
   for (let a = 0; a < count; a++) {
     let gi = contentWindow.GroupItems.groupItems[a];
     groupTitles[a] = gi.getTitle();
   }
-  
+
   // Create a second tab
-  gBrowser.addTab("about:robots");
+  gBrowser.loadOneTab("about:robots", { inBackground: false });
   is(gBrowser.tabs.length, 2, "we now have 2 tabs");
   registerCleanupFunction(function() {
     gBrowser.removeTab(gBrowser.tabs[1]);
   });
 
   afterAllTabsLoaded(function() {
-    // Get normal tab urls
-    for (let a = 0; a < gBrowser.tabs.length; a++)
-      normalURLs.push(gBrowser.tabs[a].linkedBrowser.currentURI.spec);
+    showTabView(function() {
+      // Get normal tab urls
+      for (let a = 0; a < gBrowser.tabs.length; a++)
+        normalURLs.push(gBrowser.tabs[a].linkedBrowser.currentURI.spec);
 
-    // verify that we're all set up for our test
-    verifyNormal();
+      // verify that we're all set up for our test
+      verifyNormal();
+
+      // go into private browsing and make sure Tab View becomes hidden
+      togglePBAndThen(function() {
+        whenTabViewIsHidden(function() {
+          ok(!TabView.isVisible(), "Tab View is no longer visible");
 
-    // go into private browsing and make sure Tab View becomes hidden
-    togglePBAndThen(function() {
-      ok(!TabView.isVisible(), "Tab View is no longer visible");
-      verifyPB();
-      
-      // exit private browsing and make sure Tab View is shown again
-      togglePBAndThen(function() {
-        ok(TabView.isVisible(), "Tab View is visible again");
-        verifyNormal();
+          verifyPB();
 
-        hideTabView(onTabViewHidden);
+          // exit private browsing and make sure Tab View is shown again
+          togglePBAndThen(function() {
+            whenTabViewIsShown(function() {
+              ok(TabView.isVisible(), "Tab View is visible again");
+              verifyNormal();
+
+              hideTabView(onTabViewHidden);
+            });
+          });
+        });
       });
-    });
+    }); 
   });
 }
 
 // -----------
 function onTabViewHidden() {
   ok(!TabView.isVisible(), "Tab View is not visible");
   
   // go into private browsing and make sure Tab View remains hidden
--- a/browser/base/content/test/tabview/head.js
+++ b/browser/base/content/test/tabview/head.js
@@ -40,24 +40,29 @@ function createGroupItemWithBlankTabs(wi
   let urls = [];
   while(numNewTabs--)
     urls.push("about:blank");
   return createGroupItemWithTabs(win, width, height, padding, urls, animate);
 }
 
 // ----------
 function closeGroupItem(groupItem, callback) {
-  groupItem.addSubscriber(groupItem, "groupHidden", function() {
-    groupItem.removeSubscriber(groupItem, "groupHidden");
-    groupItem.addSubscriber(groupItem, "close", function() {
-      groupItem.removeSubscriber(groupItem, "close");
-      callback();
+  groupItem.addSubscriber(groupItem, "close", function () {
+    groupItem.removeSubscriber(groupItem, "close");
+    if ("function" == typeof callback)
+      executeSoon(callback);
+  });
+
+  if (groupItem.getChildren().length) {
+    groupItem.addSubscriber(groupItem, "groupHidden", function () {
+      groupItem.removeSubscriber(groupItem, "groupHidden");
+      groupItem.closeHidden();
     });
-    groupItem.closeHidden();
-  });
+  }
+
   groupItem.closeAll();
 }
 
 // ----------
 function afterAllTabItemsUpdated(callback, win) {
   win = win || window;
   let tabItems = win.document.getElementById("tab-view").contentWindow.TabItems;
 
@@ -285,16 +290,19 @@ function whenWindowStateReady(win, callb
   win.addEventListener("SSWindowStateReady", function onReady() {
     win.removeEventListener("SSWindowStateReady", onReady, false);
     executeSoon(callback);
   }, false);
 }
 
 // ----------
 function newWindowWithState(state, callback) {
+  const ss = Cc["@mozilla.org/browser/sessionstore;1"]
+             .getService(Ci.nsISessionStore);
+
   let opts = "chrome,all,dialog=no,height=800,width=800";
   let win = window.openDialog(getBrowserURL(), "_blank", opts);
 
   whenWindowLoaded(win, function () {
     ss.setWindowState(win, JSON.stringify(state), true);
   });
 
   whenWindowStateReady(win, function () {
@@ -304,18 +312,22 @@ function newWindowWithState(state, callb
 
 // ----------
 function restoreTab(callback, index, win) {
   win = win || window;
 
   let tab = win.undoCloseTab(index || 0);
   let tabItem = tab._tabViewTabItem;
 
+  let finalize = function () {
+    afterAllTabsLoaded(function () callback(tab), win);
+  };
+
   if (tabItem._reconnected) {
-    afterAllTabsLoaded(callback, win);
+    finalize();
     return;
   }
 
   tab._tabViewTabItem.addSubscriber(tab, "reconnected", function onReconnected() {
     tab._tabViewTabItem.removeSubscriber(tab, "reconnected");
-    afterAllTabsLoaded(callback, win);
+    finalize();
   });
 }
--- a/browser/base/jar.mn
+++ b/browser/base/jar.mn
@@ -16,16 +16,18 @@ browser.jar:
 *       content/browser/aboutDialog.js                (content/aboutDialog.js)
 *       content/browser/aboutDialog.css               (content/aboutDialog.css)
 *       content/browser/aboutRobots.xhtml             (content/aboutRobots.xhtml)
 *       content/browser/aboutHome.xhtml               (content/aboutHome.xhtml)
 *       content/browser/aboutHome.js                  (content/aboutHome.js)
 *       content/browser/aboutHome.css                 (content/aboutHome.css)
         content/browser/aboutHome-restore-icon.png    (content/aboutHome-restore-icon.png)
         content/browser/aboutHome-restore-icon-small.png    (content/aboutHome-restore-icon-small.png)
+        content/browser/aboutHome-snippet1.png        (content/aboutHome-snippet1.png)
+        content/browser/aboutHome-snippet2.png        (content/aboutHome-snippet2.png)
         content/browser/aboutRobots-icon.png          (content/aboutRobots-icon.png)
         content/browser/aboutRobots-widget-left.png   (content/aboutRobots-widget-left.png)
 *       content/browser/browser.css                   (content/browser.css)
 *       content/browser/browser.js                    (content/browser.js)
 *       content/browser/browser.xul                   (content/browser.xul)
 *       content/browser/browser-tabPreviews.xml       (content/browser-tabPreviews.xml)
 *       content/browser/fullscreen-video.xhtml        (content/fullscreen-video.xhtml)
 *       content/browser/inspector.html                (content/inspector.html)
--- a/browser/components/places/content/browserPlacesViews.js
+++ b/browser/components/places/content/browserPlacesViews.js
@@ -397,19 +397,19 @@ PlacesViewBase.prototype = {
    *        The livemark container popup
    */
   _ensureLivemarkStatusMenuItem:
   function PVB_ensureLivemarkStatusMenuItem(aPopup) {
     let itemId = aPopup._placesNode.itemId;
     let as = PlacesUtils.annotations;
 
     let lmStatus = null;
-    if (as.itemHasAnnotation(itemId, "livemark/loadfailed"))
+    if (as.itemHasAnnotation(itemId, PlacesUtils.LMANNO_LOADFAILED))
       lmStatus = "bookmarksLivemarkFailed";
-    else if (as.itemHasAnnotation(itemId, "livemark/loading"))
+    else if (as.itemHasAnnotation(itemId, PlacesUtils.LMANNO_LOADING))
       lmStatus = "bookmarksLivemarkLoading";
 
     let lmStatusElt = aPopup._lmStatusMenuItem;
     if (lmStatus && !lmStatusElt) {
       // Create the status menuitem and cache it in the popup object.
       lmStatusElt = document.createElement("menuitem");
       lmStatusElt.setAttribute("lmStatus", lmStatus);
       lmStatusElt.setAttribute("label", PlacesUIUtils.getString(lmStatus));
@@ -461,27 +461,31 @@ PlacesViewBase.prototype = {
     if (!icon)
       elt.removeAttribute("image");
     else if (icon != elt.getAttribute("image"))
       elt.setAttribute("image", icon);
   },
 
   nodeAnnotationChanged:
   function PVB_nodeAnnotationChanged(aPlacesNode, aAnno) {
-    // All livemarks have a feedURI, so use it as our indicator.
+    let elt = aPlacesNode._DOMElement;
+    if (!elt)
+      throw "aPlacesNode must have _DOMElement set";
+
+    // All livemarks have a feedURI, so use it as our indicator of a livemark
+    // being modified.
     if (aAnno == PlacesUtils.LMANNO_FEEDURI) {
-      let elt = aPlacesNode._DOMElement;
-      if (!elt)
-        throw "aPlacesNode must have _DOMElement set";
-
       let menu = elt.parentNode;
       if (!menu.hasAttribute("livemark"))
         menu.setAttribute("livemark", "true");
+    }
 
-      // Add or remove the livemark status menuitem.
+    if ([PlacesUtils.LMANNO_LOADING,
+         PlacesUtils.LMANNO_LOADFAILED].indexOf(aAnno) != -1) {
+      // Loading status changed, update the livemark status menuitem.
       this._ensureLivemarkStatusMenuItem(elt);
     }
   },
 
   nodeTitleChanged:
   function PVB_nodeTitleChanged(aPlacesNode, aNewTitle) {
     let elt = aPlacesNode._DOMElement;
     if (!elt)
@@ -1164,20 +1168,27 @@ PlacesToolbar.prototype = {
 
     if (elt.parentNode == this._rootElt) {
       // Node is on the toolbar.
 
       // All livemarks have a feedURI, so use it as our indicator.
       if (aAnno == PlacesUtils.LMANNO_FEEDURI) {
         elt.setAttribute("livemark", true);
       }
-      return;
+
+      if ([PlacesUtils.LMANNO_LOADING,
+           PlacesUtils.LMANNO_LOADFAILED].indexOf(aAnno) != -1) {
+        // Loading status changed, update the livemark status menuitem.
+        this._ensureLivemarkStatusMenuItem(elt.firstChild);
+      }
     }
-
-    PlacesViewBase.prototype.nodeAnnotationChanged.apply(this, arguments);
+    else {
+      // Node is in a submenu.
+      PlacesViewBase.prototype.nodeAnnotationChanged.apply(this, arguments);
+    }
   },
 
   nodeTitleChanged: function PT_nodeTitleChanged(aPlacesNode, aNewTitle) {
     let elt = aPlacesNode._DOMElement;
     if (!elt)
       throw "aPlacesNode must have _DOMElement set";
 
     // There's no UI representation for the root node, thus there's
--- a/browser/components/places/content/editBookmarkOverlay.js
+++ b/browser/components/places/content/editBookmarkOverlay.js
@@ -613,20 +613,22 @@ var gEditItemOverlay = {
   onSiteLocationFieldBlur: function EIO_onSiteLocationFieldBlur() {
     var uri = null;
     try {
       uri = PlacesUIUtils.createFixedURI(this._element("siteLocationField").value);
     }
     catch(ex) {  }
 
     var currentSiteURI = PlacesUtils.livemarks.getSiteURI(this._itemId);
-    if (!uri || !currentSiteURI.equals(uri)) {
-      var txn = PlacesUIUtils.ptm.editLivemarkSiteURI(this._itemId, uri);
-      PlacesUIUtils.ptm.doTransaction(txn);
+    if ((!uri && !currentSiteURI) ||
+        (uri && currentSiteURI && currentSiteURI.equals(uri))) {
+      return;
     }
+    var txn = PlacesUIUtils.ptm.editLivemarkSiteURI(this._itemId, uri);
+    PlacesUIUtils.ptm.doTransaction(txn);
   },
 
   onLoadInSidebarCheckboxCommand:
   function EIO_onLoadInSidebarCheckboxCommand() {
     var loadInSidebarChecked = this._element("loadInSidebarCheckbox").checked;
     var txn = PlacesUIUtils.ptm.setLoadInSidebar(this._itemId,
                                                  loadInSidebarChecked);
     PlacesUIUtils.ptm.doTransaction(txn);
--- a/browser/components/places/tests/Makefile.in
+++ b/browser/components/places/tests/Makefile.in
@@ -43,11 +43,11 @@ VPATH		= @srcdir@
 relativesrcdir = browser/components/places/tests
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE		= test_browser_places
 
 XPCSHELL_TESTS = unit
 
-DIRS = browser chrome perf
+DIRS = browser chrome
 
 include $(topsrcdir)/config/rules.mk
--- a/browser/components/places/tests/browser/browser_0_library_left_pane_migration.js
+++ b/browser/components/places/tests/browser/browser_0_library_left_pane_migration.js
@@ -39,27 +39,17 @@
 /**
  *  Test we correctly migrate Library left pane to the latest version.
  *  Note: this test MUST be the first between browser chrome tests, or results
  *        of next tests could be unexpected due to PlacesUIUtils getters.
  */
 
 const TEST_URI = "http://www.mozilla.org/";
 
-var ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
-         getService(Ci.nsIWindowWatcher);
-
-function windowObserver(aSubject, aTopic, aData) {
-  if (aTopic != "domwindowopened")
-    return;
-  ww.unregisterNotification(windowObserver);
-  var organizer = aSubject.QueryInterface(Ci.nsIDOMWindow);
-  organizer.addEventListener("load", function onLoad(event) {
-    organizer.removeEventListener("load", onLoad, false);
-    executeSoon(function () {
+function onLibraryReady(organizer) {
       // Check left pane.
       ok(PlacesUIUtils.leftPaneFolderId > 0,
          "Left pane folder correctly created");
       var leftPaneItems =
         PlacesUtils.annotations
                    .getItemsWithAnnotation(PlacesUIUtils.ORGANIZER_FOLDER_ANNO);
       is(leftPaneItems.length, 1,
          "We correctly have only 1 left pane folder");
@@ -78,18 +68,16 @@ function windowObserver(aSubject, aTopic
       is(organizer.PlacesOrganizer._places.selectedNode.itemId,
          PlacesUIUtils.leftPaneQueries["History"],
          "Library left pane is populated and working");
 
       // Close Library window.
       organizer.close();
       // No need to cleanup anything, we have a correct left pane now.
       finish();
-    });
-  }, false);
 }
 
 function test() {
   waitForExplicitFinish();
   // Sanity checks.
   ok(PlacesUtils, "PlacesUtils is running in chrome context");
   ok(PlacesUIUtils, "PlacesUIUtils is running in chrome context");
   ok(PlacesUIUtils.ORGANIZER_LEFTPANE_VERSION > 0,
@@ -128,15 +116,10 @@ function test() {
   is(leftPaneItems[0], fakeLeftPaneRoot, "left pane root itemId is correct");
 
   // Check version.
   var version = PlacesUtils.annotations.getItemAnnotation(fakeLeftPaneRoot,
                                                           PlacesUIUtils.ORGANIZER_FOLDER_ANNO);
   is(version, PlacesUIUtils.ORGANIZER_LEFTPANE_VERSION - 1, "Left pane version correctly set");
 
   // Open Library, this will upgrade our left pane version.
-  ww.registerNotification(windowObserver);
-  ww.openWindow(null,
-                "chrome://browser/content/places/places.xul",
-                "",
-                "chrome,toolbar=yes,dialog=no,resizable",
-                null);
+  openLibrary(onLibraryReady);
 }
--- a/browser/components/places/tests/browser/browser_410196_paste_into_tags.js
+++ b/browser/components/places/tests/browser/browser_410196_paste_into_tags.js
@@ -19,22 +19,22 @@ Components.utils.import("resource://gre/
 const TEST_URL = "http://example.com/";
 const MOZURISPEC = "http://mozilla.com/";
 
 let gLibrary;
 let PlacesOrganizer;
 
 function test() {
   waitForExplicitFinish();
-  gLibrary = window.openDialog("chrome://browser/content/places/places.xul",
-                               "", "chrome,toolbar=yes,dialog=no,resizable");
-  waitForFocus(onLibraryReady, gLibrary);
+  openLibrary(onLibraryReady);
 }
 
-function onLibraryReady() {
+function onLibraryReady(library) {
+  gLibrary = library;
+
   ok(PlacesUtils, "PlacesUtils in scope");
   ok(PlacesUIUtils, "PlacesUIUtils in scope");
 
   PlacesOrganizer = gLibrary.PlacesOrganizer;
   ok(PlacesOrganizer, "Places organizer in scope");
 
   tests.makeHistVisit();
   tests.makeTag();
--- a/browser/components/places/tests/browser/browser_forgetthissite_single.js
+++ b/browser/components/places/tests/browser/browser_forgetthissite_single.js
@@ -53,38 +53,30 @@ function waitForClearHistory(aCallback) 
 
   let hs = Cc["@mozilla.org/browser/nav-history-service;1"].
            getService(Ci.nsINavHistoryService);
   hs.QueryInterface(Ci.nsIBrowserHistory).removeAllPages();
 }
 
 function test() {
   // initialization
-  let ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
-           getService(Ci.nsIWindowWatcher);
   waitForExplicitFinish();
 
   // Add a history entry.
   let TEST_URIs = ["http://www.mozilla.org/test1", "http://www.mozilla.org/test2"];
   ok(PlacesUtils, "checking PlacesUtils, running in chrome context?");
   let history = PlacesUtils.history;
   TEST_URIs.forEach(function(TEST_URI) {
     let visitId = history.addVisit(PlacesUtils._uri(TEST_URI), Date.now() * 1000,
                                    null, PlacesUtils.history.TRANSITION_TYPED, false, 0);
     ok(visitId > 0, TEST_URI + " successfully marked visited");
   });
 
   function testForgetThisSiteVisibility(selectionCount, funcNext) {
-    function observer(aSubject, aTopic, aData) {
-      if (aTopic != "domwindowopened")
-        return;
-      ww.unregisterNotification(observer);
-      let organizer = aSubject.QueryInterface(Ci.nsIDOMWindow);
-      SimpleTest.waitForFocus(function() {
-        executeSoon(function() {
+    openLibrary(function (organizer) {
           // Select History in the left pane.
           organizer.PlacesOrganizer.selectLeftPaneQuery('History');
           let PO = organizer.PlacesOrganizer;
           let histContainer = PO._places.selectedNode.QueryInterface(Ci.nsINavHistoryContainerResultNode);
           histContainer.containerOpen = true;
           PO._places.selectNode(histContainer.getChild(0));
           // Select the first history entry.
           let doc = organizer.document;
@@ -101,43 +93,31 @@ function test() {
             let forgetThisSite = doc.getElementById("placesContext_deleteHost");
             let hideForgetThisSite = (selectionCount != 1);
             is(forgetThisSite.hidden, hideForgetThisSite,
               "The Forget this site menu item should " + (hideForgetThisSite ? "" : "not ") +
               "be hidden with " + selectionCount + " items selected");
             // Close the context menu
             contextmenu.hidePopup();
             // Wait for the Organizer window to actually be closed
-            function closeObserver(aSubject, aTopic, aData) {
-              if (aTopic != "domwindowclosed")
-                return;
-              ww.unregisterNotification(closeObserver);
+            organizer.addEventListener("unload", function () {
+              organizer.removeEventListener("unload", arguments.callee, false);
               // Proceed
               funcNext();
-            }
-            ww.registerNotification(closeObserver);
+            }, false);
             // Close Library window.
             organizer.close();
           }, true);
           // Get cell coordinates
           var x = {}, y = {}, width = {}, height = {};
           tree.treeBoxObject.getCoordsForCellItem(0, tree.columns[0], "text",
                                                   x, y, width, height);
           // Initiate a context menu for the selected cell
           EventUtils.synthesizeMouse(tree.body, x.value + width.value / 2, y.value + height.value / 2, {type: "contextmenu"}, organizer);
-        });
-      }, organizer);
-    }
-
-    ww.registerNotification(observer);
-    ww.openWindow(null,
-                  "chrome://browser/content/places/places.xul",
-                  "",
-                  "chrome,toolbar=yes,dialog=no,resizable",
-                  null);
+    });
   }
 
   testForgetThisSiteVisibility(1, function() {
     testForgetThisSiteVisibility(2, function() {
       // Cleanup
       waitForClearHistory(finish);
     });
   });
--- a/browser/components/places/tests/browser/browser_library_batch_delete.js
+++ b/browser/components/places/tests/browser/browser_library_batch_delete.js
@@ -91,35 +91,20 @@ gTests.push({
 
 function test() {
   waitForExplicitFinish();
   registerCleanupFunction(function () {
     PlacesUtils.bookmarks
                .removeFolderChildren(PlacesUtils.unfiledBookmarksFolderId);
   });
 
-  Services.ww.registerNotification(function (aSubject, aTopic, aData)
-  {
-    if (aTopic != "domwindowopened")
-      return;
-
-    Services.ww.unregisterNotification(arguments.callee);
-
-    gLibrary = aSubject.QueryInterface(Ci.nsIDOMWindow);
-    gLibrary.addEventListener("load", function (event) {
-      gLibrary.removeEventListener("load", arguments.callee, false);
-      executeSoon(nextTest);
-    }, false);
+  openLibrary(function (library) {
+    gLibrary = library;
+    executeSoon(nextTest);
   });
-
-  Services.ww.openWindow(null,
-                         "chrome://browser/content/places/places.xul",
-                          "",
-                          "chrome,toolbar=yes,dialog=no,resizable",
-                          null);
 }
 
 function nextTest() {
   if (gTests.length) {
     var test = gTests.shift();
     info("Start of test: " + test.desc);
     test.run();
   }
--- a/browser/components/places/tests/browser/browser_library_infoBox.js
+++ b/browser/components/places/tests/browser/browser_library_infoBox.js
@@ -210,40 +210,21 @@ function nextTest() {
   else {
     // Close Library window.
     gLibrary.close();
     // No need to cleanup anything, we have a correct left pane now.
     finish();
   }
 }
 
-var ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
-         getService(Ci.nsIWindowWatcher);
-
-function windowObserver(aSubject, aTopic, aData) {
-  if (aTopic != "domwindowopened")
-    return;
-  ww.unregisterNotification(windowObserver);
-  gLibrary = aSubject.QueryInterface(Ci.nsIDOMWindow);
-  gLibrary.addEventListener("load", function onLoad(event) {
-    gLibrary.removeEventListener("load", onLoad, false);
-    executeSoon(function() {
-      gLibrary.PlacesOrganizer._places.focus();
-      waitForFocus(nextTest, gLibrary);
-    });
-  }, false);
-}
-
 function test() {
-  dump("Starting test browser_library_infoBox.js\n");
   waitForExplicitFinish();
   // Sanity checks.
   ok(PlacesUtils, "PlacesUtils is running in chrome context");
   ok(PlacesUIUtils, "PlacesUIUtils is running in chrome context");
 
   // Open Library.
-  ww.registerNotification(windowObserver);
-  ww.openWindow(null,
-                "chrome://browser/content/places/places.xul",
-                "",
-                "chrome,toolbar=yes,dialog=no,resizable",
-                null);
+  openLibrary(function (library) {
+    gLibrary = library;
+    gLibrary.PlacesOrganizer._places.focus();
+    nextTest(gLibrary);
+  });
 }
--- a/browser/components/places/tests/browser/browser_library_left_pane_commands.js
+++ b/browser/components/places/tests/browser/browser_library_left_pane_commands.js
@@ -168,36 +168,20 @@ function nextTest() {
   else {
     // Close Library window.
     gLibrary.close();
     // No need to cleanup anything, we have a correct left pane now.
     finish();
   }
 }
 
-var ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
-         getService(Ci.nsIWindowWatcher);
-
-function windowObserver(aSubject, aTopic, aData) {
-  if (aTopic != "domwindowopened")
-    return;
-  ww.unregisterNotification(windowObserver);
-  gLibrary = aSubject.QueryInterface(Ci.nsIDOMWindow);
-  gLibrary.addEventListener("load", function onLoad(event) {
-    gLibrary.removeEventListener("load", onLoad, false);
-    executeSoon(nextTest);
-  }, false);
-}
-
 function test() {
   waitForExplicitFinish();
   // Sanity checks.
   ok(PlacesUtils, "PlacesUtils is running in chrome context");
   ok(PlacesUIUtils, "PlacesUIUtils is running in chrome context");
 
   // Open Library.
-  ww.registerNotification(windowObserver);
-  ww.openWindow(null,
-                "chrome://browser/content/places/places.xul",
-                "",
-                "chrome,toolbar=yes,dialog=no,resizable",
-                null);
+  openLibrary(function (library) {
+    gLibrary = library;
+    nextTest();
+  });
 }
--- a/browser/components/places/tests/browser/browser_library_left_pane_fixnames.js
+++ b/browser/components/places/tests/browser/browser_library_left_pane_fixnames.js
@@ -35,50 +35,38 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 /**
  *  Test we correctly fix broken Library left pane queries names.
  */
 
-var ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
-         getService(Ci.nsIWindowWatcher);
-
 // Array of left pane queries objects, each one has the following properties:
 // name: query's identifier got from annotations,
 // itemId: query's itemId,
 // correctTitle: original and correct query's title.
 var leftPaneQueries = [];
 
-function windowObserver(aSubject, aTopic, aData) {
-  if (aTopic != "domwindowopened")
-    return;
-  ww.unregisterNotification(windowObserver);
-  var organizer = aSubject.QueryInterface(Ci.nsIDOMWindow);
-  organizer.addEventListener("load", function onLoad(event) {
-    organizer.removeEventListener("load", onLoad, false);
-    executeSoon(function () {
+function onLibraryReady(organizer) {
       // Check titles have been fixed.
       for (var i = 0; i < leftPaneQueries.length; i++) {
         var query = leftPaneQueries[i];
         is(PlacesUtils.bookmarks.getItemTitle(query.itemId),
            query.correctTitle, "Title is correct for query " + query.name);
         if ("concreteId" in query) {
           is(PlacesUtils.bookmarks.getItemTitle(query.concreteId),
            query.concreteTitle, "Concrete title is correct for query " + query.name);
         }
       }
 
       // Close Library window.
       organizer.close();
       // No need to cleanup anything, we have a correct left pane now.
       finish();
-    });
-  }, false);
 }
 
 function test() {
   waitForExplicitFinish();
   // Sanity checks.
   ok(PlacesUtils, "PlacesUtils is running in chrome context");
   ok(PlacesUIUtils, "PlacesUIUtils is running in chrome context");
   ok(PlacesUIUtils.ORGANIZER_LEFTPANE_VERSION > 0,
@@ -129,15 +117,10 @@ function test() {
     PlacesUtils.bookmarks.setItemTitle(query.itemId, "badName");
     if ("concreteId" in query)
       PlacesUtils.bookmarks.setItemTitle(query.concreteId, "badName");
   }
 
   PlacesUIUtils.__defineGetter__("leftPaneFolderId", cachedLeftPaneFolderIdGetter);
 
   // Open Library, this will kick-off left pane code.
-  ww.registerNotification(windowObserver);
-  ww.openWindow(null,
-                "chrome://browser/content/places/places.xul",
-                "",
-                "chrome,toolbar=yes,dialog=no,resizable",
-                null);
+  openLibrary(onLibraryReady);
 }
--- a/browser/components/places/tests/browser/browser_library_middleclick.js
+++ b/browser/components/places/tests/browser/browser_library_middleclick.js
@@ -241,38 +241,22 @@ function test() {
 
   // Add tabs listeners.
   gBrowser.tabContainer.addEventListener("TabOpen", gTabsListener, false);
   gBrowser.addTabsProgressListener(gTabsListener);
 
   // Temporary disable history, so we won't record pages navigation.
   gPrefService.setBoolPref(ENABLE_HISTORY_PREF, false);
 
-  // Window watcher for Library window.
-  var ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
-           getService(Ci.nsIWindowWatcher);
-  function windowObserver(aSubject, aTopic, aData) {
-    if (aTopic != "domwindowopened")
-      return;
-    ww.unregisterNotification(windowObserver);
-    gLibrary = aSubject.QueryInterface(Ci.nsIDOMWindow);
-    gLibrary.addEventListener("load", function onLoad(event) {
-      gLibrary.removeEventListener("load", onLoad, false);
-      // Kick off tests.
-      setTimeout(runNextTest, 0);
-    }, false);
-  }
-
   // Open Library window.
-  ww.registerNotification(windowObserver);
-  ww.openWindow(null,
-                "chrome://browser/content/places/places.xul",
-                "",
-                "chrome,toolbar=yes,dialog=no,resizable",
-                null); 
+  openLibrary(function (library) {
+    gLibrary = library;
+    // Kick off tests.
+    runNextTest();
+  });
 }
 
 function runNextTest() {
   // Cleanup from previous test.
   if (gCurrentTest)
     gCurrentTest.cleanup();
 
   if (gTests.length > 0) {
--- a/browser/components/places/tests/browser/browser_library_open_leak.js
+++ b/browser/components/places/tests/browser/browser_library_open_leak.js
@@ -40,35 +40,16 @@
  * Bug 474831
  * https://bugzilla.mozilla.org/show_bug.cgi?id=474831
  *
  * Tests for leaks caused by simply opening and closing the Places Library
  * window.  Opens the Places Library window, waits for it to load, closes it,
  * and finishes.
  */
 
-let ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
-         getService(Ci.nsIWindowWatcher);
-
-function windowObserver(aSubject, aTopic, aData) {
-  if (aTopic != "domwindowopened")
-    return;
-  ww.unregisterNotification(windowObserver);
-  let win = aSubject.QueryInterface(Ci.nsIDOMWindow);
-  win.addEventListener("load", function onLoad(event) {
-    win.removeEventListener("load", onLoad, false);
-    executeSoon(function () {
-      ok(true, "Library has been correctly opened");
-      win.close();
-      finish();
-    });
-  }, false);
-}
-
 function test() {
   waitForExplicitFinish();
-  ww.registerNotification(windowObserver);
-  ww.openWindow(null,
-                "chrome://browser/content/places/places.xul",
-                "",
-                "chrome,toolbar=yes,dialog=no,resizable",
-                null);
+  openLibrary(function (win) {
+    ok(true, "Library has been correctly opened");
+    win.close();
+    finish();
+  });
 }
--- a/browser/components/places/tests/browser/browser_library_panel_leak.js
+++ b/browser/components/places/tests/browser/browser_library_panel_leak.js
@@ -45,25 +45,18 @@
  * ISSUE: We were adding a bookmarks observer when editing a bookmark, when
  *        selecting an history entry the panel was not un-initialized, and
  *        since an histroy entry does not have an itemId, the observer was
  *        never removed.
  */
 
 const TEST_URI = "http://www.mozilla.org/";
 
-let ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
-         getService(Ci.nsIWindowWatcher);
-
-function windowObserver(aSubject, aTopic, aData) {
-  if (aTopic != "domwindowopened")
-    return;
-  ww.unregisterNotification(windowObserver);
-  let organizer = aSubject.QueryInterface(Ci.nsIDOMWindow);
-  waitForFocus(function () {
+function test() {
+  function onLibraryReady(organizer) {
     let contentTree = organizer.document.getElementById("placeContent");
     isnot(contentTree, null, "Sanity check: placeContent tree should exist");
     isnot(organizer.PlacesOrganizer, null, "Sanity check: PlacesOrganizer should exist");
     isnot(organizer.gEditItemOverlay, null, "Sanity check: gEditItemOverlay should exist");
 
     ok(organizer.gEditItemOverlay._initialized, "gEditItemOverlay is initialized");
     isnot(organizer.gEditItemOverlay.itemId, -1, "Editing a bookmark");
 
@@ -74,33 +67,26 @@ function windowObserver(aSubject, aTopic
     selection.clearSelection();
     selection.rangedSelect(0, 0, true);
     // Check the panel is editing the history entry.
     is(organizer.gEditItemOverlay.itemId, -1, "Editing an history entry");
     // Close Library window.
     organizer.close();
     // Clean up history.
     waitForClearHistory(finish);
-  }, organizer);
-}
+  }
 
-function test() {
   waitForExplicitFinish();
   // Add an history entry.
   ok(PlacesUtils, "checking PlacesUtils, running in chrome context?");
   PlacesUtils.history.addVisit(PlacesUtils._uri(TEST_URI), Date.now() * 1000,
                                null, PlacesUtils.history.TRANSITION_TYPED,
                                false, 0);
 
-  ww.registerNotification(windowObserver);
-  ww.openWindow(null,
-                "chrome://browser/content/places/places.xul",
-                "",
-                "chrome,toolbar=yes,dialog=no,resizable",
-                null);
+  openLibrary(onLibraryReady);
 }
 
 function waitForClearHistory(aCallback) {
   let observer = {
     observe: function(aSubject, aTopic, aData) {
       Services.obs.removeObserver(this, PlacesUtils.TOPIC_EXPIRATION_FINISHED);
       aCallback(aSubject, aTopic, aData);
     }
--- a/browser/components/places/tests/browser/browser_library_search.js
+++ b/browser/components/places/tests/browser/browser_library_search.js
@@ -296,29 +296,10 @@ function test() {
                                Date.now() * 1000, null,
                                PlacesUtils.history.TRANSITION_TYPED, false, 0);
   PlacesUtils.bookmarks.insertBookmark(PlacesUtils.bookmarks.unfiledBookmarksFolder,
                                        PlacesUtils._uri(TEST_URL),
                                        PlacesUtils.bookmarks.DEFAULT_INDEX,
                                        "dummy");
   PlacesUtils.tagging.tagURI(PlacesUtils._uri(TEST_URL), ["dummyTag"]);
 
-  var ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
-           getService(Ci.nsIWindowWatcher);
-
-  function windowObserver(aSubject, aTopic, aData) {
-    if (aTopic != "domwindowopened")
-      return;
-    ww.unregisterNotification(windowObserver);
-    var win = aSubject.QueryInterface(Ci.nsIDOMWindow);
-    win.addEventListener("load", function onLoad(event) {
-      win.removeEventListener("load", onLoad, false);
-      executeSoon(function () testHelper(win));
-    }, false);
-  }
-
-  ww.registerNotification(windowObserver);
-  ww.openWindow(null,
-                "chrome://browser/content/places/places.xul",
-                "",
-                "chrome,toolbar=yes,dialog=no,resizable",
-                null);
+  openLibrary(testHelper);
 }
--- a/browser/components/places/tests/browser/browser_library_views_liveupdate.js
+++ b/browser/components/places/tests/browser/browser_library_views_liveupdate.js
@@ -48,34 +48,20 @@ function test() {
   // See Bug 525610.
   requestLongerTimeout(2);
 
   // Sanity checks.
   ok(PlacesUtils, "PlacesUtils in context");
   ok(PlacesUIUtils, "PlacesUIUtils in context");
 
   // Open Library, we will check the left pane.
-  var ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
-           getService(Ci.nsIWindowWatcher);
-  function windowObserver(aSubject, aTopic, aData) {
-    if (aTopic != "domwindowopened")
-      return;
-    ww.unregisterNotification(windowObserver);
-    gLibrary = aSubject.QueryInterface(Ci.nsIDOMWindow);
-    gLibrary.addEventListener("load", function onLoad(event) {
-      gLibrary.removeEventListener("load", onLoad, false);
-      executeSoon(startTest);
-    }, false);
-  }
-  ww.registerNotification(windowObserver);
-  ww.openWindow(null,
-                "chrome://browser/content/places/places.xul",
-                "",
-                "chrome,toolbar=yes,dialog=no,resizable",
-                null);
+  openLibrary(function (library) {
+    gLibrary = library;
+    startTest();
+  });
 }
 
 /**
  * Adds bookmarks observer, and executes a bunch of bookmarks operations.
  */
 function startTest() {
   var bs = PlacesUtils.bookmarks;
   // Add observers.
--- a/browser/components/places/tests/browser/browser_sort_in_library.js
+++ b/browser/components/places/tests/browser/browser_sort_in_library.js
@@ -263,43 +263,24 @@ function testSortByDir(aOrganizerWin, aP
   });
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
 function test() {
   waitForExplicitFinish();
 
-  let ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
-           getService(Ci.nsIWindowWatcher);
-
-  function windowObserver(aSubject, aTopic, aData) {
-    if (aTopic != "domwindowopened")
-      return;
-    ww.unregisterNotification(windowObserver);
-    let win = aSubject.QueryInterface(Ci.nsIDOMWindow);
-    win.addEventListener("load", function onLoad(event) {
-      win.removeEventListener("load", onLoad, false);
-      executeSoon(function () {
+  openLibrary(function (win) {
         let tree = win.document.getElementById("placeContent");
         isnot(tree, null, "sanity check: placeContent tree should exist");
         // Run the tests.
         testSortByColAndDir(win, tree, true);
         testSortByColAndDir(win, tree, false);
         testSortByDir(win, tree, true);
         testSortByDir(win, tree, false);
         testInvalid(win, tree);
         // Reset the sort to SORT_BY_NONE.
         setSort(win, tree, false, false);
         // Close the window and finish.
         win.close();
         finish();
-      });
-    }, false);
-  }
-
-  ww.registerNotification(windowObserver);
-  ww.openWindow(null,
-                "chrome://browser/content/places/places.xul",
-                "",
-                "chrome,toolbar=yes,dialog=no,resizable",
-                null);
+  });
 }
--- a/browser/components/places/tests/browser/head.js
+++ b/browser/components/places/tests/browser/head.js
@@ -8,8 +8,17 @@ let (getter = PlacesUIUtils.__lookupGett
 // ...And restore it when test ends.
 registerCleanupFunction(function(){
   let (getter = PlacesUIUtils.__lookupGetter__("leftPaneFolderId")) {
     if (cachedLeftPaneFolderIdGetter && typeof(getter) != "function")
       PlacesUIUtils.__defineGetter__("leftPaneFolderId",
                                      cachedLeftPaneFolderIdGetter);
   }
 });
+
+
+function openLibrary(callback) {
+  var library = window.openDialog("chrome://browser/content/places/places.xul",
+                                  "", "chrome,toolbar=yes,dialog=no,resizable");
+  waitForFocus(function () {
+    callback(library);
+  }, library);
+}
deleted file mode 100644
--- a/browser/components/places/tests/perf/Makefile.in
+++ /dev/null
@@ -1,66 +0,0 @@
-# ***** BEGIN LICENSE BLOCK *****
-# Version: MPL 1.1/GPL 2.0/LGPL 2.1
-#
-# The contents of this file are subject to the Mozilla Public License Version
-# 1.1 (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-# http://www.mozilla.org/MPL/
-#
-# Software distributed under the License is distributed on an "AS IS" basis,
-# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
-# for the specific language governing rights and limitations under the
-# License.
-#
-# The Original Code is mozilla.org code.
-#
-# The Initial Developer of the Original Code is
-# Mozilla Corporation.
-# Portions created by the Initial Developer are Copyright (C) 2008
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-#  	Shawn Wilsher <me@shawnwilsher.com> (Original Author)
-#
-# Alternatively, the contents of this file may be used under the terms of
-# either of the GNU General Public License Version 2 or later (the "GPL"),
-# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
-# in which case the provisions of the GPL or the LGPL are applicable instead
-# of those above. If you wish to allow use of your version of this file only
-# under the terms of either the GPL or the LGPL, and not to allow others to
-# use your version of this file under the terms of the MPL, indicate your
-# decision by deleting the provisions above and replace them with the notice
-# and other provisions required by the GPL or the LGPL. If you do not delete
-# the provisions above, a recipient may use your version of this file under
-# the terms of any one of the MPL, the GPL or the LGPL.
-#
-# ***** END LICENSE BLOCK *****
-
-DEPTH          = ../../../../..
-topsrcdir      = @top_srcdir@
-srcdir         = @srcdir@
-VPATH          = @srcdir@
-relativesrcdir = browser/components/places/tests/perf
-
-include $(DEPTH)/config/autoconf.mk
-include $(topsrcdir)/config/rules.mk
-
-_CHROME_FILES = \
-	perf_large_delete.xul \
-	$(NULL)
-
-# Disabled due to bad interactions with next tests.
-# browser_ui_locationbar.js
-_BROWSER_TEST_FILES = \
-	browser_ui_000_data.js \
-	browser_ui_bookmarks_sidebar.js \
-	browser_ui_history_menu.js \
-	browser_ui_history_sidebar.js \
-	browser_ui_history_sidebar_2.js \
-	browser_ui_history_sidebar_3.js \
-	$(NULL)
-
-libs:: $(_CHROME_FILES)
-	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/chrome/$(relativesrcdir)
-
-libs:: $(_BROWSER_TEST_FILES)
-	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/browser/$(relativesrcdir)
deleted file mode 100644
--- a/browser/components/places/tests/perf/browser_ui_000_data.js
+++ /dev/null
@@ -1,153 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is mozilla.org code.
- *
- * The Initial Developer of the Original Code is
- * Mozilla Corporation.
- * Portions created by the Initial Developer are Copyright (C) 2008
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   Dietrich Ayala <dietrich@mozilla.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/*
-
-Sets up the database for subsequent performance
-tests, and test the speed of adding to history
-and bookmarks.
-
-- add XXX visits distributed over XXX days
-- add XXX bookmarks distributed over XXX days
-
-*/
-
-/*********************** begin header **********************/
-waitForExplicitFinish();
-
-const TEST_IDENTIFIER = "ui-perf-test";
-const TEST_SUITE = "places";
-
-var hs = Cc["@mozilla.org/browser/nav-history-service;1"].
-         getService(Ci.nsINavHistoryService);
-var bs = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
-         getService(Ci.nsINavBookmarksService);
-
-function add_visit(aURI, aDate) {
-  var placeID = hs.addVisit(aURI,
-                            aDate,
-                            null, // no referrer
-                            hs.TRANSITION_TYPED, // user typed in URL bar
-                            false, // not redirect
-                            0);
-  return placeID;
-}
-
-function add_bookmark(aURI) {
-  var bId = bs.insertBookmark(bs.unfiledBookmarksFolder, aURI,
-                              bs.DEFAULT_INDEX, "bookmark/" + aURI.spec);
-  return bId;
-}
-
-function make_test_report(testName, result, units) {
-  return [TEST_IDENTIFIER, TEST_SUITE, testName, result, units||"ms"].join(":");
-}
-
-// Each test is an obj w/ a name property and run method
-var ptests = [];
-
-/*********************** end header **********************/
-
-// add visits and bookmarks
-ptests.push({
-  run: function() {
-    bs.runInBatchMode({
-      runBatched: function(aUserData) {
-        // timespan - same as default history pref for now
-        var days = 90;
-
-        // add visits, distributed across the timespan
-        var total_visits = 300;
-        var visits_per_day = total_visits/days;
-
-        var visit_date_microsec = Date.now() * 1000;
-        var day_counter = 0;
-        
-        var start = Date.now();
-        for (var i = 0; i < days; i++) {
-          visit_date_microsec -= 86400 * 1000 * 1000; // remove a day
-          var spec = "http://example.com/" + visit_date_microsec;
-          for (var j = 0; j < visits_per_day; j++) {
-            var uri = Services.io.newURI(spec + j, null, null);
-            add_visit(uri, visit_date_microsec);
-          }
-        }
-        var duration = Date.now() - start;
-        var report = make_test_report("add_visits", duration);
-        ok(true, report);
-
-        // add bookmarks
-        var bookmarks_total = total_visits/10; // bookmark a tenth of the URLs in history
-        var bookmarks_per_day = bookmarks_total/days;
-
-        // reset visit date counter
-        visit_date_microsec = Date.now() * 1000;
-        var bookmark_counter = 0;
-        start = Date.now();
-        for (var i = 0; i < days; i++) {
-          visit_date_microsec -= 86400 * 1000 * 1000; // remove a day
-          var spec = "http://example.com/" + visit_date_microsec;
-          for (var j = 0; j < visits_per_day; j++) {
-            var uri = Services.io.newURI(spec + j, null, null);
-            if (bookmark_counter < bookmarks_per_day) {
-              add_bookmark(uri);
-              bookmark_counter++;
-            }
-            else
-              bookmark_counter = 0;
-          }
-        }
-        duration = Date.now() - start;
-        report = make_test_report("add_bookmarks", duration);
-        ok(true, report);
-        runNextTest();
-      }
-    }, null);
-  }
-});
-
-function test() {
-  // kick off tests
-  runNextTest();
-}
-
-function runNextTest() {
-  if (ptests.length > 0)
-    ptests.shift().run();
-  else
-    finish();
-}
deleted file mode 100644
--- a/browser/components/places/tests/perf/browser_ui_bookmarks_sidebar.js
+++ /dev/null
@@ -1,128 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is mozilla.org code.
- *
- * The Initial Developer of the Original Code is
- * Mozilla Corporation.
- * Portions created by the Initial Developer are Copyright (C) 2008
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   Dietrich Ayala <dietrich@mozilla.com>
- *   Marco Bonardo <mak77@bonardo.net>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/*
-Tests the performance of opening the bookmarks sidebar
-
-*/
-
-/*********************** begin header **********************/
-waitForExplicitFinish();
-
-const TEST_IDENTIFIER = "ui-perf-test";
-const TEST_SUITE = "places";
-
-var hs = Cc["@mozilla.org/browser/nav-history-service;1"].
-         getService(Ci.nsINavHistoryService);
-var bs = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
-         getService(Ci.nsINavBookmarksService);
-
-function add_visit(aURI, aDate) {
-  var visitId = hs.addVisit(aURI,
-                            aDate,
-                            null, // no referrer
-                            hs.TRANSITION_TYPED, // user typed in URL bar
-                            false, // not redirect
-                            0);
-  return visitId;
-}
-
-function add_bookmark(aURI) {
-  var bId = bs.insertBookmark(bs.unfiledBookmarksFolder, aURI,
-                              bs.DEFAULT_INDEX, "bookmark/" + aURI.spec);
-  return bId;
-}
-
-function make_test_report(testName, result, units) {
-  return [TEST_IDENTIFIER, TEST_SUITE, testName, result, units||"ms"].join(":");
-}
-
-// Each test is an obj w/ a name property and run method
-var ptests = [];
-
-/*********************** end header **********************/
-
-const TEST_REPEAT_COUNT = 6;
-
-// test duration of bookmarks sidebar opening
-ptests.push({
-  name: "open_bookmarks_sidebar",
-  times: [],
-  run: function() {
-    var self = this;
-    var start = Date.now();
-    var sb = document.getElementById("sidebar");
-    sb.addEventListener("load", function() {
-      sb.removeEventListener("load", arguments.callee, true);
-      executeSoon(function() {
-        var duration = Date.now() - start;
-        toggleSidebar("viewBookmarksSidebar", false);
-        self.times.push(duration);
-        if (self.times.length == TEST_REPEAT_COUNT)
-          self.finish();
-        else
-          self.run();
-      });
-    }, true);
-    toggleSidebar("viewBookmarksSidebar", true);
-  },
-  finish: function() {
-    this.times.sort();  // sort the scores
-    this.times.pop();   // remove worst
-    this.times.shift(); // remove best
-    var totalDuration = this.times.reduce(function(time, total){ return time + total; });
-    var avgDuration = totalDuration/this.times.length;
-    var report = make_test_report("open_bookmarks_sidebar", avgDuration);
-    ok(true, report);
-    setTimeout(runNextTest, 0);
-  }
-});
-
-function test() {
-  requestLongerTimeout(2);
-  // kick off tests
-  setTimeout(runNextTest, 0);
-}
-
-function runNextTest() {
-  if (ptests.length > 0) {
-    ptests.shift().run();
-  }
-  else
-    finish();
-}
deleted file mode 100644
--- a/browser/components/places/tests/perf/browser_ui_history_menu.js
+++ /dev/null
@@ -1,137 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is mozilla.org code.
- *
- * The Initial Developer of the Original Code is
- * Mozilla Corporation.
- * Portions created by the Initial Developer are Copyright (C) 2008
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   Dietrich Ayala <dietrich@mozilla.com>
- *   Marco Bonardo <mak77@bonardo.net>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/*
-Tests the performance of opening the history menu.
-*/
-
-/*********************** begin header **********************/
-const TEST_IDENTIFIER = "ui-perf-test";
-const TEST_SUITE = "places";
-
-var hs = Cc["@mozilla.org/browser/nav-history-service;1"].
-         getService(Ci.nsINavHistoryService);
-var bs = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
-         getService(Ci.nsINavBookmarksService);
-
-var historyMenu = document.getElementById("history-menu");
-var historyPopup = document.getElementById("goPopup");
-
-function add_visit(aURI, aDate) {
-  var visitId = hs.addVisit(aURI,
-                            aDate,
-                            null, // no referrer
-                            hs.TRANSITION_TYPED, // user typed in URL bar
-                            false, // not redirect
-                            0);
-  return visitId;
-}
-
-function add_bookmark(aURI) {
-  var bId = bs.insertBookmark(bs.unfiledBookmarksFolder, aURI,
-                              bs.DEFAULT_INDEX, "bookmark/" + aURI.spec);
-  return bId;
-}
-
-function make_test_report(testName, result, units) {
-  return [TEST_IDENTIFIER, TEST_SUITE, testName, result, units||"ms"].join(":");
-}
-
-// Each test is an obj w/ a name property and run method
-var ptests = [];
-
-/*********************** end header **********************/
-
-const TEST_REPEAT_COUNT = 6;
-
-// test duration of history menu opening
-ptests.push({
-  name: "open_history_menu",
-  times: [],
-  run: function() {
-    var self = this;
-    var start = Date.now();
-    historyPopup.addEventListener("popupshown", function() {
-      historyPopup.removeEventListener("popupshown", arguments.callee, true);
-      executeSoon(function() {
-        var duration = Date.now() - start;
-        historyPopup.hidePopup();
-        historyMenu.open = false;
-        self.times.push(duration);
-        if (self.times.length == TEST_REPEAT_COUNT)
-          self.finish();
-        else
-          self.run();
-      });
-    }, true);
-    historyMenu.open = true;
-    historyPopup.openPopup();
-  },
-  finish: function() {
-    processTestResult(this);
-    setTimeout(runNextTest, 0);
-  }
-});
-
-function processTestResult(aTest) {
-  aTest.times.sort();  // sort the scores
-  aTest.times.pop();   // remove worst
-  aTest.times.shift(); // remove best
-  var totalDuration = aTest.times.reduce(function(time, total){ return time + total; });
-  var avgDuration = totalDuration/aTest.times.length;
-  var report = make_test_report(aTest.name, avgDuration);
-  ok(true, report);
-}
-
-function test() {
-  // Skip test on Mac due to native menus.
-  if (navigator.platform.toLowerCase().indexOf("mac") != -1)
-    return;
-
-  waitForExplicitFinish();
-
-  // kick off tests
-  setTimeout(runNextTest, 0);
-}
-
-function runNextTest() {
-  if (ptests.length > 0)
-    ptests.shift().run();
-  else
-    finish();
-}
deleted file mode 100644
--- a/browser/components/places/tests/perf/browser_ui_history_sidebar.js
+++ /dev/null
@@ -1,189 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is mozilla.org code.
- *
- * The Initial Developer of the Original Code is
- * Mozilla Corporation.
- * Portions created by the Initial Developer are Copyright (C) 2008
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   Dietrich Ayala <dietrich@mozilla.com>
- *   Marco Bonardo <mak77@bonardo.net>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/*
-Tests the performance of opening the History
-sidebar in all the available views.
-*/
-
-/*********************** begin header **********************/
-waitForExplicitFinish();
-
-const TEST_IDENTIFIER = "ui-perf-test";
-const TEST_SUITE = "places";
-
-var hs = Cc["@mozilla.org/browser/nav-history-service;1"].
-         getService(Ci.nsINavHistoryService);
-var bs = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
-         getService(Ci.nsINavBookmarksService);
-
-var sidebar = document.getElementById("sidebar");
-
-function add_visit(aURI, aDate) {
-  var visitId = hs.addVisit(aURI,
-                            aDate,
-                            null, // no referrer
-                            hs.TRANSITION_TYPED, // user typed in URL bar
-                            false, // not redirect
-                            0);
-  return visitId;
-}
-
-function add_bookmark(aURI) {
-  var bId = bs.insertBookmark(bs.unfiledBookmarksFolder, aURI,
-                              bs.DEFAULT_INDEX, "bookmark/" + aURI.spec);
-  return bId;
-}
-
-function make_test_report(testName, result, units) {
-  return [TEST_IDENTIFIER, TEST_SUITE, testName, result, units||"ms"].join(":");
-}
-
-// Each test is an obj w/ a name property and run method
-var ptests = [];
-
-/*********************** end header **********************/
-
-const TEST_REPEAT_COUNT = 6;
-
-// test duration of history sidebar opening
-// default: bydayandsite
-ptests.push({
-  name: "open_history_sidebar_bydayandsite",
-  times: [],
-  run: function() {
-    var self = this;
-    var start = Date.now();
-    sidebar.addEventListener("load", function(aEvent) {
-      sidebar.removeEventListener("load", arguments.callee, true);
-      executeSoon(function() {
-        var duration = Date.now() - start;
-        toggleSidebar("viewHistorySidebar", false);
-        self.times.push(duration);
-        if (self.times.length == TEST_REPEAT_COUNT)
-          self.finish();
-        else
-          self.run();
-      });
-    }, true);
-    toggleSidebar("viewHistorySidebar", true);
-  },
-  finish: function() {
-    processTestResult(this);
-    setTimeout(runNextTest, 0);
-  }
-});
-
-// bysite
-ptests.push({
-  name: "history_sidebar_bysite",
-  times: [],
-  run: function() {
-    var self = this;
-    var start = Date.now();
-    sidebar.addEventListener("load", function() {
-      sidebar.removeEventListener("load", arguments.callee, true);
-      executeSoon(function() {
-        var duration = Date.now() - start;
-        sidebar.contentDocument.getElementById("bysite").doCommand();
-        toggleSidebar("viewHistorySidebar", false);
-        self.times.push(duration);
-        if (self.times.length == TEST_REPEAT_COUNT)
-          self.finish();
-        else
-          self.run();
-      });
-    }, true);
-    toggleSidebar("viewHistorySidebar", true);
-  },
-  finish: function() {
-    processTestResult(this);
-    setTimeout(runNextTest, 0);
-  }
-});
-
-// byday
-ptests.push({
-  name: "history_sidebar_byday",
-  times: [],
-  run: function() {
-    var self = this;
-    var start = Date.now();
-    sidebar.addEventListener("load", function() {
-      sidebar.removeEventListener("load", arguments.callee, true);
-      executeSoon(function() {
-        var duration = Date.now() - start;
-        sidebar.contentDocument.getElementById("byday").doCommand();
-        toggleSidebar("viewHistorySidebar", false);
-        self.times.push(duration);
-        if (self.times.length == TEST_REPEAT_COUNT)
-          self.finish();
-        else
-          self.run();
-      });
-    }, true);
-    toggleSidebar("viewHistorySidebar", true);
-  },
-  finish: function() {
-    processTestResult(this);
-    setTimeout(runNextTest, 0);
-  }
-});
-
-function processTestResult(aTest) {
-  aTest.times.sort();  // sort the scores
-  aTest.times.pop();   // remove worst
-  aTest.times.shift(); // remove best
-  var totalDuration = aTest.times.reduce(function(time, total){ return time + total; });
-  var avgDuration = totalDuration/aTest.times.length;
-  var report = make_test_report(aTest.name, avgDuration);
-  ok(true, report);
-}
-
-function test() {
-  requestLongerTimeout(2);
-  // kick off tests
-  setTimeout(runNextTest, 0);
-}
-
-function runNextTest() {
-  if (ptests.length > 0)
-    ptests.shift().run();
-  else
-    finish();
-}
deleted file mode 100644
--- a/browser/components/places/tests/perf/browser_ui_history_sidebar_2.js
+++ /dev/null
@@ -1,134 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is mozilla.org code.
- *
- * The Initial Developer of the Original Code is
- * Mozilla Corporation.
- * Portions created by the Initial Developer are Copyright (C) 2008
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   Dietrich Ayala <dietrich@mozilla.com>
- *   Marco Bonardo <mak77@bonardo.net>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/*
-Tests the performance of opening the History
-sidebar in all the available views.
-*/
-
-/*********************** begin header **********************/
-waitForExplicitFinish();
-
-const TEST_IDENTIFIER = "ui-perf-test";
-const TEST_SUITE = "places";
-
-var hs = Cc["@mozilla.org/browser/nav-history-service;1"].
-         getService(Ci.nsINavHistoryService);
-var bs = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
-         getService(Ci.nsINavBookmarksService);
-
-var sidebar = document.getElementById("sidebar");
-
-function add_visit(aURI, aDate) {
-  var visitId = hs.addVisit(aURI,
-                            aDate,
-                            null, // no referrer
-                            hs.TRANSITION_TYPED, // user typed in URL bar
-                            false, // not redirect
-                            0);
-  return visitId;
-}
-
-function add_bookmark(aURI) {
-  var bId = bs.insertBookmark(bs.unfiledBookmarksFolder, aURI,
-                              bs.DEFAULT_INDEX, "bookmark/" + aURI.spec);
-  return bId;
-}
-
-function make_test_report(testName, result, units) {
-  return [TEST_IDENTIFIER, TEST_SUITE, testName, result, units||"ms"].join(":");
-}
-
-// Each test is an obj w/ a name property and run method
-var ptests = [];
-
-/*********************** end header **********************/
-
-const TEST_REPEAT_COUNT = 6;
-
-// test duration of history sidebar opening
-// byvisited
-ptests.push({
-  name: "history_sidebar_byvisited",
-  times: [],
-  run: function() {
-    var self = this;
-    var start = Date.now();
-    sidebar.addEventListener("load", function() {
-      sidebar.removeEventListener("load", arguments.callee, true);
-      executeSoon(function() {
-        var duration = Date.now() - start;
-        sidebar.contentDocument.getElementById("byvisited").doCommand();
-        toggleSidebar("viewHistorySidebar", false);
-        self.times.push(duration);
-        if (self.times.length == TEST_REPEAT_COUNT)
-          self.finish();
-        else
-          self.run();
-      });
-    }, true);
-    toggleSidebar("viewHistorySidebar", true);
-  },
-  finish: function() {
-    processTestResult(this);
-    setTimeout(runNextTest, 0);
-  }
-});
-
-function processTestResult(aTest) {
-  aTest.times.sort();  // sort the scores
-  aTest.times.pop();   // remove worst
-  aTest.times.shift(); // remove best
-  var totalDuration = aTest.times.reduce(function(time, total){ return time + total; });
-  var avgDuration = totalDuration/aTest.times.length;
-  var report = make_test_report(aTest.name, avgDuration);
-  ok(true, report);
-}
-
-function test() {
-  requestLongerTimeout(2);
-  // kick off tests
-  setTimeout(runNextTest, 0);
-}
-
-function runNextTest() {
-  if (ptests.length > 0)
-    ptests.shift().run();
-  else
-    finish();
-}
deleted file mode 100644
--- a/browser/components/places/tests/perf/browser_ui_history_sidebar_3.js
+++ /dev/null
@@ -1,134 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is mozilla.org code.
- *
- * The Initial Developer of the Original Code is
- * Mozilla Corporation.
- * Portions created by the Initial Developer are Copyright (C) 2008
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   Dietrich Ayala <dietrich@mozilla.com>
- *   Marco Bonardo <mak77@bonardo.net>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/*
-Tests the performance of opening the History
-sidebar in all the available views.
-*/
-
-/*********************** begin header **********************/
-waitForExplicitFinish();
-
-const TEST_IDENTIFIER = "ui-perf-test";
-const TEST_SUITE = "places";
-
-var hs = Cc["@mozilla.org/browser/nav-history-service;1"].
-         getService(Ci.nsINavHistoryService);
-var bs = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
-         getService(Ci.nsINavBookmarksService);
-
-var sidebar = document.getElementById("sidebar");
-
-function add_visit(aURI, aDate) {
-  var visitId = hs.addVisit(aURI,
-                            aDate,
-                            null, // no referrer
-                            hs.TRANSITION_TYPED, // user typed in URL bar
-                            false, // not redirect
-                            0);
-  return visitId;
-}
-
-function add_bookmark(aURI) {
-  var bId = bs.insertBookmark(bs.unfiledBookmarksFolder, aURI,
-                              bs.DEFAULT_INDEX, "bookmark/" + aURI.spec);
-  return bId;
-}
-
-function make_test_report(testName, result, units) {
-  return [TEST_IDENTIFIER, TEST_SUITE, testName, result, units||"ms"].join(":");
-}
-
-// Each test is an obj w/ a name property and run method
-var ptests = [];
-
-/*********************** end header **********************/
-
-const TEST_REPEAT_COUNT = 6;
-
-// test duration of history sidebar opening
-// bylastvisited
-ptests.push({
-  name: "history_sidebar_bylastvisited",
-  times: [],
-  run: function() {
-    var self = this;
-    var start = Date.now();
-    sidebar.addEventListener("load", function() {
-      sidebar.removeEventListener("load", arguments.callee, true);
-      executeSoon(function() {
-        var duration = Date.now() - start;
-        sidebar.contentDocument.getElementById("bylastvisited").doCommand();
-        toggleSidebar("viewHistorySidebar", false);
-        self.times.push(duration);
-        if (self.times.length == TEST_REPEAT_COUNT)
-          self.finish();
-        else
-          self.run();
-      });
-    }, true);
-    toggleSidebar("viewHistorySidebar", true);
-  },
-  finish: function() {
-    processTestResult(this);
-    setTimeout(runNextTest, 0);
-  }
-});
-
-function processTestResult(aTest) {
-  aTest.times.sort();  // sort the scores
-  aTest.times.pop();   // remove worst
-  aTest.times.shift(); // remove best
-  var totalDuration = aTest.times.reduce(function(time, total){ return time + total; });
-  var avgDuration = totalDuration/aTest.times.length;
-  var report = make_test_report(aTest.name, avgDuration);
-  ok(true, report);
-}
-
-function test() {
-  requestLongerTimeout(2);
-  // kick off tests
-  setTimeout(runNextTest, 0);
-}
-
-function runNextTest() {
-  if (ptests.length > 0)
-    ptests.shift().run();
-  else
-    finish();
-}
deleted file mode 100644
--- a/browser/components/places/tests/perf/browser_ui_locationbar.js
+++ /dev/null
@@ -1,139 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is mozilla.org code.
- *
- * The Initial Developer of the Original Code is
- * Mozilla Corporation.
- * Portions created by the Initial Developer are Copyright (C) 2008
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   Dietrich Ayala <dietrich@mozilla.com>
- *   Marco Bonardo <mak77@bonardo.net>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/*
-Tests the performance of opening the location bar dropdown.
-*/
-
-/*********************** begin header **********************/
-waitForExplicitFinish();
-
-const TEST_IDENTIFIER = "ui-perf-test";
-const TEST_SUITE = "places";
-
-var hs = Cc["@mozilla.org/browser/nav-history-service;1"].
-         getService(Ci.nsINavHistoryService);
-var bs = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
-         getService(Ci.nsINavBookmarksService);
-
-var maxResults = Services.prefs.getIntPref("browser.urlbar.maxRichResults");
-var onSearchComplete = gURLBar.onSearchComplete;
-
-function add_visit(aURI, aDate) {
-  var visitId = hs.addVisit(aURI,
-                            aDate,
-                            null, // no referrer
-                            hs.TRANSITION_TYPED, // user typed in URL bar
-                            false, // not redirect
-                            0);
-  return visitId;
-}
-
-function add_bookmark(aURI) {
-  var bId = bs.insertBookmark(bs.unfiledBookmarksFolder, aURI,
-                              bs.DEFAULT_INDEX, "bookmark/" + aURI.spec);
-  return bId;
-}
-
-function make_test_report(testName, result, units) {
-  return [TEST_IDENTIFIER, TEST_SUITE, testName, result, units||"ms"].join(":");
-}
-
-// Each test is an obj w/ a name property and run method
-var ptests = [];
-
-/*********************** end header **********************/
-
-const TEST_REPEAT_COUNT = 6;
-
-// test duration of locationbar searching
-ptests.push({
-  name: "open_locationbar_default",
-  times: [],
-  run: function() {
-    var self = this;
-    var start = Date.now();
-    var acItemsCount = 1;
-    gURLBar.onSearchComplete = function() {
-      executeSoon(function() {
-        var duration = Date.now() - start;
-        self.times.push(duration);
-        if (self.times.length == TEST_REPEAT_COUNT)
-          self.finish();
-        else
-          self.run();
-      });
-    };
-    window.focus();
-    gURLBar.focus();
-    var synthesizeSearch = function() {
-      EventUtils.synthesizeKey("VK_BACK_SPACE", {});
-      EventUtils.synthesizeKey("e", {});
-    };
-    waitForFocus(synthesizeSearch);
-  },
-  finish: function() {
-    gURLBar.value = "";
-    processTestResult(this);
-    setTimeout(runNextTest, 0);
-  }
-});
-
-function processTestResult(aTest) {
-  aTest.times.sort();  // sort the scores
-  aTest.times.pop();   // remove worst
-  aTest.times.shift(); // remove best
-  var totalDuration = aTest.times.reduce(function(time, total){ return time + total; });
-  var avgDuration = totalDuration/aTest.times.length;
-  var report = make_test_report(aTest.name, avgDuration);
-  ok(true, report);
-}
-
-function test() {
-  // kick off tests
-  setTimeout(runNextTest, 0);
-}
-
-function runNextTest() {
-  if (ptests.length > 0)
-    ptests.shift().run();
-  else {
-    gURLBar.onSearchComplete = onSearchComplete;
-    finish();
-  }
-}
deleted file mode 100644
--- a/browser/components/places/tests/perf/perf_large_delete.xul
+++ /dev/null
@@ -1,167 +0,0 @@
-<?xml version="1.0"?>
-<!--
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is mozilla.org code.
- *
- * The Initial Developer of the Original Code is
- * Mozilla Corporation.
- * Portions created by the Initial Developer are Copyright (C) 2008
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   Shawn Wilsher <me@shawnwilsher.com> (Original Author)
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/**
- * This tests that the performance of deleting a large number of bookmarks.  See
- * bug 432706 for more details.
- *
- * To run this test, run it like you would a standard chrome test, with the test
- * path being:
- * ../chrome/browser/components/places/tests/perf/perf_large_delete.xul
- */
--->
-
-<window title="Places Library Performance Test"
-        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
-        onload="test();">
-
-  <script type="application/javascript"
-          src="chrome://mochikit/content/MochiKit/packed.js"/>
-  <script type="application/javascript"
-          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
-  <script type="application/javascript"
-          src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/>
-
-  <script type="application/javascript">
-  <![CDATA[
-
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cr = Components.results;
-
-function test()
-{
-  let ios = Cc["@mozilla.org/network/io-service;1"].
-            getService(Ci.nsIIOService);
-
-  // First, add 250 bookmarks
-  let bs = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
-           getService(Ci.nsINavBookmarksService);
-  bs.runInBatchMode({
-    runBatched: function(aUserData)
-    {
-      for (let i = 0; i < 250; i++) {
-        let uri = ios.newURI("http://example.com/" + i, null, null);
-        bs.insertBookmark(bs.unfiledBookmarksFolder, uri, bs.DEFAULT_INDEX,
-                          "bookmark " + i);
-      }
-    }
-  }, null);
-
-  // Close the window if it's already open
-  let wm = Cc["@mozilla.org/appshell/window-mediator;1"].
-           getService(Ci.nsIWindowMediator);
-  let win = wm.getMostRecentWindow("Places:Organizer");
-  if (win)
-    win.close();
-
-
-  let ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
-           getService(Ci.nsIWindowWatcher);
-  ww.registerNotification({
-    observe: function(aSubject, aTopic, aData)
-    {
-      if (aTopic != "domwindowopened")
-        return;
-
-      let win = aSubject.QueryInterface(Ci.nsIDOMEventTarget);
-
-      // We need to run after the window is loaded, and has run its startup code
-      win.addEventListener("DOMContentLoaded", function() {
-        let tm = Cc["@mozilla.org/thread-manager;1"].
-                 getService(Ci.nsIThreadManager);
-        tm.mainThread.dispatch({
-          run: function() doTest(win.QueryInterface(Ci.nsIDOMWindow))
-        }, Ci.nsIThread.DISPATCH_NORMAL);
-      }, false);
-
-      // and now to unregister ourself as a listener
-      ww.unregisterNotification(this);
-    }
-  });
-
-  function doTest(aWin)
-  {
-    // Select all the bookmarks
-    synthesizeKey("a", {accelKey:true}, aWin);
-
-    // If we can, start profiling
-    try {
-      startProfiling();
-    }
-    catch (e) { }
-
-    // Delete the bookmarks
-    let start = Date.now();
-    synthesizeKey("VK_BACK_SPACE", {}, aWin);
-    let end = Date.now();
-
-    // Stop profiling, if we can
-    try {
-      stopProfiling();
-    }
-    catch (e) { }
-
-    // Close the window, and write the results out
-    aWin.close();
-    document.getElementById("test-result").value =
-      "Duration was " + String(end - start) + "ms";
-
-    SimpleTest.finish();
-  }
-
-  // And open the window
-  wm.getMostRecentWindow("navigator:browser")
-    .openDialog("chrome://browser/content/places/places.xul",
-                "", "chrome,toolbar=yes,dialog=no,resizable",
-                "UnfiledBookmarks");
-
-  SimpleTest.waitForExplicitFinish();
-}
-
-  ]]>
-  </script>
-
-  <body xmlns="http://www.w3.org/1999/xhtml">
-    <p id="display"></p>
-    <div id="content" style="display:none;"></div>
-    <pre id="test"></pre>
-  </body>
-  <label id="test-result"/>
-</window>
--- a/browser/components/preferences/aboutPermissions.xul
+++ b/browser/components/preferences/aboutPermissions.xul
@@ -147,17 +147,17 @@
       </hbox>
 
       <!-- Cookies -->
       <hbox id="cookie-pref-item"
             class="pref-item" align="top">
         <image class="pref-icon" type="cookie"/>
         <vbox>
           <label class="pref-title" value="&cookie.label;"/>
-          <hbox algin="center">
+          <hbox align="center">
             <menulist id="cookie-menulist"
                       class="pref-menulist"
                       type="cookie"
                       oncommand="AboutPermissions.onPermissionCommand(event);">
               <menupopup>
                 <menuitem id="cookie-1" value="1" label="&permission.allow;"/>
                 <menuitem id="cookie-8" value="8" label="&permission.allowForSession;"/>
                 <menuitem id="cookie-2" value="2" label="&permission.block;"/>
--- a/browser/components/sessionstore/src/nsSessionStartup.js
+++ b/browser/components/sessionstore/src/nsSessionStartup.js
@@ -152,28 +152,26 @@ SessionStartup.prototype = {
       this._sessionType = Ci.nsISessionStartup.RECOVER_SESSION;
     else if (!lastSessionCrashed && doResumeSession)
       this._sessionType = Ci.nsISessionStartup.RESUME_SESSION;
     else if (initialState)
       this._sessionType = Ci.nsISessionStartup.DEFER_SESSION;
     else
       this._iniString = null; // reset the state string
 
-    if (this.doRestore()) {
-      // wait for the first browser window to open
+    // wait for the first browser window to open
+    // Don't reset the initial window's default args (i.e. the home page(s))
+    // if all stored tabs are pinned.
+    if (this.doRestore() &&
+        (!initialState.windows ||
+        !initialState.windows.every(function (win)
+           win.tabs.every(function (tab) tab.pinned))))
+      Services.obs.addObserver(this, "domwindowopened", true);
 
-      // Don't reset the initial window's default args (i.e. the home page(s))
-      // if all stored tabs are pinned.
-      if (!initialState.windows ||
-          !initialState.windows.every(function (win)
-             win.tabs.every(function (tab) tab.pinned)))
-        Services.obs.addObserver(this, "domwindowopened", true);
-
-      Services.obs.addObserver(this, "sessionstore-windows-restored", true);
-    }
+    Services.obs.addObserver(this, "sessionstore-windows-restored", true);
   },
 
   /**
    * Handle notifications
    */
   observe: function sss_observe(aSubject, aTopic, aData) {
     switch (aTopic) {
     case "app-startup": 
@@ -195,28 +193,19 @@ SessionStartup.prototype = {
       var self = this;
       window.addEventListener("load", function() {
         self._onWindowOpened(window);
         window.removeEventListener("load", arguments.callee, false);
       }, false);
       break;
     case "sessionstore-windows-restored":
       Services.obs.removeObserver(this, "sessionstore-windows-restored");
-      // We only want to start listening for the purge notification after we've
-      // sessionstore has finished its initial startup. That way we won't observe
-      // the purge notification & clear the old session before sessionstore loads
-      // it (in the case of a crash).
-      Services.obs.addObserver(this, "browser:purge-session-history", true);
-      break;
-    case "browser:purge-session-history":
-      // reset all state on sanitization
+      // free _iniString after nsSessionStore is done with it
       this._iniString = null;
       this._sessionType = Ci.nsISessionStartup.NO_SESSION;
-      // no need in repeating this, since startup state won't change
-      Services.obs.removeObserver(this, "browser:purge-session-history");
       break;
     }
   },
 
   /**
    * Removes the default arguments from the first browser window
    * (and removes the "domwindowopened" observer afterwards).
    */
--- a/browser/components/sessionstore/src/nsSessionStore.js
+++ b/browser/components/sessionstore/src/nsSessionStore.js
@@ -2899,17 +2899,17 @@ SessionStoreService.prototype = {
 
       didStartLoad = true;
       try {
         // In order to work around certain issues in session history, we need to
         // force session history to update its internal index and call reload
         // instead of gotoIndex. See bug 597315.
         browser.webNavigation.sessionHistory.getEntryAtIndex(activeIndex, true);
         browser.webNavigation.sessionHistory.
-          QueryInterface(Ci.nsISHistory_2_0_BRANCH).reloadCurrentEntry();
+          QueryInterface(Ci.nsISHistory).reloadCurrentEntry();
       }
       catch (ex) {
         // ignore page load errors
         aTab.removeAttribute("busy");
         didStartLoad = false;
       }
     }
 
--- a/browser/components/sessionstore/test/browser/browser_346337_sample.html
+++ b/browser/components/sessionstore/test/browser/browser_346337_sample.html
@@ -1,37 +1,37 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
-<title>Test for bug 346337</title>
-
-<h3>Text Fields</h3>
-<input type="text" name="input">
-<input type="text" name="spaced 1">
-<input>
-
-<h3>Checkboxes and Radio buttons</h3>
-<input type="checkbox" name="check"> Check 1
-<input type="checkbox" name="uncheck" checked> Check 2
-<p>
-<input type="radio" name="group" value="1"> Radio 1
-<input type="radio" name="group" value="some"> Radio 2
-<input type="radio" name="group" checked> Radio 3
-
-<h3>Selects</h3>
-<select name="any">  
-  <option value="1"> Select 1  
-  <option value="some"> Select 2 
-  <option>Select 3
-</select>
-<select multiple="multiple">  
-  <option value=1> Multi-select 1
-  <option value=2> Multi-select 2  
-  <option value=3> Multi-select 3
-  <option value=4> Multi-select 4
-</select> 
-
-<h3>Text Areas</h3>
-<textarea name="testarea"></textarea>
-<textarea name="sized one" rows="5" cols="25"></textarea>
-<textarea></textarea>
-
-<h3>File Selector</h3>
-<input type="file">
-<input type="file" multiple>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
+<title>Test for bug 346337</title>
+
+<h3>Text Fields</h3>
+<input type="text" name="input">
+<input type="text" name="spaced 1">
+<input>
+
+<h3>Checkboxes and Radio buttons</h3>
+<input type="checkbox" name="check"> Check 1
+<input type="checkbox" name="uncheck" checked> Check 2
+<p>
+<input type="radio" name="group" value="1"> Radio 1
+<input type="radio" name="group" value="some"> Radio 2
+<input type="radio" name="group" checked> Radio 3
+
+<h3>Selects</h3>
+<select name="any">  
+  <option value="1"> Select 1  
+  <option value="some"> Select 2 
+  <option>Select 3
+</select>
+<select multiple="multiple">  
+  <option value=1> Multi-select 1
+  <option value=2> Multi-select 2  
+  <option value=3> Multi-select 3
+  <option value=4> Multi-select 4
+</select> 
+
+<h3>Text Areas</h3>
+<textarea name="testarea"></textarea>
+<textarea name="sized one" rows="5" cols="25"></textarea>
+<textarea></textarea>
+
+<h3>File Selector</h3>
+<input type="file">
+<input type="file" multiple>
--- a/browser/components/sessionstore/test/browser/browser_454908_sample.html
+++ b/browser/components/sessionstore/test/browser/browser_454908_sample.html
@@ -1,8 +1,8 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
-<title>Test for bug 454908</title>
-
-<h3>Dummy Login</h3>
-<form>
-<p>Username: <input type="text" id="username">
-<p>Password: <input type="password" id="passwd">
-</form>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
+<title>Test for bug 454908</title>
+
+<h3>Dummy Login</h3>
+<form>
+<p>Username: <input type="text" id="username">
+<p>Password: <input type="password" id="passwd">
+</form>
--- a/browser/components/sessionstore/test/browser/browser_476161_sample.html
+++ b/browser/components/sessionstore/test/browser/browser_476161_sample.html
@@ -1,24 +1,24 @@
-<!DOCTYPE html>
-<title>Test for bug 476161</title>
-
-<script>
-
-document.addEventListener("input", function(aEvent) {
-  var inputEl = aEvent.originalTarget;
-  var changedEl = document.getElementById("changed");
-  
-  changedEl.textContent += " " + inputEl.id;
-}, false);
-
-</script>
-
-<h3>Text fields with changed text</h3>
-<input type="text" id="modify1">
-<input type="text" id="modify2" value="preset value">
-
-<h3>Text fields with unchanged text</h3>
-<input type="text" id="unchanged1">
-<input type="text" id="unchanged2" value="preset value">
-
-<h3>Changed field IDs</h3>
-<div id="changed"></div>
+<!DOCTYPE html>
+<title>Test for bug 476161</title>
+
+<script>
+
+document.addEventListener("input", function(aEvent) {
+  var inputEl = aEvent.originalTarget;
+  var changedEl = document.getElementById("changed");
+  
+  changedEl.textContent += " " + inputEl.id;
+}, false);
+
+</script>
+
+<h3>Text fields with changed text</h3>
+<input type="text" id="modify1">
+<input type="text" id="modify2" value="preset value">
+
+<h3>Text fields with unchanged text</h3>
+<input type="text" id="unchanged1">
+<input type="text" id="unchanged2" value="preset value">
+
+<h3>Changed field IDs</h3>
+<div id="changed"></div>
--- a/browser/components/sessionstore/test/browser/browser_485482_sample.html
+++ b/browser/components/sessionstore/test/browser/browser_485482_sample.html
@@ -1,12 +1,12 @@
-<!DOCTYPE html>
-<title>Test for bug 485482</title>
-
-<bad=name>
-  <input type="text">
-</bad=name>
-
-<worse=name>
-  <l0c@l+na~e"'>
-    <input type="checkbox" name="check"> Check
-  </l0c@l+na~e"'>
-</worse=name>
+<!DOCTYPE html>
+<title>Test for bug 485482</title>
+
+<bad=name>
+  <input type="text">
+</bad=name>
+
+<worse=name>
+  <l0c@l+na~e"'>
+    <input type="checkbox" name="check"> Check
+  </l0c@l+na~e"'>
+</worse=name>
--- a/browser/installer/removed-files.in
+++ b/browser/installer/removed-files.in
@@ -73,31 +73,40 @@ components/pluginGlue.js
 components/sidebar.xpt
 components/WeaveCrypto.js
 components/WeaveCrypto.manifest
 components/xmlextras.xpt
 components/xpcom.xpt
 components/xpti.dat
 components/xptitemp.dat
 components/nsMicrosummaryService.js
+D3DCompiler_42.dll
+d3dx9_42.dll
 defaults/pref/all.js
 defaults/pref/bug259708.js
 defaults/pref/bug307259.js
 defaults/pref/reporter.js
 defaults/pref/security-prefs.js
 defaults/pref/winpref.js
 defaults/pref/xpinstall.js
 defaults/profile/US/
 defaults/profile/extensions/
 defaults/profile/extensions/Extensions.rdf
 defaults/profile/extensions/installed-extensions.txt
 defaults/profile/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/
 defaults/profile/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/install.rdf
 defaults/profile/search.rdf
 #ifndef SHIP_FEEDBACK
+# In the average case, this directory is only used by Test Pilot, and will get
+# removed by the updater. In some cases (eg, partner builds), distribution/
+# will have other files and/or directories in it. In these cases, the updater
+# will print a non-fatal error and continue on, because we're not appending
+# '*' to force a recursive removal.
+distribution/
+distribution/extensions/
 distribution/extensions/testpilot@labs.mozilla.com.xpi
 #endif
 extensions/talkback@mozilla.org/
 extensions/talkback@mozilla.org/chrome.manifest
 extensions/talkback@mozilla.org/components/@DLL_PREFIX@qfaservices@DLL_SUFFIX@
 extensions/talkback@mozilla.org/components/qfaservices.xpt
 extensions/talkback@mozilla.org/install.rdf
 extensions/{641d8d09-7dda-4850-8228-ac0ab65e2ac9}/
@@ -260,17 +269,16 @@ res/loading-image.png
 res/maccharset.properties
 res/mathml.css
 res/os2charset.properties
 res/quirk.css
 res/ua.css
 res/unixcharset.properties
 res/viewsource.css
 res/wincharset.properties
-searchplugins/
 searchplugins/DRAE.gif
 searchplugins/DRAE.png
 searchplugins/DRAE.src
 searchplugins/MediaDICO-fr.gif
 searchplugins/MediaDICO-fr.png
 searchplugins/MediaDICO-fr.src
 searchplugins/allegro-pl.gif
 searchplugins/allegro-pl.png
--- a/build/pgo/profileserver.py
+++ b/build/pgo/profileserver.py
@@ -59,35 +59,53 @@ os.chdir(SCRIPT_DIR)
 
 class EasyServer(SocketServer.TCPServer):
   allow_reuse_address = True
 
 if __name__ == '__main__':
   from optparse import OptionParser
   automation = Automation()
 
-  parser = OptionParser()
+  parser = OptionParser(usage='OBJDIR=path/to/objdir python %prog [NUM_RUNS]')
   addCommonOptions(parser)
 
   options, args = parser.parse_args()
 
+  if not os.getenv('OBJDIR'):
+      parser.error('Please specify the OBJDIR environment variable.')
+
+  if not args:
+      num_runs = 1
+  else:
+      try:
+          num_runs = int(args[0])
+      except:
+          parser.error('NUM_RUNS argument must be an integer.')
+      if num_runs < 1:
+          parser.error('NUM_RUNS must be greater than zero.')
+
   debuggerInfo = getDebuggerInfo(".", options.debugger, options.debuggerArgs,
           options.debuggerInteractive)
 
   httpd = EasyServer(("", PORT), SimpleHTTPServer.SimpleHTTPRequestHandler)
   t = threading.Thread(target=httpd.serve_forever)
   t.setDaemon(True) # don't hang on exit
   t.start()
   
   automation.setServerInfo("localhost", PORT)
   automation.initializeProfile(PROFILE_DIRECTORY)
   browserEnv = automation.environment()
   browserEnv["XPCOM_DEBUG_BREAK"] = "warn"
   browserEnv["MOZ_JAR_LOG_DIR"] = MOZ_JAR_LOG_DIR
 
   url = "http://localhost:%d/index.html" % PORT
   appPath = os.path.join(SCRIPT_DIR, automation.DEFAULT_APP)
-  status = automation.runApp(url, browserEnv, appPath, PROFILE_DIRECTORY, {},
-                             debuggerInfo=debuggerInfo,
-                             # the profiling HTML doesn't output anything,
-                             # so let's just run this without a timeout
-                             timeout = None)
-  sys.exit(status)
+
+  for i in range(0, num_runs):
+      if num_runs != 1:
+          print "Starting profiling run %d of %d" % (i + 1, num_runs)
+      status = automation.runApp(url, browserEnv, appPath, PROFILE_DIRECTORY, {},
+                                 debuggerInfo=debuggerInfo,
+                                 # the profiling HTML doesn't output anything,
+                                 # so let's just run this without a timeout
+                                 timeout = None)
+      if status != 0:
+          sys.exit(status)
--- a/build/pgo/server-locations.txt
+++ b/build/pgo/server-locations.txt
@@ -122,16 +122,20 @@ https://untrusted.example.com:443      p
 https://expired.example.com:443        privileged,cert=expired
 https://requestclientcert.example.com:443         privileged,clientauth=request
 https://requireclientcert.example.com:443         privileged,clientauth=require
 
 # This is here so that we don't load the default live bookmark over
 # the network in every test suite.
 http://fxfeeds.mozilla.com:80
 
+# Prevent safebrowsing tests from hitting the network for its-a-trap.html and
+# its-an-attack.html.
+http://www.mozilla.com:80
+
 #
 # These are subdomains of <ält.example.org>.
 #
 http://sub1.xn--lt-uia.example.org:8000   privileged
 http://sub2.xn--lt-uia.example.org:80     privileged
 http://xn--exmple-cua.test:80             privileged
 http://sub1.xn--exmple-cua.test:80        privileged
 
--- a/build/stdc++compat.cpp
+++ b/build/stdc++compat.cpp
@@ -32,20 +32,17 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include <ostream>
 #include <istream>
-#ifdef DEBUG
 #include <string>
-#endif
-
 
 /* GLIBCXX_3.4.8  is from gcc 4.1.1 (111691)
    GLIBCXX_3.4.9  is from gcc 4.2.0 (111690)
    GLIBCXX_3.4.10 is from gcc 4.3.0 (126287)
    GLIBCXX_3.4.11 is from gcc 4.4.0 (133006)
    GLIBCXX_3.4.12 is from gcc 4.4.1 (147138)
    GLIBCXX_3.4.13 is from gcc 4.4.2 (151127)
    GLIBCXX_3.4.14 is from gcc 4.5.0 (151126)
@@ -58,33 +55,31 @@ namespace std {
 #if MOZ_LIBSTDCXX_VERSION >= GLIBCXX_VERSION(3, 4, 9)
     /* Instantiate these templates to avoid GLIBCXX_3.4.9 symbol versions */
     template ostream& ostream::_M_insert(double);
     template ostream& ostream::_M_insert(long);
     template ostream& ostream::_M_insert(unsigned long);
     template ostream& __ostream_insert(ostream&, const char*, streamsize);
     template istream& istream::_M_extract(double&);
 #endif
-#ifdef DEBUG
 #if MOZ_LIBSTDCXX_VERSION >= GLIBCXX_VERSION(3, 4, 14)
     /* Instantiate these templates to avoid GLIBCXX_3.4.14 symbol versions
-     * in debug builds */
+     * depending on optimization level */
     template char *string::_S_construct_aux_2(size_type, char, allocator<char> const&);
 #ifdef _GLIBCXX_USE_WCHAR_T
     template wchar_t *wstring::_S_construct_aux_2(size_type, wchar_t, allocator<wchar_t> const&);
 #endif /* _GLIBCXX_USE_WCHAR_T */
 #ifdef __GXX_EXPERIMENTAL_CXX0X__
     template string::basic_string(string&&);
     template string& string::operator=(string&&);
     template wstring::basic_string(wstring&&);
     template wstring& wstring::operator=(wstring&&);
     template wstring& wstring::assign(wstring&&);
 #endif /* __GXX_EXPERIMENTAL_CXX0X__ */
 #endif /* (__GNUC__ == 4) && (__GNUC_MINOR__ >= 5) */
-#endif /* DEBUG */
 }
 
 namespace std __attribute__((visibility("default"))) {
 #if MOZ_LIBSTDCXX_VERSION >= GLIBCXX_VERSION(3, 4, 14)
     /* Hack to avoid GLIBCXX_3.4.14 symbol versions */
     struct _List_node_base
     {
         void hook(_List_node_base * const __position) throw ();
--- a/build/unix/elfhack/Makefile.in
+++ b/build/unix/elfhack/Makefile.in
@@ -115,8 +115,9 @@ GARBAGE_DIRS += inject
 OS_CXXFLAGS := $(filter-out -pedantic,$(OS_CXXFLAGS))
 
 include $(topsrcdir)/config/rules.mk
 
 inject/%.$(OBJ_SUFFIX): DEFINES += -DBITS=$(if $(HAVE_64BIT_OS),64,32)
 inject/%.$(OBJ_SUFFIX): CFLAGS := -O2 -fno-stack-protector $(filter -m% -I%,$(CFLAGS))
 inject/$(CPU)-noinit.$(OBJ_SUFFIX): DEFINES += -DNOINIT
 test.$(OBJ_SUFFIX): CFLAGS := -O0
+host_elf.$(OBJ_SUFFIX) host_elfhack.$(OBJ_SUFFIX): elfxx.h
--- a/build/unix/elfhack/elfxx.h
+++ b/build/unix/elfhack/elfxx.h
@@ -443,16 +443,19 @@ public:
         unsigned int addr = section->getAddr();
         // This may be biased, but should work in most cases
         if ((section->getFlags() & SHF_ALLOC) == 0)
             return false;
         // Special case for PT_DYNAMIC. Eventually, this should
         // be better handled than special cases
         if ((p_type == PT_DYNAMIC) && (section->getType() != SHT_DYNAMIC))
             return false;
+        // Special case for PT_TLS.
+        if ((p_type == PT_TLS) && !(section->getFlags() & SHF_TLS))
+            return false;
         return (addr >= p_vaddr) &&
                (addr + size <= p_vaddr + p_memsz);
 
     }
 };
 
 typedef serializable<Elf_Dyn_Traits> Elf_Dyn;
 
--- a/build/unix/elfhack/test.c
+++ b/build/unix/elfhack/test.c
@@ -110,18 +110,20 @@ const char *strings2[] = {
 static int ret = 1;
 
 __attribute__((visibility("default"))) int print_status() {
     fprintf(stderr, "%s\n", ret ? "FAIL" : "PASS");
     return ret;
 }
 
 /* On ARM, this creates a .tbss section before .init_array, which
- * elfhack could then pick instead of .init_array */
-__thread int foo;
+ * elfhack could then pick instead of .init_array.
+ * Also, when .tbss is big enough, elfhack may wrongfully consider
+ * following sections as part of the PT_TLS segment. */
+__thread int foo[1024];
 
 __attribute__((constructor)) void end_test() {
     static int count = 0;
     /* Only exit when both constructors have been called */
     if (++count == 2)
         ret = 0;
 }
 
--- a/caps/include/nsScriptSecurityManager.h
+++ b/caps/include/nsScriptSecurityManager.h
@@ -45,17 +45,16 @@
 #include "nsIScriptSecurityManager.h"
 #include "nsIPrincipal.h"
 #include "jsapi.h"
 #include "jsdbgapi.h"
 #include "nsIXPCSecurityManager.h"
 #include "nsInterfaceHashtable.h"
 #include "nsHashtable.h"
 #include "nsCOMPtr.h"
-#include "nsIPrefService.h"
 #include "nsIChannelEventSink.h"
 #include "nsIJSContextStack.h"
 #include "nsIObserver.h"
 #include "pldhash.h"
 #include "plstr.h"
 #include "nsIScriptExternalNameSet.h"
 
 class nsIDocShell;
@@ -612,34 +611,30 @@ private:
     };
 
     // JS strings we need to clean up on shutdown
     static jsid sEnabledID;
 
     inline void
     ScriptSecurityPrefChanged();
 
-    static const char sJSEnabledPrefName[];
-    static const char sFileOriginPolicyPrefName[];
-
     nsObjectHashtable* mOriginToPolicyMap;
     DomainPolicy* mDefaultPolicy;
     nsObjectHashtable* mCapabilities;
 
-    nsCOMPtr<nsIPrefBranch> mPrefBranch;
     nsCOMPtr<nsIPrincipal> mSystemPrincipal;
     nsCOMPtr<nsIPrincipal> mSystemCertificate;
     ContextPrincipal *mContextPrincipals;
     nsInterfaceHashtable<PrincipalKey, nsIPrincipal> mPrincipals;
+    PRPackedBool mPrefInitialized;
     PRPackedBool mIsJavaScriptEnabled;
     PRPackedBool mIsWritingPrefs;
     PRPackedBool mPolicyPrefsChanged;
 #ifdef XPC_IDISPATCH_SUPPORT    
     PRPackedBool mXPCDefaultGrantAll;
-    static const char sXPCDefaultGrantAllName[];
 #endif
 
     static PRBool sStrictFileOriginPolicy;
 
     static nsIIOService    *sIOService;
     static nsIXPConnect    *sXPConnect;
     static nsIThreadJSContextStack* sJSContextStack;
     static nsIStringBundle *sStrBundle;
--- a/caps/src/nsPrincipal.cpp
+++ b/caps/src/nsPrincipal.cpp
@@ -48,87 +48,28 @@
 #include "nsIFileURL.h"
 #include "nsIProtocolHandler.h"
 #include "nsNetUtil.h"
 #include "nsJSPrincipals.h"
 #include "nsVoidArray.h"
 #include "nsHashtable.h"
 #include "nsIObjectInputStream.h"
 #include "nsIObjectOutputStream.h"
-#include "nsIPrefBranch2.h"
-#include "nsIPrefService.h"
 #include "nsIClassInfoImpl.h"
 #include "nsDOMError.h"
 #include "nsIContentSecurityPolicy.h"
 
 #include "nsPrincipal.h"
 
-class nsCodeBasePrefObserver : nsIObserver
-{
-public:
-  nsCodeBasePrefObserver()
-  {
-    NS_ASSERTION(!sObserverInstalled, "Shouldn't recreate observer\n");
-  }
-  ~nsCodeBasePrefObserver()
-  {
-    sObserverInstalled = PR_FALSE;
-  }
-
-  void Init()
-  {
-    nsCOMPtr<nsIPrefBranch2> prefBranch =
-      do_GetService(NS_PREFSERVICE_CONTRACTID);
-    if (prefBranch) {
-      if (NS_FAILED(prefBranch->GetBoolPref(PrefName(), &sPrefValue))) {
-        sPrefValue = PR_FALSE;
-      }
-      if (NS_SUCCEEDED(prefBranch->AddObserver(PrefName(), this, PR_FALSE))) {
-        sObserverInstalled = PR_TRUE;
-      }
-    }
-  }
-
-  NS_DECL_ISUPPORTS
+#include "mozilla/Preferences.h"
 
-  NS_IMETHOD Observe(nsISupports* aSubject,
-                     const char* aTopic,
-                     const PRUnichar* aData)
-  {
-    NS_ASSERTION(!strcmp(aTopic,  NS_PREFBRANCH_PREFCHANGE_TOPIC_ID),
-                 "Wrong topic!");
-    NS_ASSERTION(!strcmp(NS_ConvertUTF16toUTF8(aData).get(), PrefName()),
-                 "Wrong pref!");
-
-    nsCOMPtr<nsIPrefBranch> prefBranch(do_QueryInterface(aSubject));
-    if (!prefBranch ||
-        NS_FAILED(prefBranch->GetBoolPref(PrefName(), &sPrefValue))) {
-      sPrefValue = PR_FALSE;
-    }
-    return NS_OK;
-  }
+using namespace mozilla;
 
-  const char* PrefName()
-  {
-    static const char pref[] = "signed.applets.codebase_principal_support";
-    return pref;
-  }
-
-  static PRBool PrefValue() { return sPrefValue; }
-  static PRBool Installed() { return sObserverInstalled; }
-
-
-protected:
-  static PRBool sPrefValue;
-  static PRBool sObserverInstalled;
-};
-
-PRBool nsCodeBasePrefObserver::sPrefValue = PR_FALSE;
-PRBool nsCodeBasePrefObserver::sObserverInstalled = PR_FALSE;
-NS_IMPL_ISUPPORTS1(nsCodeBasePrefObserver, nsIObserver)
+static PRBool gCodeBasePrincipalSupport = PR_FALSE;
+static PRBool gIsObservingCodeBasePrincipalSupport = PR_FALSE;
 
 static PRBool URIIsImmutable(nsIURI* aURI)
 {
   nsCOMPtr<nsIMutable> mutableObj(do_QueryInterface(aURI));
   PRBool isMutable;
   return
     mutableObj &&
     NS_SUCCEEDED(mutableObj->GetMutable(&isMutable)) &&
@@ -175,22 +116,24 @@ nsPrincipal::Release()
 nsPrincipal::nsPrincipal()
   : mCapabilities(nsnull),
     mSecurityPolicy(nsnull),
     mTrusted(PR_FALSE),
     mInitialized(PR_FALSE),
     mCodebaseImmutable(PR_FALSE),
     mDomainImmutable(PR_FALSE)
 {
-  if (!nsCodeBasePrefObserver::Installed()) {
-    nsRefPtr<nsCodeBasePrefObserver> obs = new nsCodeBasePrefObserver();
-    if (obs)
-      obs->Init();
-    NS_WARN_IF_FALSE(nsCodeBasePrefObserver::Installed(),
-                     "Installing nsCodeBasePrefObserver failed!");
+  if (!gIsObservingCodeBasePrincipalSupport) {
+    nsresult rv =
+      Preferences::AddBoolVarCache(&gCodeBasePrincipalSupport,
+                                   "signed.applets.codebase_principal_support",
+                                   PR_FALSE);
+    gIsObservingCodeBasePrincipalSupport = NS_SUCCEEDED(rv);
+    NS_WARN_IF_FALSE(gIsObservingCodeBasePrincipalSupport,
+                     "Installing gCodeBasePrincipalSupport failed!");
   }
 }
 
 nsresult
 nsPrincipal::Init(const nsACString& aCertFingerprint,
                   const nsACString& aSubjectName,
                   const nsACString& aPrettyName,
                   nsISupports* aCert,
@@ -533,17 +476,17 @@ nsPrincipal::CanEnableCapability(const c
                                "uninitialized principal");
 
     // If we are a non-trusted codebase principal, capabilities can not
     // be enabled if the user has not set the pref allowing scripts to
     // request enhanced capabilities; however, the file: and resource:
     // schemes are special and may be able to get extra capabilities
     // even with the pref disabled.
 
-    if (!nsCodeBasePrefObserver::PrefValue()) {
+    if (!gCodeBasePrincipalSupport) {
       PRBool mightEnable = PR_FALSE;
       nsresult rv = mCodebase->SchemeIs("file", &mightEnable);
       if (NS_FAILED(rv) || !mightEnable) {
         rv = mCodebase->SchemeIs("resource", &mightEnable);
         if (NS_FAILED(rv) || !mightEnable) {
           *result = nsIPrincipal::ENABLE_DENIED;
 
           return NS_OK;
--- a/caps/src/nsScriptSecurityManager.cpp
+++ b/caps/src/nsScriptSecurityManager.cpp
@@ -76,30 +76,32 @@
 #include "nsIScriptGlobalObject.h"
 #include "nsPIDOMWindow.h"
 #include "nsIDocShell.h"
 #include "nsIDocShellTreeItem.h"
 #include "nsIPrompt.h"
 #include "nsIWindowWatcher.h"
 #include "nsIConsoleService.h"
 #include "nsISecurityCheckedComponent.h"
-#include "nsIPrefBranch2.h"
 #include "nsIJSRuntimeService.h"
 #include "nsIObserverService.h"
 #include "nsIContent.h"
 #include "nsAutoPtr.h"
 #include "nsDOMJSUtils.h"
 #include "nsAboutProtocolUtils.h"
 #include "nsIClassInfo.h"
 #include "nsIURIFixup.h"
 #include "nsCDefaultURIFixup.h"
 #include "nsIChromeRegistry.h"
 #include "nsPrintfCString.h"
 #include "nsIContentSecurityPolicy.h"
 #include "nsIAsyncVerifyRedirectCallback.h"
+#include "mozilla/Preferences.h"
+
+using namespace mozilla;
 
 static NS_DEFINE_CID(kZipReaderCID, NS_ZIPREADER_CID);
 
 nsIIOService    *nsScriptSecurityManager::sIOService = nsnull;
 nsIXPConnect    *nsScriptSecurityManager::sXPConnect = nsnull;
 nsIThreadJSContextStack *nsScriptSecurityManager::sJSContextStack = nsnull;
 nsIStringBundle *nsScriptSecurityManager::sStrBundle = nsnull;
 JSRuntime       *nsScriptSecurityManager::sRuntime   = 0;
@@ -1116,17 +1118,17 @@ nsScriptSecurityManager::LookupPolicy(ns
 {
     nsresult rv;
     result->level = SCRIPT_SECURITY_UNDEFINED_ACCESS;
 
     DomainPolicy* dpolicy = nsnull;
     //-- Initialize policies if necessary
     if (mPolicyPrefsChanged)
     {
-        if (!mPrefBranch) {
+        if (!mPrefInitialized) {
             rv = InitPrefs();
             NS_ENSURE_SUCCESS(rv, rv);
         }
         rv = InitPolicies();
         if (NS_FAILED(rv))
             return rv;
     }
     else
@@ -2532,40 +2534,40 @@ nsScriptSecurityManager::SavePrincipal(n
     nsCAutoString subjectNamePrefName;
     rv = GetPrincipalPrefNames( idPrefName,
                                 grantedPrefName,
                                 deniedPrefName,
                                 subjectNamePrefName );
     if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
 
     mIsWritingPrefs = PR_TRUE;
-    if (grantedList)
-        mPrefBranch->SetCharPref(grantedPrefName.get(), grantedList);
-    else
-        mPrefBranch->ClearUserPref(grantedPrefName.get());
-
-    if (deniedList)
-        mPrefBranch->SetCharPref(deniedPrefName.get(), deniedList);
-    else
-        mPrefBranch->ClearUserPref(deniedPrefName.get());
+    if (grantedList) {
+        Preferences::SetCString(grantedPrefName.get(), grantedList);
+    } else {
+        Preferences::ClearUser(grantedPrefName.get());
+    }
+
+    if (deniedList) {
+        Preferences::SetCString(deniedPrefName.get(), deniedList);
+    } else {
+        Preferences::ClearUser(deniedPrefName.get());
+    }
 
     if (grantedList || deniedList) {
-        mPrefBranch->SetCharPref(idPrefName, id);
-        mPrefBranch->SetCharPref(subjectNamePrefName.get(),
-                                           subjectName);
-    }
-    else {
-        mPrefBranch->ClearUserPref(idPrefName);
-        mPrefBranch->ClearUserPref(subjectNamePrefName.get());
+        Preferences::SetCString(idPrefName, id);
+        Preferences::SetCString(subjectNamePrefName.get(), subjectName);
+    } else {
+        Preferences::ClearUser(idPrefName);
+        Preferences::ClearUser(subjectNamePrefName.get());
     }
 
     mIsWritingPrefs = PR_FALSE;
 
-    nsCOMPtr<nsIPrefService> prefService(do_GetService(NS_PREFSERVICE_CONTRACTID, &rv));
-    NS_ENSURE_SUCCESS(rv, rv);
+    nsIPrefService* prefService = Preferences::GetService();
+    NS_ENSURE_TRUE(prefService, NS_ERROR_FAILURE);
     return prefService->SavePrefFile(nsnull);
 }
 
 ///////////////// Capabilities API /////////////////////
 NS_IMETHODIMP
 nsScriptSecurityManager::IsCapabilityEnabled(const char *capability,
                                              PRBool *result)
 {
@@ -3327,19 +3329,37 @@ nsScriptSecurityManager::AsyncOnChannelR
     cb->OnRedirectVerifyCallback(NS_OK);
     return NS_OK;
 }
 
 
 /////////////////////////////////////
 // Method implementing nsIObserver //
 /////////////////////////////////////
+const char sJSEnabledPrefName[] = "javascript.enabled";
+const char sFileOriginPolicyPrefName[] =
+    "security.fileuri.strict_origin_policy";
+#ifdef XPC_IDISPATCH_SUPPORT
+const char sXPCDefaultGrantAllName[] = "security.classID.allowByDefault";
+#endif
 static const char sPrincipalPrefix[] = "capability.principal";
 static const char sPolicyPrefix[] = "capability.policy.";
 
+static const char* kObservedPrefs[] = {
+  sJSEnabledPrefName,
+  sFileOriginPolicyPrefName,
+#ifdef XPC_IDISPATCH_SUPPORT
+  sXPCDefaultGrantAllName,
+#endif
+  sPolicyPrefix,
+  sPrincipalPrefix,
+  nsnull
+};
+
+
 NS_IMETHODIMP
 nsScriptSecurityManager::Observe(nsISupports* aObject, const char* aTopic,
                                  const PRUnichar* aMessage)
 {
     nsresult rv = NS_OK;
     NS_ConvertUTF16toUTF8 messageStr(aMessage);
     const char *message = messageStr.get();
 
@@ -3374,16 +3394,17 @@ nsScriptSecurityManager::Observe(nsISupp
 /////////////////////////////////////////////
 // Constructor, Destructor, Initialization //
 /////////////////////////////////////////////
 nsScriptSecurityManager::nsScriptSecurityManager(void)
     : mOriginToPolicyMap(nsnull),
       mDefaultPolicy(nsnull),
       mCapabilities(nsnull),
       mContextPrincipals(nsnull),
+      mPrefInitialized(PR_FALSE),
       mIsJavaScriptEnabled(PR_FALSE),
       mIsWritingPrefs(PR_FALSE),
       mPolicyPrefsChanged(PR_TRUE)
 #ifdef XPC_IDISPATCH_SUPPORT
       , mXPCDefaultGrantAll(PR_FALSE)
 #endif
 {
     NS_ASSERTION(sizeof(PRWord) == sizeof(void*),
@@ -3458,16 +3479,17 @@ nsresult nsScriptSecurityManager::Init()
 }
 
 static nsScriptSecurityManager *gScriptSecMan = nsnull;
 
 jsid nsScriptSecurityManager::sEnabledID   = JSID_VOID;
 
 nsScriptSecurityManager::~nsScriptSecurityManager(void)
 {
+    Preferences::RemoveObservers(this, kObservedPrefs);
     NS_ASSERTION(!mContextPrincipals, "Leaking mContextPrincipals");
     delete mOriginToPolicyMap;
     if(mDefaultPolicy)
         mDefaultPolicy->Drop();
     delete mCapabilities;
     gScriptSecMan = nsnull;
 }
 
@@ -3583,23 +3605,21 @@ nsScriptSecurityManager::InitPolicies()
 
     // Get a JS context - we need it to create internalized strings later.
     JSContext* cx = GetSafeJSContext();
     NS_ASSERTION(cx, "failed to get JS context");
     AutoCxPusher autoPusher(sJSContextStack, cx);
     rv = InitDomainPolicy(cx, "default", mDefaultPolicy);
     NS_ENSURE_SUCCESS(rv, rv);
 
-    nsXPIDLCString policyNames;
-    rv = mPrefBranch->GetCharPref("capability.policy.policynames",
-                                            getter_Copies(policyNames));
-
-    nsXPIDLCString defaultPolicyNames;
-    rv = mPrefBranch->GetCharPref("capability.policy.default_policynames",
-                                            getter_Copies(defaultPolicyNames));
+    nsAdoptingCString policyNames =
+        Preferences::GetCString("capability.policy.policynames");
+
+    nsAdoptingCString defaultPolicyNames =
+        Preferences::GetCString("capability.policy.default_policynames");
     policyNames += NS_LITERAL_CSTRING(" ") + defaultPolicyNames;
 
     //-- Initialize domain policies
     char* policyCurrent = policyNames.BeginWriting();
     PRBool morePolicies = PR_TRUE;
     while (morePolicies)
     {
         while(*policyCurrent == ' ' || *policyCurrent == ',')
@@ -3614,21 +3634,21 @@ nsScriptSecurityManager::InitPolicies()
         morePolicies = (*policyCurrent != '\0');
         *policyCurrent = '\0';
         policyCurrent++;
 
         nsCAutoString sitesPrefName(
             NS_LITERAL_CSTRING(sPolicyPrefix) +
             nsDependentCString(nameBegin) +
             NS_LITERAL_CSTRING(".sites"));
-        nsXPIDLCString domainList;
-        rv = mPrefBranch->GetCharPref(sitesPrefName.get(),
-                                                getter_Copies(domainList));
-        if (NS_FAILED(rv))
+        nsAdoptingCString domainList =
+            Preferences::GetCString(sitesPrefName.get());
+        if (!domainList) {
             continue;
+        }
 
         DomainPolicy* domainPolicy = new DomainPolicy();
         if (!domainPolicy)
             return NS_ERROR_OUT_OF_MEMORY;
 
         if (!domainPolicy->Init())
         {
             delete domainPolicy;
@@ -3719,18 +3739,19 @@ nsScriptSecurityManager::InitDomainPolic
     nsresult rv;
     nsCAutoString policyPrefix(NS_LITERAL_CSTRING(sPolicyPrefix) +
                                nsDependentCString(aPolicyName) +
                                NS_LITERAL_CSTRING("."));
     PRUint32 prefixLength = policyPrefix.Length() - 1; // subtract the '.'
 
     PRUint32 prefCount;
     char** prefNames;
-    rv = mPrefBranch->GetChildList(policyPrefix.get(),
-                                   &prefCount, &prefNames);
+    nsIPrefBranch* branch = Preferences::GetRootBranch();
+    NS_ASSERTION(branch, "failed to get the root pref branch");
+    rv = branch->GetChildList(policyPrefix.get(), &prefCount, &prefNames);
     if (NS_FAILED(rv)) return rv;
     if (prefCount == 0)
         return NS_OK;
 
     //-- Populate the policy
     PRUint32 currentPref = 0;
     for (; currentPref < prefCount; currentPref++)
     {
@@ -3742,21 +3763,21 @@ nsScriptSecurityManager::InitDomainPolic
         static const char sitesStr[] = "sites";
 
         // We dealt with "sites" in InitPolicies(), so no need to do
         // that again...
         if (PL_strncmp(start, sitesStr, sizeof(sitesStr)-1) == 0)
             continue;
 
         // Get the pref value
-        nsXPIDLCString prefValue;
-        rv = mPrefBranch->GetCharPref(prefNames[currentPref],
-                                                getter_Copies(prefValue));
-        if (NS_FAILED(rv) || !prefValue)
+        nsAdoptingCString prefValue =
+            Preferences::GetCString(prefNames[currentPref]);
+        if (!prefValue) {
             continue;
+        }
 
         SecurityLevel secLevel;
         if (PL_strcasecmp(prefValue, "noAccess") == 0)
             secLevel.level = SCRIPT_SECURITY_NO_ACCESS;
         else if (PL_strcasecmp(prefValue, "allAccess") == 0)
             secLevel.level = SCRIPT_SECURITY_ALL_ACCESS;
         else if (PL_strcasecmp(prefValue, "sameOrigin") == 0)
             secLevel.level = SCRIPT_SECURITY_SAME_ORIGIN_ACCESS;
@@ -3899,49 +3920,47 @@ nsScriptSecurityManager::InitPrincipals(
     static const char idSuffix[] = ".id";
     for (PRUint32 c = 0; c < aPrefCount; c++)
     {
         PRInt32 prefNameLen = PL_strlen(aPrefNames[c]) - 
             (NS_ARRAY_LENGTH(idSuffix) - 1);
         if (PL_strcasecmp(aPrefNames[c] + prefNameLen, idSuffix) != 0)
             continue;
 
-        nsXPIDLCString id;
-        if (NS_FAILED(mPrefBranch->GetCharPref(aPrefNames[c], getter_Copies(id))))
+        nsAdoptingCString id = Preferences::GetCString(aPrefNames[c]);
+        if (!id) {
             return NS_ERROR_FAILURE;
+        }
 
         nsCAutoString grantedPrefName;
         nsCAutoString deniedPrefName;
         nsCAutoString subjectNamePrefName;
         nsresult rv = GetPrincipalPrefNames(aPrefNames[c],
                                             grantedPrefName,
                                             deniedPrefName,
                                             subjectNamePrefName);
         if (rv == NS_ERROR_OUT_OF_MEMORY)
             return rv;
         if (NS_FAILED(rv))
             continue;
 
-        nsXPIDLCString grantedList;
-        mPrefBranch->GetCharPref(grantedPrefName.get(),
-                                           getter_Copies(grantedList));
-        nsXPIDLCString deniedList;
-        mPrefBranch->GetCharPref(deniedPrefName.get(),
-                                           getter_Copies(deniedList));
-        nsXPIDLCString subjectName;
-        mPrefBranch->GetCharPref(subjectNamePrefName.get(),
-                                           getter_Copies(subjectName));
+        nsAdoptingCString grantedList =
+            Preferences::GetCString(grantedPrefName.get());
+        nsAdoptingCString deniedList =
+            Preferences::GetCString(deniedPrefName.get());
+        nsAdoptingCString subjectName =
+            Preferences::GetCString(subjectNamePrefName.get());
 
         //-- Delete prefs if their value is the empty string
         if (id.IsEmpty() || (grantedList.IsEmpty() && deniedList.IsEmpty()))
         {
-            mPrefBranch->ClearUserPref(aPrefNames[c]);
-            mPrefBranch->ClearUserPref(grantedPrefName.get());
-            mPrefBranch->ClearUserPref(deniedPrefName.get());
-            mPrefBranch->ClearUserPref(subjectNamePrefName.get());
+            Preferences::ClearUser(aPrefNames[c]);
+            Preferences::ClearUser(grantedPrefName.get());
+            Preferences::ClearUser(deniedPrefName.get());
+            Preferences::ClearUser(subjectNamePrefName.get());
             continue;
         }
 
         //-- Create a principal based on the prefs
         static const char certificateName[] = "capability.principal.certificate";
         static const char codebaseName[] = "capability.principal.codebase";
         static const char codebaseTrustedName[] = "capability.principal.codebaseTrusted";
 
@@ -3973,96 +3992,73 @@ nsScriptSecurityManager::InitPrincipals(
                                               grantedList, deniedList, nsnull, 
                                               isCert, isTrusted);
         if (NS_SUCCEEDED(rv))
             mPrincipals.Put(newPrincipal, newPrincipal);
     }
     return NS_OK;
 }
 
-const char nsScriptSecurityManager::sJSEnabledPrefName[] =
-    "javascript.enabled";
-const char nsScriptSecurityManager::sFileOriginPolicyPrefName[] =
-    "security.fileuri.strict_origin_policy";
-#ifdef XPC_IDISPATCH_SUPPORT
-const char nsScriptSecurityManager::sXPCDefaultGrantAllName[] =
-    "security.classID.allowByDefault";
-#endif
-
 inline void
 nsScriptSecurityManager::ScriptSecurityPrefChanged()
 {
     // JavaScript defaults to enabled in failure cases.
     mIsJavaScriptEnabled = PR_TRUE;
 
     sStrictFileOriginPolicy = PR_TRUE;
 
 #ifdef XPC_IDISPATCH_SUPPORT
     // Granting XPC Priveleges defaults to disabled in failure cases.
     mXPCDefaultGrantAll = PR_FALSE;
 #endif
 
     nsresult rv;
-    if (!mPrefBranch) {
+    if (!mPrefInitialized) {
         rv = InitPrefs();
         if (NS_FAILED(rv))
             return;
     }
 
-    PRBool temp;
-    rv = mPrefBranch->GetBoolPref(sJSEnabledPrefName, &temp);
-    if (NS_SUCCEEDED(rv))
-        mIsJavaScriptEnabled = temp;
-
-    rv = mPrefBranch->GetBoolPref(sFileOriginPolicyPrefName, &temp);
-    if (NS_SUCCEEDED(rv))
-        sStrictFileOriginPolicy = NS_SUCCEEDED(rv) && temp;
+    mIsJavaScriptEnabled =
+        Preferences::GetBool(sJSEnabledPrefName, mIsJavaScriptEnabled);
+
+    sStrictFileOriginPolicy =
+        Preferences::GetBool(sFileOriginPolicyPrefName, PR_FALSE);
 
 #ifdef XPC_IDISPATCH_SUPPORT
-    rv = mPrefBranch->GetBoolPref(sXPCDefaultGrantAllName, &temp);
-    if (NS_SUCCEEDED(rv))
-        mXPCDefaultGrantAll = temp;
+    mXPCDefaultGrantAll =
+        Preferences::GetBoolPref(sXPCDefaultGrantAllName, mXPCDefaultGrantAll);
 #endif
 }
 
 nsresult
 nsScriptSecurityManager::InitPrefs()
 {
     nsresult rv;
-    nsCOMPtr<nsIPrefService> prefService(do_GetService(NS_PREFSERVICE_CONTRACTID, &rv));
-    NS_ENSURE_SUCCESS(rv, rv);
-    rv = prefService->GetBranch(nsnull, getter_AddRefs(mPrefBranch));
-    NS_ENSURE_SUCCESS(rv, rv);
-    nsCOMPtr<nsIPrefBranch2> prefBranchInternal(do_QueryInterface(mPrefBranch, &rv));
-    NS_ENSURE_SUCCESS(rv, rv);
+    nsIPrefBranch* branch = Preferences::GetRootBranch();
+    NS_ENSURE_TRUE(branch, NS_ERROR_FAILURE);
+
+    mPrefInitialized = PR_TRUE;
 
     // Set the initial value of the "javascript.enabled" prefs
     ScriptSecurityPrefChanged();
+
     // set observer callbacks in case the value of the prefs change
-    prefBranchInternal->AddObserver(sJSEnabledPrefName, this, PR_FALSE);
-    prefBranchInternal->AddObserver(sFileOriginPolicyPrefName, this, PR_FALSE);
-#ifdef XPC_IDISPATCH_SUPPORT
-    prefBranchInternal->AddObserver(sXPCDefaultGrantAllName, this, PR_FALSE);
-#endif
+    Preferences::AddStrongObservers(this, kObservedPrefs);
+
     PRUint32 prefCount;
     char** prefNames;
-
-    // Set a callback for policy pref changes
-    prefBranchInternal->AddObserver(sPolicyPrefix, this, PR_FALSE);
-
     //-- Initialize the principals database from prefs
-    rv = mPrefBranch->GetChildList(sPrincipalPrefix, &prefCount, &prefNames);
+    rv = branch->GetChildList(sPrincipalPrefix, &prefCount, &prefNames);
     if (NS_SUCCEEDED(rv) && prefCount > 0)
     {
         rv = InitPrincipals(prefCount, (const char**)prefNames);
         NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(prefCount, prefNames);
         NS_ENSURE_SUCCESS(rv, rv);
     }
-    //-- Set a callback for principal changes
-    prefBranchInternal->AddObserver(sPrincipalPrefix, this, PR_FALSE);
 
     return NS_OK;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 // The following code prints the contents of the policy DB to the console.
 #ifdef DEBUG_CAPS_HACKER
 
--- a/chrome/src/nsChromeProtocolHandler.cpp
+++ b/chrome/src/nsChromeProtocolHandler.cpp
@@ -47,17 +47,16 @@
 #include "nsChromeRegistry.h"
 #include "nsCOMPtr.h"
 #include "nsContentCID.h"
 #include "nsCRT.h"
 #include "nsThreadUtils.h"
 #include "nsIChannel.h"
 #include "nsIChromeRegistry.h"
 #include "nsIComponentManager.h"
-#include "nsIFastLoadService.h"
 #include "nsIFile.h"
 #include "nsIFileURL.h"
 #include "nsIFileChannel.h"
 #include "nsIIOService.h"
 #include "nsIJARChannel.h"
 #include "nsIJARURI.h"
 #include "nsILoadGroup.h"
 #include "nsIObjectOutputStream.h"
@@ -240,54 +239,20 @@ nsChromeProtocolHandler::NewChannel(nsIU
         nsCOMPtr<nsIPrincipal> principal;
         rv = securityManager->GetSystemPrincipal(getter_AddRefs(principal));
         if (NS_FAILED(rv)) return rv;
 
         nsCOMPtr<nsISupports> owner = do_QueryInterface(principal);
         result->SetOwner(owner);
     }
 
-#ifdef MOZ_XUL
-    // Track FastLoad file dependencies.
-    //
-    // This is harder than it ought to be!  While an nsResChannel "is-a"
-    // nsIFileChannel, an nsJARChannel is not.  Once you unravel the jar:
-    // URI, you may have a resource: URL -- but without a channel for it,
-    // you can't get the URI that it yields through substitution!
-    //
-    // XXXbe fix nsResChannel.cpp to move the substitution code into a new
-    //       nsResURL class?
-    nsCOMPtr<nsIFastLoadService> fastLoadServ(do_GetFastLoadService());
-    if (fastLoadServ) {
-        nsCOMPtr<nsIObjectOutputStream> objectOutput;
-        fastLoadServ->GetOutputStream(getter_AddRefs(objectOutput));
-        if (objectOutput) {
-            nsCOMPtr<nsIFile> file;
-
-            nsCOMPtr<nsIURI> uri;
-            result->GetURI(getter_AddRefs(uri));
-            uri = NS_GetInnermostURI(uri);
-
-            // Here we have a URL of the form resource:/chrome/A.jar
-            // or file:/some/path/to/A.jar.
-            nsCOMPtr<nsIFileURL> fileURL(do_QueryInterface(uri));
-            if (fileURL)
-                fileURL->GetFile(getter_AddRefs(file));
-
-            if (file) {
-                rv = fastLoadServ->AddDependency(file);
-                if (NS_FAILED(rv)) {
-                   nsCOMPtr<nsIXULPrototypeCache> cache
-                       (do_GetService(kXULPrototypeCacheCID));
-                   if (cache)
-                       cache->AbortFastLoads();
-                }
-            }
-        }
-    }
-#endif
+    // XXX Removed dependency-tracking code from here, because we're not
+    // tracking them anyways (with fastload we checked only in DEBUG
+    // and with startupcache not at all), but this is where we would start
+    // if we need to re-add.
+    // See bug 531886, bug 533038.
 
     *aResult = result;
     NS_ADDREF(*aResult);
     return NS_OK;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
--- a/config/autoconf.mk.in
+++ b/config/autoconf.mk.in
@@ -146,17 +146,16 @@ MOZ_FEEDS = @MOZ_FEEDS@
 MOZ_TOOLKIT_SEARCH = @MOZ_TOOLKIT_SEARCH@
 MOZ_PLACES = @MOZ_PLACES@
 MOZ_STORAGE = @MOZ_STORAGE@
 MOZ_SAFE_BROWSING = @MOZ_SAFE_BROWSING@
 MOZ_URL_CLASSIFIER = @MOZ_URL_CLASSIFIER@
 MOZ_ZIPWRITER = @MOZ_ZIPWRITER@
 MOZ_MORK = @MOZ_MORK@
 MOZ_MORKREADER = @MOZ_MORKREADER@
-MOZ_NO_FAST_LOAD = @MOZ_NO_FAST_LOAD@
 MOZ_OGG = @MOZ_OGG@
 MOZ_RAW = @MOZ_RAW@
 MOZ_SYDNEYAUDIO = @MOZ_SYDNEYAUDIO@
 MOZ_WAVE = @MOZ_WAVE@
 MOZ_MEDIA = @MOZ_MEDIA@
 MOZ_VORBIS = @MOZ_VORBIS@
 MOZ_TREMOR = @MOZ_TREMOR@
 MOZ_WEBM = @MOZ_WEBM@
@@ -310,16 +309,17 @@ OS_COMPILE_CXXFLAGS = $(OS_CPPFLAGS) @CO
 OS_INCLUDES	= $(NSPR_CFLAGS) $(NSS_CFLAGS) $(JPEG_CFLAGS) $(PNG_CFLAGS) $(ZLIB_CFLAGS)
 OS_LIBS		= @LIBS@
 ACDEFINES	= @MOZ_DEFINES@
 
 WARNINGS_AS_ERRORS = @WARNINGS_AS_ERRORS@
 
 MOZ_OPTIMIZE	= @MOZ_OPTIMIZE@
 MOZ_OPTIMIZE_FLAGS = @MOZ_OPTIMIZE_FLAGS@
+MOZ_PGO_OPTIMIZE_FLAGS = @MOZ_PGO_OPTIMIZE_FLAGS@
 MOZ_OPTIMIZE_LDFLAGS = @MOZ_OPTIMIZE_LDFLAGS@
 MOZ_OPTIMIZE_SIZE_TWEAK = @MOZ_OPTIMIZE_SIZE_TWEAK@
 
 MOZ_RTTI_FLAGS_ON = @_MOZ_RTTI_FLAGS_ON@
 MOZ_EXCEPTIONS_FLAGS_ON = @_MOZ_EXCEPTIONS_FLAGS_ON@
 
 PROFILE_GEN_CFLAGS = @PROFILE_GEN_CFLAGS@
 PROFILE_GEN_LDFLAGS = @PROFILE_GEN_LDFLAGS@
@@ -661,18 +661,16 @@ MOZ_MAEMO_LIBLOCATION 	= @MOZ_MAEMO_LIBL
 
 MOZ_ENABLE_LIBCONIC = @MOZ_ENABLE_LIBCONIC@
 LIBCONIC_CFLAGS     = @LIBCONIC_CFLAGS@
 LIBCONIC_LIBS       = @LIBCONIC_LIBS@
 
 MACOS_SDK_DIR	= @MACOS_SDK_DIR@
 NEXT_ROOT	= @NEXT_ROOT@
 GCC_VERSION	= @GCC_VERSION@
-XCODEBUILD_VERSION= @XCODEBUILD_VERSION@
-HAS_XCODE_2_1	= @HAS_XCODE_2_1@
 UNIVERSAL_BINARY= @UNIVERSAL_BINARY@
 HAVE_DTRACE= @HAVE_DTRACE@
 
 VISIBILITY_FLAGS = @VISIBILITY_FLAGS@
 WRAP_SYSTEM_INCLUDES = @WRAP_SYSTEM_INCLUDES@
 
 HAVE_ARM_SIMD = @HAVE_ARM_SIMD@
 HAVE_ARM_NEON = @HAVE_ARM_NEON@
--- a/config/config.mk
+++ b/config/config.mk
@@ -417,18 +417,23 @@ LDFLAGS		= $(OS_LDFLAGS) $(MOZ_FIX_LINK_
 # by setting MODULE_OPTIMIZE_FLAGS if the developer has not given
 # arguments to --enable-optimize
 ifdef MOZ_OPTIMIZE
 ifeq (1,$(MOZ_OPTIMIZE))
 ifdef MODULE_OPTIMIZE_FLAGS
 CFLAGS		+= $(MODULE_OPTIMIZE_FLAGS)
 CXXFLAGS	+= $(MODULE_OPTIMIZE_FLAGS)
 else
+ifneq (,$(if $(MOZ_PROFILE_GENERATE)$(MOZ_PROFILE_USE),$(MOZ_PGO_OPTIMIZE_FLAGS)))
+CFLAGS		+= $(MOZ_PGO_OPTIMIZE_FLAGS)
+CXXFLAGS	+= $(MOZ_PGO_OPTIMIZE_FLAGS)
+else
 CFLAGS		+= $(MOZ_OPTIMIZE_FLAGS)
 CXXFLAGS	+= $(MOZ_OPTIMIZE_FLAGS)
+endif # neq (,$(MOZ_PROFILE_GENERATE)$(MOZ_PROFILE_USE))
 endif # MODULE_OPTIMIZE_FLAGS
 else
 CFLAGS		+= $(MOZ_OPTIMIZE_FLAGS)
 CXXFLAGS	+= $(MOZ_OPTIMIZE_FLAGS)
 endif # MOZ_OPTIMIZE == 1
 LDFLAGS		+= $(MOZ_OPTIMIZE_LDFLAGS)
 endif # MOZ_OPTIMIZE
 
@@ -581,23 +586,16 @@ export MACOSX_DEPLOYMENT_TARGET
 PBBUILD_SETTINGS += MACOSX_DEPLOYMENT_TARGET="$(MACOSX_DEPLOYMENT_TARGET)"
 endif # MACOSX_DEPLOYMENT_TARGET
 ifdef MOZ_OPTIMIZE
 ifeq (2,$(MOZ_OPTIMIZE))
 # Only override project defaults if the config specified explicit settings
 PBBUILD_SETTINGS += GCC_MODEL_TUNING= OPTIMIZATION_CFLAGS="$(MOZ_OPTIMIZE_FLAGS)"
 endif # MOZ_OPTIMIZE=2
 endif # MOZ_OPTIMIZE
-ifeq (1,$(HAS_XCODE_2_1))
-# Xcode 2.1 puts its build products in a directory corresponding to the
-# selected build style/configuration.
-XCODE_PRODUCT_DIR = build/$(BUILDSTYLE)
-else
-XCODE_PRODUCT_DIR = build
-endif # HAS_XCODE_2_1=1
 endif # OS_ARCH=Darwin
 
 
 ifdef MOZ_NATIVE_MAKEDEPEND
 MKDEPEND_DIR =
 MKDEPEND = $(MOZ_NATIVE_MAKEDEPEND)
 else
 MKDEPEND_DIR = $(CONFIG_TOOLS)/mkdepend
deleted file mode 100644
--- a/config/installcfunc.pl
+++ /dev/null
@@ -1,191 +0,0 @@
-#!perl -w
-# 
-# ***** BEGIN LICENSE BLOCK *****
-# Version: MPL 1.1/GPL 2.0/LGPL 2.1
-#
-# The contents of this file are subject to the Mozilla Public License Version
-# 1.1 (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-# http://www.mozilla.org/MPL/
-#
-# Software distributed under the License is distributed on an "AS IS" basis,
-# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
-# for the specific language governing rights and limitations under the
-# License.
-#
-# The Original Code is Mozilla Communicator client code, released
-# March 31, 1998.
-#
-# The Initial Developer of the Original Code is
-# Netscape Communications Corporation.
-# Portions created by the Initial Developer are Copyright (C) 1998-1999
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-#   Sean Su <ssu@netscape.com>
-#
-# Alternatively, the contents of this file may be used under the terms of
-# either of the GNU General Public License Version 2 or later (the "GPL"),
-# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
-# in which case the provisions of the GPL or the LGPL are applicable instead
-# of those above. If you wish to allow use of your version of this file only
-# under the terms of either the GPL or the LGPL, and not to allow others to
-# use your version of this file under the terms of the MPL, indicate your
-# decision by deleting the provisions above and replace them with the notice
-# and other provisions required by the GPL or the LGPL. If you do not delete
-# the provisions above, a recipient may use your version of this file under
-# the terms of any one of the MPL, the GPL or the LGPL.
-#
-# ***** END LICENSE BLOCK *****
-
-use Cwd;
-return(1);
-
-sub InstallChrome()
-{
-  # inOsType     - type of OS being run under
-  # inType       - type of reg file to create (jar or resource)
-  # inTargetPath - path to where the bin\chrome dir
-  ($inOsType, $inType, $inTargetPath) = @_;
-  my($mOutFilenameTmp) = "installed-chrome_tmp.txt";
-  my($mFinalFilename)  = "installed-chrome.txt";
-
-  if($inOsType =~ /win32/i)
-  {
-    $gPathDelimiter="\\";
-  }
-  elsif($inOsType =~ /mac/i)
-  {
-    $gPathDelimiter=":";
-  }
-  elsif($inOsType =~ /unix/i)
-  {
-    $gPathDelimiter="/";
-  }
-
-  if($inOsType =~ /win32/i)
-  {
-    # Convert all '/' to '\\' or else win32 will have problems
-    $inTargetPath =~ s/\//\\/g;
-  }
-
-  # Make sure $inTargetPath exists
-  if(!(-e "$inTargetPath"))
-  {
-    return(1);
-  }
-
-  open(fpOutFileTmp, ">$inTargetPath$gPathDelimiter$mOutFilenameTmp") || die "\nCould not open $inTargetPath$gPathDelimiter$mOutFilenameTmp: $!\n";
-
-  CreateChromeTextFile($inType, $inTargetPath, "locales",  "loc");
-  CreateChromeTextFile($inType, $inTargetPath, "packages", "pkg");
-  CreateChromeTextFile($inType, $inTargetPath, "skins",    "skn");
-
-  if(-e "$inTargetPath$gPathDelimiter$mFinalFilename")
-  {
-    open(fpInFile, "$inTargetPath$gPathDelimiter$mFinalFilename") || die "\nCould not open $inTargetPath$gPathDelimiter$mFinalFilename: $!\n";
-    while($line = <fpInFile>)
-    {
-      print fpOutFileTmp "$line";
-    }
-
-    close(fpInFile);
-    unlink "$inTargetPath$gPathDelimiter$mFinalFilename";
-  }
-  close(fpOutFileTmp);
-
-  if(!rename("$inTargetPath$gPathDelimiter$mOutFilenameTmp", "$inTargetPath$gPathDelimiter$mFinalFilename"))
-  {
-    die "\n Error $!: rename (\"$inTargetPath$gPathDelimiter$mOutFilenameTmp\", \"$inTargetPath$gPathDelimiter$mFinalFilename\")\n";
-  }
-  return(0);
-}
-
-sub CreateChromeTextFile()
-{
-  my($inType, $inTargetPath, $inChromeDir, $inExt) = @_;
-
-  @dlChromeDir = <$inTargetPath\\$inChromeDir\\*>;
-  foreach $dir (@dlChromeDir)
-  {
-    if($inOsType =~ /win32/i)
-    {
-      # Convert all '/' to '\\' or else win32 will have problems
-      $dir =~ s/\//\\/g;
-    }
-
-    # Get the leaf dir name from full path
-    if($inOsType =~ /win32/i)
-    {
-      @dirItem = split(/\\/, $dir);
-    }
-    elsif($inOsType =~ /mac/i)
-    {
-      @dirItem = split(/:/, $dir);
-    }
-    elsif($inOsType =~ /unix/i)
-    {
-      @dirItem = split(/\//, $dir);
-    }
-    $dirName = $dirItem[$#dirItem];
-
-    # Make sure the path is valid
-    if(-d "$dir")
-    {
-      if($inType =~ /jar/i)
-      {
-        if(CheckDir("content", "$dir"))
-        {
-          print fpOutFileTmp "content,install,url,jar:resource:/chrome/$dirName.$inExt!/\n";
-        }
-        if(CheckDir("locale", "$dir"))
-        {
-          print fpOutFileTmp "locale,install,url,jar:resource:/chrome/$dirName.$inExt!/\n";
-        }
-        if(CheckDir("skin", "$dir"))
-        {
-          print fpOutFileTmp "skin,install,url,jar:resource:/chrome/$dirName.$inExt!/\n";
-        }
-      }
-      else
-      {
-        if(CheckDir("content", "$dir"))
-        {
-          print fpOutFileTmp "content,install,url,resource:/chrome/$inChromeDir/$dirName/\n";
-        }
-        if(CheckDir("locale", "$dir"))
-        {
-          print fpOutFileTmp "locale,install,url,resource:/chrome/$inChromeDir/$dirName/\n";
-        }
-        if(CheckDir("skin", "$dir"))
-        {
-          print fpOutFileTmp "skin,install,url,resource:/chrome/$inChromeDir/$dirName/\n";
-        }
-      }
-    }
-  }
-
-  return(0);
-}
-
-sub CheckDir()
-{
-  my($dirType, $inPath) = @_;
-
-  @dlDirType = <$inPath$gPathDelimiter*>;
-  foreach $dir (@dlDirType)
-  {
-    if($inOsType =~ /win32/i)
-    {
-      # Convert all '/' to '\\' or else win32 will have problems
-      $dir =~ s/\//\\/g;
-    }
-
-    if(-d "$dir$gPathDelimiter$dirType")
-    {
-      return(1);
-    }
-  }
-  return(0);
-}
-
deleted file mode 100644
--- a/config/installchrome.pl
+++ /dev/null
@@ -1,60 +0,0 @@
-#!perl -w
-# 
-# ***** BEGIN LICENSE BLOCK *****
-# Version: MPL 1.1/GPL 2.0/LGPL 2.1
-#
-# The contents of this file are subject to the Mozilla Public License Version
-# 1.1 (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-# http://www.mozilla.org/MPL/
-#
-# Software distributed under the License is distributed on an "AS IS" basis,
-# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
-# for the specific language governing rights and limitations under the
-# License.
-#
-# The Original Code is Mozilla Communicator client code, released
-# March 31, 1998.
-#
-# The Initial Developer of the Original Code is
-# Netscape Communications Corporation.
-# Portions created by the Initial Developer are Copyright (C) 1998-1999
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-#   Sean Su <ssu@netscape.com>
-#
-# Alternatively, the contents of this file may be used under the terms of
-# either of the GNU General Public License Version 2 or later (the "GPL"),
-# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
-# in which case the provisions of the GPL or the LGPL are applicable instead
-# of those above. If you wish to allow use of your version of this file only
-# under the terms of either the GPL or the LGPL, and not to allow others to
-# use your version of this file under the terms of the MPL, indicate your
-# decision by deleting the provisions above and replace them with the notice
-# and other provisions required by the GPL or the LGPL. If you do not delete
-# the provisions above, a recipient may use your version of this file under
-# the terms of any one of the MPL, the GPL or the LGPL.
-#
-# ***** END LICENSE BLOCK *****
-
-# Make sure there are at least two arguments
-if($#ARGV < 1)
-{
-  die "usage: $0 <os> <type> <target path>
-
-       os         : mac, unix, win32
-       type       : jar or resource
-       target path: path to where the chrome dir is at
-
-              ie: $0 win32 resource $ENV{MOZ_SRC}\\mozilla\\dist\\win32_d.obj\\bin\\chrome
-       \n";
-}
-
-require "$ENV{MOZ_SRC}/mozilla/config/installcfunc.pl";
-
-if(&InstallChrome($ARGV[0], $ARGV[1], $ARGV[2]) != 0)
-{
-  die "\n Error: InstallChrome($ARGV[0], $ARGV[1], $ARGV[2]): $!\n";
-}
-
--- a/config/rules.mk
+++ b/config/rules.mk
@@ -898,16 +898,27 @@ ifdef PROGRAM
 endif
 ifdef SHARED_LIBRARY
 	$(PYTHON) $(topsrcdir)/build/win32/pgomerge.py \
 	  $(SHARED_LIBRARY_NAME) $(DIST)/$(MOZ_APP_NAME)
 endif
 endif # SHARED_LIBRARY || PROGRAM
 endif # WINNT_
 endif # MOZ_PROFILE_GENERATE || MOZ_PROFILE_USE
+ifdef MOZ_PROFILE_GENERATE
+# Clean up profiling data during PROFILE_GENERATE phase
+export::
+ifeq ($(OS_ARCH)_$(GNU_CC), WINNT_)
+	-$(RM) *.pgd
+else
+ifdef GNU_CC
+	-$(RM) *.gcda
+endif
+endif
+endif
 endif # NO_PROFILE_GUIDED_OPTIMIZE
 
 ##############################################
 
 stdc++compat.$(OBJ_SUFFIX): CXXFLAGS+=-DMOZ_LIBSTDCXX_VERSION=$(MOZ_LIBSTDCXX_TARGET_VERSION)
 host_stdc++compat.$(OBJ_SUFFIX): CXXFLAGS+=-DMOZ_LIBSTDCXX_VERSION=$(MOZ_LIBSTDCXX_HOST_VERSION)
 
 checkout:
--- a/configure.in
+++ b/configure.in
@@ -122,17 +122,17 @@ PYTHON_VERSION=2.5
 CAIRO_VERSION=1.10
 PANGO_VERSION=1.14.0
 GTK2_VERSION=2.10.0
 WINDRES_VERSION=2.14.90
 W32API_VERSION=3.8
 GNOMEVFS_VERSION=2.0
 GNOMEUI_VERSION=2.2.0
 GCONF_VERSION=1.2.1
-GIO_VERSION=2.0
+GIO_VERSION=2.18
 STARTUP_NOTIFICATION_VERSION=0.8
 DBUS_VERSION=0.60
 SQLITE_VERSION=3.7.5
 LIBNOTIFY_VERSION=0.4
 
 MSMANIFEST_TOOL=
 
 dnl Set various checks
@@ -1009,36 +1009,23 @@ from building Mozilla. Upgrade to Xcode 
         fi
     fi
 
     dnl xcodebuild needs GCC_VERSION defined in the environment, since it
     dnl doesn't respect the CC/CXX setting.  With GCC_VERSION set, it will use
     dnl /usr/bin/g(cc|++)-$GCC_VERSION.
     MOZ_PATH_PROGS(PBBUILD, pbbuild xcodebuild pbxbuild)
 
-    case "$PBBUILD" in
-      *xcodebuild*)
-        changequote(,)
-        XCODEBUILD_VERSION=`$PBBUILD -version 2>/dev/null | xargs | sed -e 's/.*DevToolsCore-\([0-9]*\).*/\1/'`
-        changequote([,])
-        if test -n "$XCODEBUILD_VERSION" && test "$XCODEBUILD_VERSION" -ge 620 ; then
-          HAS_XCODE_2_1=1;
-        fi
-      ;;
-    esac
-
     dnl sdp was formerly in /Developer/Tools.  As of Mac OS X 10.4 (Darwin 8),
     dnl it has moved into /usr/bin.
     MOZ_PATH_PROG(SDP, sdp, :, [$PATH:/usr/bin:/Developer/Tools])
     ;;
 esac
 
 AC_SUBST(GCC_VERSION)
-AC_SUBST(XCODEBUILD_VERSION)
-AC_SUBST(HAS_XCODE_2_1)
 
 dnl The universal machinery sets UNIVERSAL_BINARY to inform packager.mk
 dnl that a universal binary is being produced.
 AC_SUBST(UNIVERSAL_BINARY)
 
 dnl ========================================================
 dnl Check for MacOS deployment target version
 dnl ========================================================
@@ -2219,20 +2206,22 @@ ia64*-hpux*)
         GCC_VERSION=`$CC -v 2>&1 | awk '/^gcc version/ { print $3 }'`
         case $GCC_VERSION in
         4.1.*|4.2.*|4.5.*)
             # -Os is broken on gcc 4.1.x 4.2.x, 4.5.x we need to tweak it to get good results.
             MOZ_OPTIMIZE_SIZE_TWEAK="-finline-limit=50"
         esac
         # If we're building with --enable-profiling, we need a frame pointer.
         if test -z "$MOZ_PROFILING"; then
-            MOZ_OPTIMIZE_FLAGS="-O3 -fomit-frame-pointer"
+            MOZ_FRAMEPTR_FLAGS="-fomit-frame-pointer"
         else
-            MOZ_OPTIMIZE_FLAGS="-O3 -fno-omit-frame-pointer"
+            MOZ_FRAMEPTR_FLAGS="-fno-omit-frame-pointer"
         fi
+        MOZ_PGO_OPTIMIZE_FLAGS="-O3 $MOZ_FRAMEPTR_FLAGS"
+        MOZ_OPTIMIZE_FLAGS="-Os -freorder-blocks $MOZ_OPTIMIZE_SIZE_TWEAK $MOZ_FRAMEPTR_FLAGS"
         MOZ_DEBUG_FLAGS="-g"
     fi
 
     TARGET_NSPR_MDCPUCFG='\"md/_linux.cfg\"'
 
     MOZ_MEMORY=1
 
     case "${target_cpu}" in
@@ -4761,17 +4750,16 @@ MOZ_OFFICIAL_BRANDING=
 MOZ_FEEDS=1
 MOZ_INSTALLER=1
 MOZ_JSDEBUGGER=1
 MOZ_CSS_ANIMATIONS=1
 MOZ_MORK=
 MOZ_MORKREADER=1
 MOZ_AUTH_EXTENSION=1
 MOZ_NO_ACTIVEX_SUPPORT=1
-MOZ_NO_FAST_LOAD=
 MOZ_OGG=1
 MOZ_RAW=
 MOZ_SYDNEYAUDIO=
 MOZ_VORBIS=
 MOZ_TREMOR=
 MOZ_WAVE=1
 MOZ_MEDIA=
 MOZ_WEBM=1
@@ -5450,16 +5438,18 @@ then
     dnl ========================================================
     MOZ_ARG_ENABLE_BOOL(gio,
     [  --enable-gio            Enable GIO support (default: disabled)],
         MOZ_ENABLE_GIO=force,
         MOZ_ENABLE_GIO=)
 
     if test "$MOZ_ENABLE_GIO" -a "$MOZ_ENABLE_GTK2"
     then
+        PKG_CHECK_MODULES(_GTKCHECK, gtk+-2.0 >= 2.14, , 
+                          [AC_MSG_ERROR([* * * Could not find gtk+-2.0 > 2.14. Required for build with gio.])])
         PKG_CHECK_MODULES(MOZ_GIO, gio-2.0 >= $GIO_VERSION,[
             MOZ_GIO_LIBS=`echo $MOZ_GIO_LIBS | sed 's/-llinc\>//'`
             MOZ_ENABLE_GIO=1
             AC_DEFINE(MOZ_ENABLE_GIO)
         ],[
             if test "$MOZ_ENABLE_GIO" = "force"
             then
                 AC_MSG_ERROR([* * * Could not find gio-2.0 >= $GIO_VERSION])
@@ -5717,31 +5707,16 @@ MOZ_ARG_DISABLE_BOOL(printing,
     NS_PRINTING=1)
 
 if test "$NS_PRINTING"; then
     AC_DEFINE(NS_PRINTING)
     AC_DEFINE(NS_PRINT_PREVIEW)
 fi
 
 dnl ========================================================
-dnl = Disable Fast Load
-dnl ========================================================
-MOZ_ARG_DISABLE_BOOL(xpcom-fastload,
-[  --disable-xpcom-fastload
-                          Disable XPCOM fastload support],
-    MOZ_NO_FAST_LOAD=1,
-    MOZ_NO_FAST_LOAD=)
-
-AC_SUBST(MOZ_NO_FAST_LOAD)
-
-if test -n "$MOZ_NO_FAST_LOAD"; then
-    AC_DEFINE(MOZ_NO_FAST_LOAD)
-fi
-
-dnl ========================================================
 dnl = Enable Raw Codecs
 dnl ========================================================
 MOZ_ARG_ENABLE_BOOL(raw,
 [  --enable-raw           Enable support for RAW media],
     MOZ_RAW=1,
     MOZ_RAW=)
 
 if test -n "$MOZ_RAW"; then
@@ -7270,16 +7245,17 @@ if test -n "$MOZ_OPTIMIZE"; then
     CFLAGS=$_SAVE_CFLAGS
 fi
 fi # COMPILE_ENVIRONMENT
 
 AC_SUBST(MOZ_OPTIMIZE)
 AC_SUBST(MOZ_OPTIMIZE_FLAGS)
 AC_SUBST(MOZ_OPTIMIZE_LDFLAGS)
 AC_SUBST(MOZ_OPTIMIZE_SIZE_TWEAK)
+AC_SUBST(MOZ_PGO_OPTIMIZE_FLAGS)
 
 dnl ========================================================
 dnl = Enable generation of debug symbols
 dnl ========================================================
 MOZ_ARG_ENABLE_STRING(debug-symbols,
 [  --enable-debug-symbols[=DBG]
                           Enable debugging symbols (using compiler flags DBG)],
 [ if test "$enableval" != "no"; then
new file mode 100644
--- /dev/null
+++ b/content/base/crashtests/605672-1.svg
@@ -0,0 +1,17 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+
+<script>
+function boom()
+{
+  var fr = document.createElementNS("http://www.w3.org/1999/xhtml", "iframe");
+  fr.src = "data:text/html,X";
+  document.documentElement.appendChild(fr);
+  var docType = fr.contentDocument.implementation.createDocumentType(undefined, "", "");
+  document.removeChild(document.documentElement);
+  document.appendChild(docType);
+}
+
+window.addEventListener("load", boom, false);
+</script>
+
+</svg>
--- a/content/base/crashtests/crashtests.list
+++ b/content/base/crashtests/crashtests.list
@@ -75,16 +75,17 @@ load 561981-2.html
 load 564079-1.html 
 load 564114.html
 load 565125-1.html
 load 582601.html
 load 575462.svg
 load 590395-1.html
 load 595606-1.html
 load 595606-2.html
+load 605672-1.svg
 load 606729-1.html
 load 593302-1.html
 load 593302-2.html
 load 610571-1.html
 load 604262-1.html
 load 628599-1.html
 load 637214-1.svg
 load 637214-2.svg
--- a/content/base/public/Makefile.in
+++ b/content/base/public/Makefile.in
@@ -108,17 +108,16 @@ XPIDLSRCS	= \
 		nsIDOMSerializer.idl \
 		nsISelection2.idl \
 		nsISelection3.idl \
 		nsISelectionController.idl  \
 		nsISelectionDisplay.idl  \
 		nsISelectionListener.idl  \
 		nsISelectionPrivate.idl  \
 		nsIScriptLoaderObserver.idl  \
-		nsISyncLoadDOMService.idl  \
 		nsIDroppedLinkHandler.idl \
 		nsIScriptEventHandler.idl \
 		nsIScriptEventManager.idl \
 		nsIImageLoadingContent.idl \
 		nsIObjectLoadingContent.idl \
 		nsIFrameLoader.idl \
 		nsIXMLHttpRequest.idl \
 		nsIContentSecurityPolicy.idl \
--- a/content/base/public/nsContentCID.h
+++ b/content/base/public/nsContentCID.h
@@ -223,23 +223,16 @@
 
 // {d899a152-9412-46b2-b651-2e71c5c2f05f}
 #define NS_VIDEODOCUMENT_CID   \
 { 0xd899a152, 0x9412, 0x46b2,  \
   { 0xb6, 0x51, 0x2e, 0x71, 0xc5, 0xc2, 0xf0, 0x5f } }
 
 #endif
 
-#define NS_SYNCLOADDOMSERVICE_CID                   \
- { /* 0e4e7d00-f71a-439f-9178-1a71ff11b55f */       \
-  0x0e4e7d00, 0xf71a, 0x439f,                       \
- {0x91, 0x78, 0x1a, 0x71, 0xff, 0x11, 0xb5, 0x5f} }
-#define NS_SYNCLOADDOMSERVICE_CONTRACTID            \
-"@mozilla.org/content/syncload-dom-service;1"
-
 #define NS_EVENTLISTENERSERVICE_CID                 \
  { /* baa34652-f1f1-4185-b224-244ee82a413a */       \
    0xbaa34652, 0xf1f1, 0x4185,                      \
   {0xb2, 0x24, 0x24, 0x4e, 0xe8, 0x2a, 0x41, 0x3a } }
 #define NS_EVENTLISTENERSERVICE_CONTRACTID \
   "@mozilla.org/eventlistenerservice;1"
 
 #define NS_GLOBALMESSAGEMANAGER_CID                   \
--- a/content/base/public/nsContentUtils.h
+++ b/content/base/public/nsContentUtils.h
@@ -64,17 +64,16 @@ static fp_except_t oldmask = fpsetmask(~
 
 #include "nsAString.h"
 #include "nsIStatefulFrame.h"
 #include "nsINodeInfo.h"
 #include "nsNodeInfoManager.h"
 #include "nsContentList.h"
 #include "nsDOMClassInfoID.h"
 #include "nsIXPCScriptable.h"
-#include "nsIDOM3Node.h"
 #include "nsDataHashtable.h"
 #include "nsIScriptRuntime.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsIDOMEvent.h"
 #include "nsTArray.h"
 #include "nsTextFragment.h"
 #include "nsReadableUtils.h"
 #include "mozilla/AutoRestore.h"
@@ -298,20 +297,20 @@ public:
 
   /**
    * Returns true if aNode1 is before aNode2 in the same connected
    * tree.
    */
   static PRBool PositionIsBefore(nsINode* aNode1,
                                  nsINode* aNode2)
   {
-    return (aNode2->CompareDocumentPosition(aNode1) &
-      (nsIDOM3Node::DOCUMENT_POSITION_PRECEDING |
-       nsIDOM3Node::DOCUMENT_POSITION_DISCONNECTED)) ==
-      nsIDOM3Node::DOCUMENT_POSITION_PRECEDING;
+    return (aNode2->CompareDocPosition(aNode1) &
+      (nsIDOMNode::DOCUMENT_POSITION_PRECEDING |
+       nsIDOMNode::DOCUMENT_POSITION_DISCONNECTED)) ==
+      nsIDOMNode::DOCUMENT_POSITION_PRECEDING;
   }
 
   /**
    *  Utility routine to compare two "points", where a point is a
    *  node/offset pair
    *  Returns -1 if point1 < point2, 1, if point1 > point2,
    *  0 if error or if point1 == point2.
    *  NOTE! If the two nodes aren't in the same connected subtree,
@@ -337,17 +336,16 @@ public:
   /**
    * Reverses the document position flags passed in.
    *
    * @param   aDocumentPosition   The document position flags to be reversed.
    *
    * @return  The reversed document position flags.
    *
    * @see nsIDOMNode
-   * @see nsIDOM3Node
    */
   static PRUint16 ReverseDocumentPosition(PRUint16 aDocumentPosition);
 
   static PRUint32 CopyNewlineNormalizedUnicodeTo(const nsAString& aSource,
                                                  PRUint32 aSrcOffset,
                                                  PRUnichar* aDest,
                                                  PRUint32 aLength,
                                                  PRBool& aLastCharCR);
@@ -543,16 +541,17 @@ public:
 
   static nsresult SplitQName(const nsIContent* aNamespaceResolver,
                              const nsAFlatString& aQName,
                              PRInt32 *aNamespace, nsIAtom **aLocalName);
 
   static nsresult GetNodeInfoFromQName(const nsAString& aNamespaceURI,
                                        const nsAString& aQualifiedName,
                                        nsNodeInfoManager* aNodeInfoManager,
+                                       PRUint16 aNodeType,
                                        nsINodeInfo** aNodeInfo);
 
   static void SplitExpatName(const PRUnichar *aExpatName, nsIAtom **aPrefix,
                              nsIAtom **aTagName, PRInt32 *aNameSpaceID);
 
   // Get a permission-manager setting for the given uri and type.
   // If the pref doesn't exist or if it isn't ALLOW_ACTION, PR_FALSE is
   // returned, otherwise PR_TRUE is returned.
@@ -686,17 +685,19 @@ public:
    * from aNodeInfo.
    */
   static nsresult NameChanged(nsINodeInfo *aNodeInfo, nsIAtom *aName,
                               nsINodeInfo** aResult)
   {
     nsNodeInfoManager *niMgr = aNodeInfo->NodeInfoManager();
 
     *aResult = niMgr->GetNodeInfo(aName, aNodeInfo->GetPrefixAtom(),
-                                  aNodeInfo->NamespaceID()).get();
+                                  aNodeInfo->NamespaceID(),
+                                  aNodeInfo->NodeType(),
+                                  aNodeInfo->GetExtraName()).get();
     return *aResult ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
   }
 
   /**
    * Returns the appropriate event argument names for the specified
    * namespace and event name.  Added because we need to switch between
    * SVG's "evt" and the rest of the world's "event", and because onerror
    * takes 3 args.
--- a/content/base/public/nsIContent.h
+++ b/content/base/public/nsIContent.h
@@ -923,22 +923,16 @@ public:
    */
   virtual nsresult SetSMILOverrideStyleRule(mozilla::css::StyleRule* aStyleRule,
                                             PRBool aNotify) = 0;
 #endif // MOZ_SMIL
 
   nsresult LookupNamespaceURI(const nsAString& aNamespacePrefix,
                               nsAString& aNamespaceURI) const;
 
-  nsIAtom* LookupPrefix(const nsAString& aNamespaceURI);
-
-  PRBool IsEqual(nsIContent *aOther);
-
-  virtual PRBool IsEqualNode(nsINode* aOther);
-
   /**
    * If this content has independent selection, e.g., if this is input field
    * or textarea, this return TRUE.  Otherwise, false.
    */
   PRBool HasIndependentSelection();
 
   /**
    * If the content is a part of HTML editor, this returns editing
--- a/content/base/public/nsINode.h
+++ b/content/base/public/nsINode.h
@@ -431,17 +431,32 @@ public:
    *
    * @return the current document
    */
   nsIDocument *GetCurrentDoc() const
   {
     return IsInDoc() ? GetOwnerDoc() : nsnull;
   }
 
-  NS_IMETHOD GetNodeType(PRUint16* aNodeType) = 0;
+  /**
+   * The values returned by this function are the ones defined for
+   * nsIDOMNode.nodeType
+   */
+  PRUint16 NodeType() const
+  {
+    return mNodeInfo->NodeType();
+  }
+  const nsString& NodeName() const
+  {
+    return mNodeInfo->NodeName();
+  }
+  const nsString& LocalName() const
+  {
+    return mNodeInfo->LocalName();
+  }
 
   nsINode*
   InsertBefore(nsINode *aNewChild, nsINode *aRefChild, nsresult *aReturn)
   {
     return ReplaceOrInsertBefore(PR_FALSE, aNewChild, aRefChild, aReturn);
   }
   nsINode*
   ReplaceChild(nsINode *aNewChild, nsINode *aOldChild, nsresult *aReturn)
@@ -964,23 +979,26 @@ public:
    * content. Generally, this is the document's base URI, but certain
    * content carries a local base for backward compatibility, and XML
    * supports setting a per-node base URI.
    *
    * @return the base URI
    */
   virtual already_AddRefed<nsIURI> GetBaseURI() const = 0;
 
-  void GetBaseURI(nsAString &aURI) const;
+  nsresult GetDOMBaseURI(nsAString &aURI) const;
 
-  virtual void GetTextContent(nsAString &aTextContent)
+  // Note! This function must never fail. It only return an nsresult so that
+  // we can use it to implement nsIDOMNode
+  NS_IMETHOD GetTextContent(nsAString &aTextContent)
   {
     SetDOMStringToNull(aTextContent);
+    return NS_OK;
   }
-  virtual nsresult SetTextContent(const nsAString& aTextContent)
+  NS_IMETHOD SetTextContent(const nsAString& aTextContent)
   {
     return NS_OK;
   }
 
   /**
    * Associate an object aData to aKey on this node. If aData is null any
    * previously registered object and UserDataHandler associated to aKey on
    * this node will be removed.
@@ -1010,58 +1028,61 @@ public:
     nsCOMPtr<nsIAtom> key = do_GetAtom(aKey);
     if (!key) {
       return nsnull;
     }
 
     return static_cast<nsIVariant*>(GetProperty(DOM_USER_DATA, key));
   }
 
-  nsresult GetFeature(const nsAString& aFeature,
-                      const nsAString& aVersion,
-                      nsISupports** aReturn);
+  nsresult GetUserData(const nsAString& aKey, nsIVariant** aResult)
+  {
+    NS_IF_ADDREF(*aResult = GetUserData(aKey));
+  
+    return NS_OK;
+  }
+
 
   /**
    * Compares the document position of a node to this node.
    *
    * @param aOtherNode The node whose position is being compared to this node
    *
    * @return  The document position flags of the nodes. aOtherNode is compared
    *          to this node, i.e. if aOtherNode is before this node then
    *          DOCUMENT_POSITION_PRECEDING will be set.
    *
    * @see nsIDOMNode
-   * @see nsIDOM3Node
    */
-  PRUint16 CompareDocumentPosition(nsINode* aOtherNode);
-  nsresult CompareDocumentPosition(nsINode* aOtherNode, PRUint16* aResult)
+  PRUint16 CompareDocPosition(nsINode* aOtherNode);
+  nsresult CompareDocPosition(nsINode* aOtherNode, PRUint16* aReturn)
   {
     NS_ENSURE_ARG(aOtherNode);
-
-    *aResult = CompareDocumentPosition(aOtherNode);
-
+    *aReturn = CompareDocPosition(aOtherNode);
     return NS_OK;
   }
+  nsresult CompareDocumentPosition(nsIDOMNode* aOther,
+                                   PRUint16* aReturn);
 
-  PRBool IsSameNode(nsINode *aOtherNode)
-  {
-    return aOtherNode == this;
-  }
+  nsresult IsSameNode(nsIDOMNode* aOther,
+                      PRBool* aReturn);
 
-  virtual PRBool IsEqualNode(nsINode *aOtherNode) = 0;
-
-  void LookupPrefix(const nsAString& aNamespaceURI, nsAString& aPrefix);
-  PRBool IsDefaultNamespace(const nsAString& aNamespaceURI)
+  nsresult LookupPrefix(const nsAString& aNamespaceURI, nsAString& aPrefix);
+  nsresult IsDefaultNamespace(const nsAString& aNamespaceURI, PRBool* aResult)
   {
     nsAutoString defaultNamespace;
     LookupNamespaceURI(EmptyString(), defaultNamespace);
-    return aNamespaceURI.Equals(defaultNamespace);
+    *aResult = aNamespaceURI.Equals(defaultNamespace);
+    return NS_OK;
   }
-  void LookupNamespaceURI(const nsAString& aNamespacePrefix,
-                          nsAString& aNamespaceURI);
+  nsresult LookupNamespaceURI(const nsAString& aNamespacePrefix,
+                              nsAString& aNamespaceURI);
+
+  nsresult IsEqualNode(nsIDOMNode* aOther, PRBool* aReturn);
+  PRBool IsEqualTo(nsINode* aOther);
 
   nsIContent* GetNextSibling() const { return mNextSibling; }
   nsIContent* GetPreviousSibling() const { return mPreviousSibling; }
 
   /**
    * Get the next node in the pre-order tree traversal of the DOM.  If
    * aRoot is non-null, then it must be an ancestor of |this|
    * (possibly equal to |this|) and only nodes that are descendants of
--- a/content/base/public/nsINodeInfo.h
+++ b/content/base/public/nsINodeInfo.h
@@ -76,17 +76,17 @@ class nsIPrincipal;
  { 0x95, 0x90, 0xcc, 0x43, 0x6b, 0xe9, 0xcf, 0xa0 } }
 
 class nsINodeInfo : public nsISupports
 {
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_INODEINFO_IID)
 
   nsINodeInfo()
-    : mInner(nsnull, nsnull, kNameSpaceID_None),
+    : mInner(nsnull, nsnull, kNameSpaceID_None, 0, nsnull),
       mOwnerManager(nsnull)
   {
   }
 
   /*
    * Get the name from this node as a string, this does not include the prefix.
    *
    * For the HTML element "<body>" this will return "body" and for the XML
@@ -116,22 +116,27 @@ public:
    * For the HTML element "<body>" this will return "body" and for the XML
    * element "<html:body>" this will return "html:body".
    */
   const nsString& QualifiedName() const {
     return mQualifiedName;
   }
 
   /*
-   * As above, but return the qualified name in corrected case as
-   * needed.  For example, for HTML elements in HTML documents, this
-   * will return an ASCII-uppercased version of the qualified name.
+   * Returns the node's nodeName as defined in DOM Core
    */
-  const nsString& QualifiedNameCorrectedCase() const {
-    return mQualifiedNameCorrectedCase;
+  const nsString& NodeName() const {
+    return mNodeName;
+  }
+
+  /*
+   * Returns the node's localName as defined in DOM Core
+   */
+  const nsString& LocalName() const {
+    return mLocalName;
   }
 
 #ifdef MOZILLA_INTERNAL_API
   /*
    * Get the prefix from this node as a string.
    *
    * For the HTML element "<body>" this will return a null string and for
    * the XML element "<html:body>" this will return the string "html".
@@ -154,41 +159,46 @@ public:
    */
   nsIAtom* GetPrefixAtom() const
   {
     return mInner.mPrefix;
   }
 
   /*
    * Get the namespace URI for a node, if the node has a namespace URI.
-   *
-   * For the HTML element "<body>" in a HTML document this will return a null
-   * string and for the XML element "<html:body>" (assuming that this element,
-   * or one of its ancestors has an
-   * xmlns:html='http://www.w3.org/1999/xhtml' attribute) this will return
-   * the string "http://www.w3.org/1999/xhtml".
    */
   virtual nsresult GetNamespaceURI(nsAString& aNameSpaceURI) const = 0;
 
   /*
    * Get the namespace ID for a node if the node has a namespace, if not this
    * returns kNameSpaceID_None.
-   *
-   * For the HTML element "<body>" in a HTML document this will return
-   * kNameSpaceID_None and for the XML element "<html:body>" (assuming that
-   * this element, or one of its ancestors has an
-   * xmlns:html='http://www.w3.org/1999/xhtml' attribute) this will return
-   * the namespace ID for "http://www.w3.org/1999/xhtml".
    */
   PRInt32 NamespaceID() const
   {
     return mInner.mNamespaceID;
   }
 
   /*
+   * Get the nodetype for the node. Returns the values specified in nsIDOMNode
+   * for nsIDOMNode.nodeType
+   */
+  PRUint16 NodeType() const
+  {
+    return mInner.mNodeType;
+  }
+
+  /*
+   * Get the extra name, used by PIs and DocTypes, for the node.
+   */
+  nsIAtom* GetExtraName() const
+  {
+    return mInner.mExtraName;
+  }
+
+  /*
    * Get and set the ID attribute atom for this node.
    * See http://www.w3.org/TR/1998/REC-xml-19980210#sec-attribute-types
    * for the definition of an ID attribute.
    *
    */
   nsIAtom* GetIDAttributeAtom() const
   {
     return mIDAttributeAtom;
@@ -294,17 +304,17 @@ public:
     return mQualifiedName == aQualifiedName;
   }
 
   /*
    * Retrieve a pointer to the document that owns this node info.
    */
   nsIDocument* GetDocument() const
   {
-    return mOwnerManager->GetDocument();
+    return mDocument;
   }
 
 protected:
   /*
    * nsNodeInfoInner is used for two things:
    *
    *   1. as a member in nsNodeInfo for holding the name, prefix and
    *      namespace ID
@@ -317,52 +327,61 @@ protected:
    * the key is automatically deleted.
    */
 
   class nsNodeInfoInner
   {
   public:
     nsNodeInfoInner()
       : mName(nsnull), mPrefix(nsnull), mNamespaceID(kNameSpaceID_Unknown),
-        mNameString(nsnull)
+        mNodeType(0), mNameString(nsnull), mExtraName(nsnull)
     {
     }
-    nsNodeInfoInner(nsIAtom *aName, nsIAtom *aPrefix, PRInt32 aNamespaceID)
+    nsNodeInfoInner(nsIAtom *aName, nsIAtom *aPrefix, PRInt32 aNamespaceID,
+                    PRUint16 aNodeType, nsIAtom* aExtraName)
       : mName(aName), mPrefix(aPrefix), mNamespaceID(aNamespaceID),
-        mNameString(nsnull)
+        mNodeType(aNodeType), mNameString(nsnull), mExtraName(aExtraName)
     {
     }
-    nsNodeInfoInner(const nsAString& aTmpName, nsIAtom *aPrefix, PRInt32 aNamespaceID)
+    nsNodeInfoInner(const nsAString& aTmpName, nsIAtom *aPrefix,
+                    PRInt32 aNamespaceID, PRUint16 aNodeType)
       : mName(nsnull), mPrefix(aPrefix), mNamespaceID(aNamespaceID),
-        mNameString(&aTmpName)
+        mNodeType(aNodeType), mNameString(&aTmpName), mExtraName(nsnull)
     {
     }
 
     nsIAtom*            mName;
     nsIAtom*            mPrefix;
     PRInt32             mNamespaceID;
+    PRUint16            mNodeType; // As defined by nsIDOMNode.nodeType
     const nsAString*    mNameString;
+    nsIAtom*            mExtraName; // Only used by PIs and DocTypes
   };
 
   // nsNodeInfoManager needs to pass mInner to the hash table.
   friend class nsNodeInfoManager;
 
+  nsIDocument* mDocument; // Weak. Cache of mOwnerManager->mDocument
+
   nsNodeInfoInner mInner;
 
   nsCOMPtr<nsIAtom> mIDAttributeAtom;
   nsNodeInfoManager* mOwnerManager; // Strong reference!
 
   /*
    * Members for various functions of mName+mPrefix that we can be
    * asked to compute.
    */
 
   // Qualified name
   nsString mQualifiedName;
 
-  // Qualified name in "corrected case"; this will depend on our
-  // document and on mNamespaceID.
-  nsString mQualifiedNameCorrectedCase;
+  // nodeName for the node.
+  nsString mNodeName;
+
+  // localName for the node. This is either equal to mInner.mName, or a
+  // void string, depending on mInner.mNodeType.
+  nsString mLocalName;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsINodeInfo, NS_INODEINFO_IID)
 
 #endif /* nsINodeInfo_h___ */
--- a/content/base/public/nsIRange.h
+++ b/content/base/public/nsIRange.h
@@ -43,16 +43,18 @@
 #include "nsINode.h"
 #include "nsIDOMRange.h"
 
 // IID for the nsIRange interface
 #define NS_IRANGE_IID \
 { 0x09dec26b, 0x1ab7, 0x4ff0, \
  { 0xa1, 0x67, 0x7f, 0x22, 0x9c, 0xaa, 0xc3, 0x04 } }
 
+class nsIDOMFontFaceList;
+
 class nsIRange : public nsIDOMRange {
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_IRANGE_IID)
 
   nsIRange()
     : mRoot(nsnull),
       mStartOffset(0),
       mEndOffset(0),
@@ -118,16 +120,19 @@ public:
   virtual nsresult SetEnd(nsINode* aParent, PRInt32 aOffset) = 0;
   virtual nsresult CloneRange(nsIRange** aNewRange) const = 0;
 
   // Work around hiding warnings
   NS_IMETHOD SetStart(nsIDOMNode* aParent, PRInt32 aOffset) = 0;
   NS_IMETHOD SetEnd(nsIDOMNode* aParent, PRInt32 aOffset) = 0;
   NS_IMETHOD CloneRange(nsIDOMRange** aNewRange) = 0;
 
+  // To support the font inspector API
+  NS_IMETHOD GetUsedFontFaces(nsIDOMFontFaceList** aResult) = 0;
+
 protected:
   nsCOMPtr<nsINode> mRoot;
   nsCOMPtr<nsINode> mStartParent;
   nsCOMPtr<nsINode> mEndParent;
   PRInt32 mStartOffset;
   PRInt32 mEndOffset;
 
   PRPackedBool mIsPositioned;
deleted file mode 100644
--- a/content/base/public/nsISyncLoadDOMService.idl
+++ /dev/null
@@ -1,101 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is mozilla.org code.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 2002
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   Jonas Sicking <sicking@bigfoot.com> (Original author)
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#include "nsISupports.idl"
-
-interface nsIURI;
-interface nsIPrincipal;
-interface nsIDOMDocument;
-interface nsIChannel;
-
-/*************************************************************************
- *                                                                       *
- *                          **** NOTICE ****                             *
- *                                                                       *
- *                                                                       *
- *    This interface is DEPRECATED!                                      *
- *    You should instead use XMLHttpRequest which now works both from    *
- *    Javascript and C++.                                                *
- *                                                                       *
- *    Additionally, synchronous network loads are evil.  Any delays      *
- *    from the server will appear as a hang in the mozilla UI.           *
- *    Therefore, they should be avoided as much as possible.             *
- *                                                                       *
- *    Don't make me come over there!!                                    *
- *                                                                       *
- *                                                                       *
- ************************************************************************/
-
-/**
- * The nsISyncDOMLoadService interface can be used to synchronously load
- * a document.
- *
- * @deprecated use XMLHttpRequest instead
- */
-
-[deprecated, scriptable, uuid(8095998d-ae1c-4cfa-9b43-0973e5d77eb0)]
-interface nsISyncLoadDOMService : nsISupports
-{
-    /**
-     * Synchronously load the document from the specified channel.
-     *
-     * @param aChannel   The channel to load the document from.
-     * @param aLoaderPrincipal Principal of loading document. For security
-     *                         checks null if no securitychecks should be done
-     *
-     * @returns The document loaded from the URI.
-     */
-    nsIDOMDocument loadDocument(in nsIChannel aChannel,
-                                in nsIPrincipal aLoaderPrincipal);
-
-    nsIDOMDocument loadDocumentAsXML(in nsIChannel aChannel,
-                                     in nsIPrincipal aLoaderPrincipal);
-
-    /**
-     * Synchronously load an XML document from the specified
-     * channel. The channel must be possible to open synchronously.
-     *
-     * @param aChannel   The channel to load the document from.
-     * @param aLoaderPrincipal Principal of loading document. For security
-     *                         checks null if no securitychecks should be done
-     *
-     * @returns The document loaded from the URI.
-     */
-    nsIDOMDocument loadLocalDocument(in nsIChannel aChannel,
-                                     in nsIPrincipal aLoaderPrincipal);
-};
--- a/content/base/src/nsCommentNode.cpp
+++ b/content/base/src/nsCommentNode.cpp
@@ -50,27 +50,30 @@ class nsCommentNode : public nsGenericDO
 public:
   nsCommentNode(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~nsCommentNode();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
-  NS_IMPL_NSIDOMNODE_USING_GENERIC_DOM_DATA
+  NS_FORWARD_NSIDOMNODE(nsGenericDOMDataNode::)
 
   // nsIDOMCharacterData
   NS_FORWARD_NSIDOMCHARACTERDATA(nsGenericDOMDataNode::)
 
   // nsIDOMComment
   // Empty interface
 
-  // nsIContent
+  // nsINode
   virtual PRBool IsNodeOfType(PRUint32 aFlags) const;
 
+  virtual nsGenericDOMDataNode* CloneDataNode(nsINodeInfo *aNodeInfo,
+                                              PRBool aCloneText) const;
+
   virtual nsXPCClassInfo* GetClassInfo();
 #ifdef DEBUG
   virtual void List(FILE* out, PRInt32 aIndent) const;
   virtual void DumpContent(FILE* out = stdout, PRInt32 aIndent = 0,
                            PRBool aDumpAll = PR_TRUE) const
   {
     return;
   }
@@ -96,16 +99,18 @@ NS_NewCommentNode(nsIContent** aInstance
   NS_ADDREF(*aInstancePtrResult = instance);
 
   return NS_OK;
 }
 
 nsCommentNode::nsCommentNode(already_AddRefed<nsINodeInfo> aNodeInfo)
   : nsGenericDOMDataNode(aNodeInfo)
 {
+  NS_ABORT_IF_FALSE(mNodeInfo->NodeType() == nsIDOMNode::COMMENT_NODE,
+                    "Bad NodeType in aNodeInfo");
 }
 
 nsCommentNode::~nsCommentNode()
 {
 }
 
 DOMCI_NODE_DATA(Comment, nsCommentNode)
 
@@ -122,42 +127,16 @@ NS_IMPL_RELEASE_INHERITED(nsCommentNode,
 
 
 PRBool
 nsCommentNode::IsNodeOfType(PRUint32 aFlags) const
 {
   return !(aFlags & ~(eCONTENT | eCOMMENT | eDATA_NODE));
 }
 
-NS_IMETHODIMP
-nsCommentNode::GetNodeName(nsAString& aNodeName)
-{
-  aNodeName.AssignLiteral("#comment");
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsCommentNode::GetNodeValue(nsAString& aNodeValue)
-{
-  return nsGenericDOMDataNode::GetNodeValue(aNodeValue);
-}
-
-NS_IMETHODIMP
-nsCommentNode::SetNodeValue(const nsAString& aNodeValue)
-{
-  return nsGenericDOMDataNode::SetNodeValue(aNodeValue);
-}
-
-NS_IMETHODIMP
-nsCommentNode::GetNodeType(PRUint16* aNodeType)
-{
-  *aNodeType = (PRUint16)nsIDOMNode::COMMENT_NODE;
-  return NS_OK;
-}
-
 nsGenericDOMDataNode*
 nsCommentNode::CloneDataNode(nsINodeInfo *aNodeInfo, PRBool aCloneText) const
 {
   nsCOMPtr<nsINodeInfo> ni = aNodeInfo;
   nsCommentNode *it = new nsCommentNode(ni.forget());
   if (it && aCloneText) {
     it->mText = mText;
   }
--- a/content/base/src/nsContentList.cpp
+++ b/content/base/src/nsContentList.cpp
@@ -40,17 +40,16 @@
  * nsBaseContentList is a basic list of content nodes; nsContentList
  * is a commonly used NodeList implementation (used for
  * getElementsByTagName, some properties on nsIDOMHTMLDocument, etc).
  */
 
 #include "nsContentList.h"
 #include "nsIContent.h"
 #include "nsIDOMNode.h"
-#include "nsIDOM3Node.h"
 #include "nsIDocument.h"
 #include "nsGenericElement.h"
 
 #include "nsContentUtils.h"
 
 #include "nsGkAtoms.h"
 
 // Form related includes
--- a/content/base/src/nsContentSink.cpp
+++ b/content/base/src/nsContentSink.cpp
@@ -175,22 +175,26 @@ NS_INTERFACE_MAP_END
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsContentSink)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsContentSink)
   if (tmp->mDocument) {
     tmp->mDocument->RemoveObserver(tmp);
   }
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mDocument)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mParser)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mNodeInfoManager)
+  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mScriptLoader)
+  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMARRAY(mScriptElements)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsContentSink)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mDocument)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mParser)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_MEMBER(mNodeInfoManager,
                                                   nsNodeInfoManager)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mScriptLoader)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mScriptElements)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 
 nsContentSink::nsContentSink()
 {
   // We have a zeroing operator new
   NS_ASSERTION(!mLayoutStarted, "What?");
   NS_ASSERTION(!mDynamicLowerValue, "What?");
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -60,17 +60,16 @@
 #include "nsIContent.h"
 #include "mozilla/dom/Element.h"
 #include "nsIDocument.h"
 #include "nsINodeInfo.h"
 #include "nsReadableUtils.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOMNodeList.h"
 #include "nsIDOMNode.h"
-#include "nsIDOM3Node.h"
 #include "nsIIOService.h"
 #include "nsNetCID.h"
 #include "nsNetUtil.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsDOMError.h"
 #include "nsPIDOMWindow.h"
 #include "nsIJSContextStack.h"
 #include "nsIDocShell.h"
@@ -2080,16 +2079,17 @@ nsContentUtils::SplitQName(const nsICont
   return NS_OK;
 }
 
 // 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, PR_TRUE, &colon);
@@ -2099,21 +2099,21 @@ nsContentUtils::GetNodeInfoFromQName(con
   sNameSpaceManager->RegisterNameSpace(aNamespaceURI, nsID);
   if (colon) {
     const PRUnichar* end;
     qName.EndReading(end);
 
     nsCOMPtr<nsIAtom> prefix = do_GetAtom(Substring(qName.get(), colon));
 
     rv = aNodeInfoManager->GetNodeInfo(Substring(colon + 1, end), prefix,
-                                       nsID, aNodeInfo);
+                                       nsID, aNodeType, aNodeInfo);
   }
   else {
     rv = aNodeInfoManager->GetNodeInfo(aQualifiedName, nsnull, nsID,
-                                       aNodeInfo);
+                                       aNodeType, aNodeInfo);
   }
   NS_ENSURE_SUCCESS(rv, rv);
 
   return nsContentUtils::IsValidNodeName((*aNodeInfo)->NameAtom(),
                                          (*aNodeInfo)->GetPrefixAtom(),
                                          (*aNodeInfo)->NamespaceID()) ?
          NS_OK : NS_ERROR_DOM_NAMESPACE_ERR;
 }
--- a/content/base/src/nsDOMAttribute.cpp
+++ b/content/base/src/nsDOMAttribute.cpp
@@ -67,17 +67,18 @@ using namespace mozilla::dom;
 PRBool nsDOMAttribute::sInitialized;
 
 nsDOMAttribute::nsDOMAttribute(nsDOMAttributeMap *aAttrMap,
                                already_AddRefed<nsINodeInfo> aNodeInfo,
                                const nsAString   &aValue, PRBool aNsAware)
   : nsIAttribute(aAttrMap, aNodeInfo, aNsAware), mValue(aValue), mChild(nsnull)
 {
   NS_ABORT_IF_FALSE(mNodeInfo, "We must get a nodeinfo here!");
-
+  NS_ABORT_IF_FALSE(mNodeInfo->NodeType() == nsIDOMNode::ATTRIBUTE_NODE,
+                    "Wrong nodeType");
 
   // We don't add a reference to our content. It will tell us
   // to drop our reference when it goes away.
 
   EnsureChildState();
 
   nsIContent* content = GetContentInternal();
   if (content) {
@@ -135,17 +136,16 @@ NS_INTERFACE_TABLE_HEAD(nsDOMAttribute)
   NS_INTERFACE_MAP_ENTRY_TEAROFF(nsISupportsWeakReference,
                                  new nsNodeSupportsWeakRefTearoff(this))
   NS_INTERFACE_MAP_ENTRY_TEAROFF(nsIDOMEventTarget,
                                  nsDOMEventRTTearoff::Create(this))
   NS_INTERFACE_MAP_ENTRY_TEAROFF(nsIDOM3EventTarget,
                                  nsDOMEventRTTearoff::Create(this))
   NS_INTERFACE_MAP_ENTRY_TEAROFF(nsIDOMNSEventTarget,
                                  nsDOMEventRTTearoff::Create(this))
-  NS_INTERFACE_MAP_ENTRY_TEAROFF(nsIDOM3Node, new nsNode3Tearoff(this))
   NS_INTERFACE_MAP_ENTRY_TEAROFF(nsIDOMXPathNSResolver,
                                  new nsNode3Tearoff(this))
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(Attr)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsDOMAttribute)
 NS_IMPL_CYCLE_COLLECTING_RELEASE_WITH_DESTROY(nsDOMAttribute,
                                               nsNodeUtils::LastRelease(this))
@@ -188,28 +188,29 @@ nsDOMAttribute::SetOwnerDocument(nsIDocu
   NS_ASSERTION(doc != aDocument, "bad call to nsDOMAttribute::SetOwnerDocument");
   if (doc) {
     doc->DeleteAllPropertiesFor(this);
   }
 
   nsCOMPtr<nsINodeInfo> newNodeInfo;
   newNodeInfo = aDocument->NodeInfoManager()->
     GetNodeInfo(mNodeInfo->NameAtom(), mNodeInfo->GetPrefixAtom(),
-                mNodeInfo->NamespaceID());
+                mNodeInfo->NamespaceID(),
+                nsIDOMNode::ATTRIBUTE_NODE);
   NS_ENSURE_TRUE(newNodeInfo, NS_ERROR_OUT_OF_MEMORY);
   NS_ASSERTION(newNodeInfo, "GetNodeInfo lies");
   mNodeInfo.swap(newNodeInfo);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMAttribute::GetName(nsAString& aName)
 {
-  aName = mNodeInfo->QualifiedName();
+  aName = NodeName();
   return NS_OK;
 }
 
 already_AddRefed<nsIAtom>
 nsDOMAttribute::GetNameAtom(nsIContent* aContent)
 {
   nsIAtom* result = nsnull;
   if (!mNsAware &&
@@ -494,50 +495,91 @@ nsDOMAttribute::IsSupported(const nsAStr
 already_AddRefed<nsIURI>
 nsDOMAttribute::GetBaseURI() const
 {
   nsINode *parent = GetContentInternal();
 
   return parent ? parent->GetBaseURI() : nsnull;
 }
 
-PRBool
-nsDOMAttribute::IsEqualNode(nsINode* aOther)
+NS_IMETHODIMP
+nsDOMAttribute::GetDOMBaseURI(nsAString &aURI)
 {
-  if (!aOther || !aOther->IsNodeOfType(eATTRIBUTE))
-    return PR_FALSE;
-
-  nsDOMAttribute *other = static_cast<nsDOMAttribute*>(aOther);
+  return nsINode::GetDOMBaseURI(aURI);
+}
 
-  // Prefix, namespace URI, local name, node name check.
-  if (!mNodeInfo->Equals(other->NodeInfo())) {
-    return PR_FALSE;
-  }
-
-  // Value check
-  // Checks not needed:  Child nodes, attributes.
-  nsAutoString ourValue, otherValue;
-  GetValue(ourValue);
-  other->GetValue(otherValue);
-
-  return ourValue.Equals(otherValue);
+NS_IMETHODIMP
+nsDOMAttribute::CompareDocumentPosition(nsIDOMNode *other,
+                                        PRUint16 *aResult)
+{
+  return nsINode::CompareDocumentPosition(other, aResult);
 }
 
-void
+NS_IMETHODIMP
+nsDOMAttribute::IsEqualNode(nsIDOMNode* aOther, PRBool* aResult)
+{
+  return nsINode::IsEqualNode(aOther, aResult);
+}
+
+NS_IMETHODIMP
 nsDOMAttribute::GetTextContent(nsAString &aTextContent)
 {
-  GetNodeValue(aTextContent);
+  return GetNodeValue(aTextContent);
 }
 
-nsresult
+NS_IMETHODIMP
 nsDOMAttribute::SetTextContent(const nsAString& aTextContent)
 {
   return SetNodeValue(aTextContent);
 }
 
+NS_IMETHODIMP
+nsDOMAttribute::IsSameNode(nsIDOMNode *other, PRBool *aResult)
+{
+  *aResult = other == this;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDOMAttribute::LookupPrefix(const nsAString & namespaceURI,
+                             nsAString & aResult)
+{
+  SetDOMStringToNull(aResult);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDOMAttribute::IsDefaultNamespace(const nsAString & namespaceURI,
+                                   PRBool *aResult)
+{
+  *aResult = namespaceURI.IsEmpty();
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDOMAttribute::LookupNamespaceURI(const nsAString & prefix,
+                              nsAString & aResult)
+{
+  SetDOMStringToNull(aResult);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDOMAttribute::SetUserData(const nsAString & key,
+                            nsIVariant *data, nsIDOMUserDataHandler *handler,
+                            nsIVariant **aResult)
+{
+  return nsINode::SetUserData(key, data, handler, aResult);
+}
+
+NS_IMETHODIMP
+nsDOMAttribute::GetUserData(const nsAString & key, nsIVariant **aResult)
+{
+  return nsINode::GetUserData(key, aResult);
+}
 
 NS_IMETHODIMP
 nsDOMAttribute::GetIsId(PRBool* aReturn)
 {
   nsIContent* content = GetContentInternal();
   if (!content)
   {
     *aReturn = PR_FALSE;
--- a/content/base/src/nsDOMAttribute.h
+++ b/content/base/src/nsDOMAttribute.h
@@ -51,17 +51,17 @@
 #include "nsINodeInfo.h"
 #include "nsIDOM3Attr.h"
 #include "nsDOMAttributeMap.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsContentUtils.h"
 #include "nsStubMutationObserver.h"
 
 // Attribute helper class used to wrap up an attribute with a dom
-// object that implements nsIDOMAttr, nsIDOM3Attr, nsIDOMNode, nsIDOM3Node
+// object that implements nsIDOMAttr, nsIDOM3Attr, nsIDOMNode
 class nsDOMAttribute : public nsIAttribute,
                        public nsIDOMAttr,
                        public nsIDOM3Attr,
                        public nsStubMutationObserver
 {
 public:
   nsDOMAttribute(nsDOMAttributeMap* aAttrMap,
                  already_AddRefed<nsINodeInfo> aNodeInfo,
@@ -107,19 +107,16 @@ public:
                                             const nsIID& aIID);
   virtual nsresult GetSystemEventGroup(nsIDOMEventGroup** aGroup);
   virtual nsIScriptContext* GetContextForEventHandlers(nsresult* aRv)
   {
     return nsContentUtils::GetContextForEventHandlers(this, aRv);
   }
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
   virtual already_AddRefed<nsIURI> GetBaseURI() const;
-  virtual PRBool IsEqualNode(nsINode *aOtherNode);
-  virtual void GetTextContent(nsAString &aTextContent);
-  virtual nsresult SetTextContent(const nsAString& aTextContent);
 
   static void Initialize();
   static void Shutdown();
 
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsDOMAttribute,
                                                          nsIAttribute)
 
   NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED
--- a/content/base/src/nsDOMAttributeMap.cpp
+++ b/content/base/src/nsDOMAttributeMap.cpp
@@ -336,17 +336,18 @@ nsDOMAttributeMap::SetNamedItemInternal(
         if (mContent->IsInHTMLDocument() &&
             mContent->IsHTML()) {
           nsAutoString lower;
           ToLowerCase(name, lower);
           name = lower;
         }
 
         rv = mContent->NodeInfo()->NodeInfoManager()->
-          GetNodeInfo(name, nsnull, kNameSpaceID_None, getter_AddRefs(ni));
+          GetNodeInfo(name, nsnull, kNameSpaceID_None,
+                      nsIDOMNode::ATTRIBUTE_NODE, getter_AddRefs(ni));
         NS_ENSURE_SUCCESS(rv, rv);
         // value is already empty
       }
     }
 
     nsAutoString value;
     attribute->GetValue(value);
 
@@ -402,17 +403,18 @@ nsDOMAttributeMap::GetItemAt(PRUint32 aI
   nsDOMAttribute* node = nsnull;
 
   const nsAttrName* name;
   if (mContent && (name = mContent->GetAttrNameAt(aIndex))) {
     // Don't use the nodeinfo even if one exists since it can
     // have the wrong owner document.
     nsCOMPtr<nsINodeInfo> ni;
     ni = mContent->NodeInfo()->NodeInfoManager()->
-      GetNodeInfo(name->LocalName(), name->GetPrefix(), name->NamespaceID());
+      GetNodeInfo(name->LocalName(), name->GetPrefix(), name->NamespaceID(),
+                  nsIDOMNode::ATTRIBUTE_NODE);
     if (ni) {
       node = GetAttribute(ni, PR_TRUE);
     }
     else {
       *aResult = NS_ERROR_OUT_OF_MEMORY;
     }
   }
 
@@ -479,17 +481,18 @@ nsDOMAttributeMap::GetNamedItemNSInterna
     const nsAttrName* name = mContent->GetAttrNameAt(i);
     PRInt32 attrNS = name->NamespaceID();
     nsIAtom* nameAtom = name->LocalName();
 
     if (nameSpaceID == attrNS &&
         nameAtom->Equals(aLocalName)) {
       nsCOMPtr<nsINodeInfo> ni;
       ni = mContent->NodeInfo()->NodeInfoManager()->
-        GetNodeInfo(nameAtom, name->GetPrefix(), nameSpaceID);
+        GetNodeInfo(nameAtom, name->GetPrefix(), nameSpaceID,
+                    nsIDOMNode::ATTRIBUTE_NODE);
       NS_ENSURE_TRUE(ni, NS_ERROR_OUT_OF_MEMORY);
 
       if (aRemove) {
         return RemoveAttribute(ni, aReturn);
       }
 
       NS_ADDREF(*aReturn = GetAttribute(ni, PR_TRUE));
 
--- a/content/base/src/nsDOMDocumentType.cpp
+++ b/content/base/src/nsDOMDocumentType.cpp
@@ -41,17 +41,16 @@
 
 #include "nsDOMDocumentType.h"
 #include "nsDOMAttributeMap.h"
 #include "nsIDOMNamedNodeMap.h"
 #include "nsGkAtoms.h"
 #include "nsCOMPtr.h"
 #include "nsContentUtils.h"
 #include "nsDOMString.h"
-#include "nsIDOM3Node.h"
 #include "nsNodeInfoManager.h"
 #include "nsIDocument.h"
 #include "nsIXPConnect.h"
 #include "nsIDOMDocument.h"
 #include "xpcpublic.h"
 
 nsresult
 NS_NewDOMDocumentType(nsIDOMDocumentType** aDocType,
@@ -74,39 +73,41 @@ NS_NewDOMDocumentType(nsIDOMDocumentType
   else {
     nimgr = new nsNodeInfoManager();
     nsresult rv = nimgr->Init(nsnull);
     NS_ENSURE_SUCCESS(rv, rv);
 
     nimgr->SetDocumentPrincipal(aPrincipal);
   }
 
-  nsCOMPtr<nsINodeInfo> ni;
-  ni = nimgr->GetNodeInfo(nsGkAtoms::documentTypeNodeName, nsnull,
-                          kNameSpaceID_None);
+  nsCOMPtr<nsINodeInfo> ni =
+    nimgr->GetNodeInfo(nsGkAtoms::documentTypeNodeName, nsnull,
+                       kNameSpaceID_None,
+                       nsIDOMNode::DOCUMENT_TYPE_NODE,
+                       aName);
   NS_ENSURE_TRUE(ni, NS_ERROR_OUT_OF_MEMORY);
 
-  *aDocType = new nsDOMDocumentType(ni.forget(), aName, aPublicId, aSystemId,
+  *aDocType = new nsDOMDocumentType(ni.forget(), aPublicId, aSystemId,
                                     aInternalSubset);
   NS_ADDREF(*aDocType);
 
   return NS_OK;
 }
 
 nsDOMDocumentType::nsDOMDocumentType(already_AddRefed<nsINodeInfo> aNodeInfo,
-                                     nsIAtom *aName,
                                      const nsAString& aPublicId,
                                      const nsAString& aSystemId,
                                      const nsAString& aInternalSubset) :
-  nsGenericDOMDataNode(aNodeInfo),
-  mName(aName),
+  nsDOMDocumentTypeForward(aNodeInfo),
   mPublicId(aPublicId),
   mSystemId(aSystemId),
   mInternalSubset(aInternalSubset)
 {
+  NS_ABORT_IF_FALSE(mNodeInfo->NodeType() == nsIDOMNode::DOCUMENT_TYPE_NODE,
+                    "Bad NodeType in aNodeInfo");
 }
 
 nsDOMDocumentType::~nsDOMDocumentType()
 {
 }
 
 DOMCI_NODE_DATA(DocumentType, nsDOMDocumentType)
 
@@ -135,17 +136,17 @@ const nsTextFragment*
 nsDOMDocumentType::GetText()
 {
   return nsnull;
 }
 
 NS_IMETHODIMP    
 nsDOMDocumentType::GetName(nsAString& aName)
 {
-  mName->ToString(aName);
+  aName = NodeName();
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMDocumentType::GetPublicId(nsAString& aPublicId)
 {
   aPublicId = mPublicId;
 
@@ -162,50 +163,21 @@ nsDOMDocumentType::GetSystemId(nsAString
 
 NS_IMETHODIMP
 nsDOMDocumentType::GetInternalSubset(nsAString& aInternalSubset)
 {
   aInternalSubset = mInternalSubset;
   return NS_OK;
 }
 
-NS_IMETHODIMP
-nsDOMDocumentType::GetNodeName(nsAString& aNodeName)
-{
-  mName->ToString(aNodeName);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDOMDocumentType::GetNodeValue(nsAString& aNodeValue)
-{
-  SetDOMStringToNull(aNodeValue);
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDOMDocumentType::SetNodeValue(const nsAString& aNodeValue)
-{
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsDOMDocumentType::GetNodeType(PRUint16* aNodeType)
-{
-  *aNodeType = nsIDOMNode::DOCUMENT_TYPE_NODE;
-
-  return NS_OK;
-}
-
 nsGenericDOMDataNode*
 nsDOMDocumentType::CloneDataNode(nsINodeInfo *aNodeInfo, PRBool aCloneText) const
 {
   nsCOMPtr<nsINodeInfo> ni = aNodeInfo;
-  return new nsDOMDocumentType(ni.forget(), mName, mPublicId, mSystemId,
+  return new nsDOMDocumentType(ni.forget(), mPublicId, mSystemId,
                                mInternalSubset);
 }
 
 nsresult
 nsDOMDocumentType::BindToTree(nsIDocument *aDocument, nsIContent *aParent,
                               nsIContent *aBindingParent,
                               PRBool aCompileEventHandlers)
 {
@@ -221,17 +193,19 @@ nsDOMDocumentType::BindToTree(nsIDocumen
     //     break inserting DOMDocumentType nodes through other DOM methods
     //     though.
     nsNodeInfoManager *nimgr = aParent ?
       aParent->NodeInfo()->NodeInfoManager() :
       aDocument->NodeInfoManager();
     nsCOMPtr<nsINodeInfo> newNodeInfo;
     newNodeInfo = nimgr->GetNodeInfo(mNodeInfo->NameAtom(),
                                      mNodeInfo->GetPrefixAtom(),
-                                     mNodeInfo->NamespaceID());
+                                     mNodeInfo->NamespaceID(),
+                                     nsIDOMNode::DOCUMENT_TYPE_NODE,
+                                     mNodeInfo->GetExtraName());
     NS_ENSURE_TRUE(newNodeInfo, NS_ERROR_OUT_OF_MEMORY);
 
     mNodeInfo.swap(newNodeInfo);
 
     JSObject *oldScope = GetWrapper();
     if (oldScope) {
       nsIXPConnect *xpc = nsContentUtils::XPConnect();
 
--- a/content/base/src/nsDOMDocumentType.h
+++ b/content/base/src/nsDOMDocumentType.h
@@ -48,47 +48,73 @@
 #include "nsGenericDOMDataNode.h"
 #include "nsString.h"
 
 // XXX DocumentType is currently implemented by inheriting the generic
 // CharacterData object, even though DocumentType is not character
 // data. This is done simply for convenience and should be changed if
 // this restricts what should be done for character data.
 
-class nsDOMDocumentType : public nsGenericDOMDataNode,
-                          public nsIDOMDocumentType
+class nsDOMDocumentTypeForward : public nsGenericDOMDataNode,
+                                 public nsIDOMDocumentType
+{
+public:
+  nsDOMDocumentTypeForward(already_AddRefed<nsINodeInfo> aNodeInfo)
+    : nsGenericDOMDataNode(aNodeInfo)
+  {
+  }
+
+  // nsIDOMNode
+  NS_FORWARD_NSIDOMNODE(nsGenericDOMDataNode::)
+};
+
+class nsDOMDocumentType : public nsDOMDocumentTypeForward
 {
 public:
   nsDOMDocumentType(already_AddRefed<nsINodeInfo> aNodeInfo,
-                    nsIAtom *aName,
                     const nsAString& aPublicId,
                     const nsAString& aSystemId,
                     const nsAString& aInternalSubset);
 
   virtual ~nsDOMDocumentType();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMNode
-  NS_IMPL_NSIDOMNODE_USING_GENERIC_DOM_DATA
+  // Forwarded by base class
 
   // nsIDOMDocumentType
   NS_DECL_NSIDOMDOCUMENTTYPE
 
+  NS_IMETHODIMP GetNodeValue(nsAString& aNodeValue)
+  {
+    SetDOMStringToNull(aNodeValue);
+  
+    return NS_OK;
+  }
+  NS_IMETHODIMP SetNodeValue(const nsAString& aNodeValue)
+  {
+    return NS_OK;
+  }
+
+  // nsINode
+  virtual PRBool IsNodeOfType(PRUint32 aFlags) const;
+
   // nsIContent overrides
-  virtual PRBool IsNodeOfType(PRUint32 aFlags) const;
   virtual const nsTextFragment* GetText();
   virtual nsresult BindToTree(nsIDocument *aDocument, nsIContent *aParent,
                               nsIContent *aBindingParent,
                               PRBool aCompileEventHandlers);
 
+  virtual nsGenericDOMDataNode* CloneDataNode(nsINodeInfo *aNodeInfo,
+                                              PRBool aCloneText) const;
+
   virtual nsXPCClassInfo* GetClassInfo();
 protected:
-  nsCOMPtr<nsIAtom> mName;
   nsString mPublicId;
   nsString mSystemId;
   nsString mInternalSubset;
 };
 
 nsresult
 NS_NewDOMDocumentType(nsIDOMDocumentType** aDocType,
                       nsNodeInfoManager *aOwnerDoc,
--- a/content/base/src/nsDOMParser.cpp
+++ b/content/base/src/nsDOMParser.cpp
@@ -45,94 +45,44 @@
 #include "nsStringStream.h"
 #include "nsIDocument.h"
 #include "nsIDOMDocument.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsIPrincipal.h"
 #include "nsIDOMClassInfo.h"
 #include "nsReadableUtils.h"
 #include "nsCRT.h"
-#include "nsLoadListenerProxy.h"
 #include "nsStreamUtils.h"
 #include "nsThreadUtils.h"
 #include "nsNetCID.h"
 #include "nsContentUtils.h"
 #include "nsDOMJSUtils.h"
 #include "nsDOMError.h"
 #include "nsIDOMWindow.h"
 #include "nsPIDOMWindow.h"
 #include "mozilla/AutoRestore.h"
 
 using namespace mozilla;
 
-// nsIDOMEventListener
-nsresult
-nsDOMParser::HandleEvent(nsIDOMEvent* aEvent)
-{
-  return NS_OK;
-}
-
-// nsIDOMLoadListener
-nsresult
-nsDOMParser::Load(nsIDOMEvent* aEvent)
-{
-  mLoopingForSyncLoad = PR_FALSE;
-
-  return NS_OK;
-}
-
-nsresult
-nsDOMParser::BeforeUnload(nsIDOMEvent* aEvent)
-{
-  return NS_OK;
-}
-
-nsresult
-nsDOMParser::Unload(nsIDOMEvent* aEvent)
-{
-  return NS_OK;
-}
-
-nsresult
-nsDOMParser::Abort(nsIDOMEvent* aEvent)
-{
-  mLoopingForSyncLoad = PR_FALSE;
-
-  return NS_OK;
-}
-
-nsresult
-nsDOMParser::Error(nsIDOMEvent* aEvent)
-{
-  mLoopingForSyncLoad = PR_FALSE;
-
-  return NS_OK;
-}
-
 nsDOMParser::nsDOMParser()
-  : mLoopingForSyncLoad(PR_FALSE),
-    mAttemptedInit(PR_FALSE)
+  : mAttemptedInit(PR_FALSE)
 {
 }
 
 nsDOMParser::~nsDOMParser()
 {
-  NS_ABORT_IF_FALSE(!mLoopingForSyncLoad, "we rather crash than hang");
-  mLoopingForSyncLoad = PR_FALSE;
 }
 
 DOMCI_DATA(DOMParser, nsDOMParser)
 
 // QueryInterface implementation for nsDOMParser
 NS_INTERFACE_MAP_BEGIN(nsDOMParser)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMParser)
   NS_INTERFACE_MAP_ENTRY(nsIDOMParser)
   NS_INTERFACE_MAP_ENTRY(nsIDOMParserJS)
-  NS_INTERFACE_MAP_ENTRY(nsIDOMLoadListener)
-  NS_INTERFACE_MAP_ENTRY(nsIDOMEventListener)
   NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
   NS_INTERFACE_MAP_ENTRY(nsIJSNativeInitializer)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(DOMParser)
 NS_INTERFACE_MAP_END
 
 
 NS_IMPL_ADDREF(nsDOMParser)
 NS_IMPL_RELEASE(nsDOMParser)
@@ -232,48 +182,32 @@ nsDOMParser::ParseFromStream(nsIInputStr
   nsCOMPtr<nsIDOMDocument> domDocument;
   rv = nsContentUtils::CreateDocument(EmptyString(), EmptyString(), nsnull,
                                       mDocumentURI, mBaseURI,
                                       mOriginalPrincipal,
                                       scriptHandlingObject,
                                       getter_AddRefs(domDocument));
   NS_ENSURE_SUCCESS(rv, rv);
 
-  // Register as a load listener on the document
-  nsCOMPtr<nsPIDOMEventTarget> target(do_QueryInterface(domDocument));
-  if (target) {
-    nsWeakPtr requestWeak(do_GetWeakReference(static_cast<nsIDOMParser*>(this)));
-    nsLoadListenerProxy* proxy = new nsLoadListenerProxy(requestWeak);
-    if (!proxy) return NS_ERROR_OUT_OF_MEMORY;
-
-    // This will addref the proxy
-    rv = target->AddEventListenerByIID(static_cast<nsIDOMEventListener*>(proxy), 
-                                       NS_GET_IID(nsIDOMLoadListener));
-    NS_ENSURE_SUCCESS(rv, rv);
-  }
-
   // Create a fake channel 
   nsCOMPtr<nsIChannel> parserChannel;
   NS_NewInputStreamChannel(getter_AddRefs(parserChannel), mDocumentURI, nsnull,
                            nsDependentCString(contentType), nsnull);
   NS_ENSURE_STATE(parserChannel);
 
   // More principal-faking here 
   parserChannel->SetOwner(mOriginalPrincipal);
 
   if (charset) {
     parserChannel->SetContentCharset(nsDependentCString(charset));
   }
 
   // Tell the document to start loading
   nsCOMPtr<nsIStreamListener> listener;
 
-  AutoRestore<PRPackedBool> restoreSyncLoop(mLoopingForSyncLoad);
-  mLoopingForSyncLoad = PR_TRUE;
-
   // Have to pass PR_FALSE for reset here, else the reset will remove
   // our event listener.  Should that listener addition move to later
   // than this call?  Then we wouldn't need to mess around with
   // SetPrincipal, etc, probably!
   nsCOMPtr<nsIDocument> document(do_QueryInterface(domDocument));
   if (!document) return NS_ERROR_FAILURE;
 
   if (nsContentUtils::IsSystemPrincipal(mOriginalPrincipal)) {
@@ -314,25 +248,16 @@ nsDOMParser::ParseFromStream(nsIInputStr
   rv = listener->OnStopRequest(parserChannel, nsnull, status);
   // Failure returned from OnStopRequest does not affect the final status of
   // the channel, so we do not need to call Cancel(rv) as we do above.
 
   if (NS_FAILED(rv)) {
     return NS_ERROR_FAILURE;
   }
 
-  // Process events until we receive a load, abort, or error event for the
-  // document object.  That event may have already fired.
-
-  nsIThread *thread = NS_GetCurrentThread();
-  while (mLoopingForSyncLoad) {
-    if (!NS_ProcessNextEvent(thread))
-      break;
-  }
-
   domDocument.swap(*aResult);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMParser::Init(nsIPrincipal* principal, nsIURI* documentURI,
                   nsIURI* baseURI, nsIScriptGlobalObject* aScriptObject)
--- a/content/base/src/nsDOMParser.h
+++ b/content/base/src/nsDOMParser.h
@@ -36,48 +36,36 @@
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef nsDOMParser_h__
 #define nsDOMParser_h__
 
 #include "nsIDOMParser.h"
 #include "nsCOMPtr.h"
 #include "nsIURI.h"
-#include "nsIDOMLoadListener.h"
 #include "nsWeakReference.h"
 #include "nsIJSNativeInitializer.h"
 
 class nsDOMParser : public nsIDOMParser,
                     public nsIDOMParserJS,
-                    public nsIDOMLoadListener,
                     public nsIJSNativeInitializer,
                     public nsSupportsWeakReference
 {
 public: 
   nsDOMParser();
   virtual ~nsDOMParser();
 
   NS_DECL_ISUPPORTS
 
   // nsIDOMParser
   NS_DECL_NSIDOMPARSER
 
   // nsIDOMParserJS
   NS_DECL_NSIDOMPARSERJS
 
-  // nsIDOMEventListener
-  NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent);
-
-  // nsIDOMLoadListener
-  NS_IMETHOD Load(nsIDOMEvent* aEvent);
-  NS_IMETHOD BeforeUnload(nsIDOMEvent* aEvent);
-  NS_IMETHOD Unload(nsIDOMEvent* aEvent);
-  NS_IMETHOD Abort(nsIDOMEvent* aEvent);
-  NS_IMETHOD Error(nsIDOMEvent* aEvent);
-
   // nsIJSNativeInitializer
   NS_IMETHOD Initialize(nsISupports* aOwner, JSContext* cx, JSObject* obj,
                         PRUint32 argc, jsval *argv);
 
 private:
   class AttemptedInitMarker {
   public:
     AttemptedInitMarker(PRPackedBool* aAttemptedInit) :
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -1697,17 +1697,16 @@ NS_INTERFACE_TABLE_HEAD(nsDocument)
     NS_INTERFACE_TABLE_ENTRY(nsDocument, nsIRadioGroupContainer)
     NS_INTERFACE_TABLE_ENTRY(nsDocument, nsIRadioGroupContainer_MOZILLA_2_0_BRANCH)
     NS_INTERFACE_TABLE_ENTRY(nsDocument, nsIMutationObserver)
     NS_INTERFACE_TABLE_ENTRY(nsDocument, nsIApplicationCacheContainer)
     NS_INTERFACE_TABLE_ENTRY(nsDocument, nsIDOMDocumentTouch)
   NS_OFFSET_AND_INTERFACE_TABLE_END
   NS_OFFSET_AND_INTERFACE_TABLE_TO_MAP_SEGUE
   NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(nsDocument)
-  NS_INTERFACE_MAP_ENTRY_TEAROFF(nsIDOM3Node, new nsNode3Tearoff(this))
   NS_INTERFACE_MAP_ENTRY_TEAROFF(nsIDOMXPathNSResolver,
                                  new nsNode3Tearoff(this))
   NS_INTERFACE_MAP_ENTRY_TEAROFF(nsIDOMNodeSelector,
                                  new nsNodeSelectorTearoff(this))
   if (aIID.Equals(NS_GET_IID(nsIDOMXPathEvaluator)) ||
       aIID.Equals(NS_GET_IID(nsIXPathEvaluatorInternal))) {
     if (!mXPathEvaluatorTearoff) {
       nsresult rv;
@@ -1993,16 +1992,18 @@ nsDocument::Init()
 
   NS_ADDREF(mNodeInfoManager);
 
   nsresult  rv = mNodeInfoManager->Init(this);
   NS_ENSURE_SUCCESS(rv, rv);
 
   mNodeInfo = mNodeInfoManager->GetDocumentNodeInfo();
   NS_ENSURE_TRUE(mNodeInfo, NS_ERROR_OUT_OF_MEMORY);
+  NS_ABORT_IF_FALSE(mNodeInfo->NodeType() == nsIDOMNode::DOCUMENT_NODE,
+                    "Bad NodeType in aNodeInfo");
 
   NS_ASSERTION(GetOwnerDoc() == this, "Our nodeinfo is busted!");
 
   mScriptLoader = new nsScriptLoader(this);
   NS_ENSURE_TRUE(mScriptLoader, NS_ERROR_OUT_OF_MEMORY);
 
   if (!mImageTracker.Init()) {
     return NS_ERROR_OUT_OF_MEMORY;
@@ -3378,16 +3379,28 @@ nsDocument::FindContentForSubDocument(ns
 }
 
 PRBool
 nsDocument::IsNodeOfType(PRUint32 aFlags) const
 {
     return !(aFlags & ~eDOCUMENT);
 }
 
+PRUint16
+nsDocument::NodeType()
+{
+    return (PRUint16)nsIDOMNode::DOCUMENT_NODE;
+}
+
+void
+nsDocument::NodeName(nsAString& aNodeName)
+{
+  aNodeName.AssignLiteral("#document");
+}
+
 Element*
 nsDocument::GetRootElementInternal() const
 {
   // Loop backwards because any non-elements, such as doctypes and PIs
   // are likely to appear before the root element.
   PRUint32 i;
   for (i = mChildren.ChildCount(); i > 0; --i) {
     nsIContent* child = mChildren.ChildAt(i - 1);
@@ -4368,16 +4381,17 @@ nsresult
 nsDocument::CreateElementNS(const nsAString& aNamespaceURI,
                             const nsAString& aQualifiedName,
                             nsIContent** aReturn)
 {
   nsCOMPtr<nsINodeInfo> nodeInfo;
   nsresult rv = nsContentUtils::GetNodeInfoFromQName(aNamespaceURI,
                                                      aQualifiedName,
                                                      mNodeInfoManager,
+                                                     nsIDOMNode::ELEMENT_NODE,
                                                      getter_AddRefs(nodeInfo));
   NS_ENSURE_SUCCESS(rv, rv);
 
   PRInt32 ns = nodeInfo->NamespaceID();
   return NS_NewElement(aReturn, ns,
                        nodeInfo.forget(), NOT_FROM_PARSER);
 }
 
@@ -4500,16 +4514,17 @@ nsDocument::CreateAttribute(const nsAStr
   nsresult rv = nsContentUtils::CheckQName(aName, PR_FALSE);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsAutoString value;
   nsDOMAttribute* attribute;
 
   nsCOMPtr<nsINodeInfo> nodeInfo;
   rv = mNodeInfoManager->GetNodeInfo(aName, nsnull, kNameSpaceID_None,
+                                     nsIDOMNode::ATTRIBUTE_NODE,
                                      getter_AddRefs(nodeInfo));
   NS_ENSURE_SUCCESS(rv, rv);
 
   attribute = new nsDOMAttribute(nsnull, nodeInfo.forget(), value, PR_FALSE);
   NS_ENSURE_TRUE(attribute, NS_ERROR_OUT_OF_MEMORY);
 
   return CallQueryInterface(attribute, aReturn);
 }
@@ -4521,16 +4536,17 @@ nsDocument::CreateAttributeNS(const nsAS
 {
   NS_ENSURE_ARG_POINTER(aResult);
   *aResult = nsnull;
 
   nsCOMPtr<nsINodeInfo> nodeInfo;
   nsresult rv = nsContentUtils::GetNodeInfoFromQName(aNamespaceURI,
                                                      aQualifiedName,
                                                      mNodeInfoManager,
+                                                     nsIDOMNode::ATTRIBUTE_NODE,
                                                      getter_AddRefs(nodeInfo));
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsAutoString value;
   nsDOMAttribute* attribute =
     new nsDOMAttribute(nsnull, nodeInfo.forget(), value, PR_TRUE);
   NS_ENSURE_TRUE(attribute, NS_ERROR_OUT_OF_MEMORY);
 
@@ -5183,17 +5199,18 @@ nsDocument::SetTitle(const nsAString& aT
   if (!title) {
     Element *head = GetHeadElement();
     if (!head)
       return NS_OK;
 
     {
       nsCOMPtr<nsINodeInfo> titleInfo;
       titleInfo = mNodeInfoManager->GetNodeInfo(nsGkAtoms::title, nsnull,
-                                                kNameSpaceID_XHTML);
+                                                kNameSpaceID_XHTML,
+                                                nsIDOMNode::ELEMENT_NODE);
       if (!titleInfo)
         return NS_OK;
       title = NS_NewHTMLTitleElement(titleInfo.forget());
       if (!title)
         return NS_OK;
     }
 
     head->AppendChildTo(title, PR_TRUE);
@@ -5230,17 +5247,17 @@ nsDocument::DoNotifyPossibleTitleChange(
   GetTitle(title);
 
   nsCOMPtr<nsIPresShell> shell = GetShell();
   if (shell) {
     nsCOMPtr<nsISupports> container = shell->GetPresContext()->GetContainer();
     if (container) {
       nsCOMPtr<nsIBaseWindow> docShellWin = do_QueryInterface(container);
       if (docShellWin) {
-        docShellWin->SetTitle(PromiseFlatString(title).get());
+        docShellWin->SetTitle(title.get());
       }
     }
   }
 
   // Fire a DOM event for the title change.
   nsContentUtils::DispatchChromeEvent(this, static_cast<nsIDocument*>(this),
                                       NS_LITERAL_STRING("DOMTitleChanged"),
                                       PR_TRUE, PR_TRUE);
@@ -5760,45 +5777,91 @@ nsDocument::Normalize()
 NS_IMETHODIMP
 nsDocument::IsSupported(const nsAString& aFeature, const nsAString& aVersion,
                         PRBool* aReturn)
 {
   return nsGenericElement::InternalIsSupported(static_cast<nsIDOMDocument*>(this),
                                                aFeature, aVersion, aReturn);
 }
 
-void
+NS_IMETHODIMP
+nsDocument::GetDOMBaseURI(nsAString &aURI)
+{
+  return nsIDocument::GetDOMBaseURI(aURI);
+}
+
+NS_IMETHODIMP
 nsDocument::GetTextContent(nsAString &aTextContent)
 {
   SetDOMStringToNull(aTextContent);
-}
-
-PRBool
-nsDocument::IsEqualNode(nsINode* aOther)
-{
-  if (!aOther || !aOther->IsNodeOfType(eDOCUMENT))
-    return PR_FALSE;
-
-  // Child nodes check.
-  PRUint32 childCount = GetChildCount();
-  if (childCount != aOther->GetChildCount()) {
-    return PR_FALSE;
-  }
-
-  for (PRUint32 i = 0; i < childCount; i++) {
-    if (!GetChildAt(i)->IsEqual(aOther->GetChildAt(i))) {
-      return PR_FALSE;
-    }
-  }
-
-  /* Checks not needed:  Prefix, namespace URI, local name, node name,
-     node value, attributes.
-   */
-
-  return PR_TRUE;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDocument::IsEqualNode(nsIDOMNode* aOther, PRBool* aResult)
+{
+  return nsINode::IsEqualNode(aOther, aResult);
+}
+
+NS_IMETHODIMP
+nsDocument::CompareDocumentPosition(nsIDOMNode *other,
+                                   PRUint16 *aResult)
+{
+  return nsINode::CompareDocumentPosition(other, aResult);
+}
+
+NS_IMETHODIMP
+nsDocument::SetTextContent(const nsAString & aTextContent)
+{
+  return nsINode::SetTextContent(aTextContent);
+}
+
+NS_IMETHODIMP
+nsDocument::IsSameNode(nsIDOMNode *other, PRBool *aResult)
+{
+  *aResult = other == this;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDocument::LookupPrefix(const nsAString & namespaceURI, nsAString & aResult)
+{
+  SetDOMStringToNull(aResult);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDocument::IsDefaultNamespace(const nsAString & namespaceURI,
+                              PRBool *aResult)
+{
+  *aResult = namespaceURI.IsEmpty();
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDocument::LookupNamespaceURI(const nsAString & prefix,
+                              nsAString & aResult)
+{
+  SetDOMStringToNull(aResult);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDocument::SetUserData(const nsAString & key,
+                       nsIVariant *data, nsIDOMUserDataHandler *handler,
+                       nsIVariant **aResult)
+{
+  return nsINode::SetUserData(key, data, handler, aResult);
+}
+
+NS_IMETHODIMP
+nsDocument::GetUserData(const nsAString & key,
+                        nsIVariant **aResult)
+{
+  return nsINode::GetUserData(key, aResult);
 }
 
 NS_IMETHODIMP
 nsDocument::GetInputEncoding(nsAString& aInputEncoding)
 {
   if (mHaveInputEncoding) {
     return GetCharacterSet(aInputEncoding);
   }
@@ -6867,16 +6930,17 @@ nsDocument::CreateElem(const nsAString& 
 
   *aResult = nsnull;
   
   PRInt32 elementType = aDocumentDefaultType ? mDefaultElementType :
     aNamespaceID;
 
   nsCOMPtr<nsINodeInfo> nodeInfo;
   mNodeInfoManager->GetNodeInfo(aName, aPrefix, aNamespaceID,
+                                nsIDOMNode::ELEMENT_NODE,
                                 getter_AddRefs(nodeInfo));
   NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
 
   return NS_NewElement(aResult, elementType, nodeInfo.forget(),
                        NOT_FROM_PARSER);
 }
 
 PRBool
--- a/content/base/src/nsDocument.h
+++ b/content/base/src/nsDocument.h
@@ -56,17 +56,16 @@
 #include "nsStubDocumentObserver.h"
 #include "nsIDOM3EventTarget.h"
 #include "nsIDOMNSEventTarget.h"
 #include "nsIDOMStyleSheetList.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsIDOMEventTarget.h"
 #include "nsIContent.h"
 #include "nsIEventListenerManager.h"
-#include "nsIDOM3Node.h"
 #include "nsIDOMNodeSelector.h"
 #include "nsIPrincipal.h"
 #include "nsIParser.h"
 #include "nsBindingManager.h"
 #include "nsINodeInfo.h"
 #include "nsHashtable.h"
 #include "nsInterfaceHashtable.h"
 #include "nsIBoxObject.h"
@@ -714,16 +713,18 @@ public:
   virtual void OnPageShow(PRBool aPersisted, nsIDOMEventTarget* aDispatchStartTarget);
   virtual void OnPageHide(PRBool aPersisted, nsIDOMEventTarget* aDispatchStartTarget);
   
   virtual void WillDispatchMutationEvent(nsINode* aTarget);
   virtual void MutationEventDispatched(nsINode* aTarget);
 
   // nsINode
   virtual PRBool IsNodeOfType(PRUint32 aFlags) const;
+  virtual PRUint16 NodeType();
+  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,
                                  PRBool aNotify);
   virtual nsresult AppendChildTo(nsIContent* aKid, PRBool aNotify);
   virtual nsresult RemoveChildAt(PRUint32 aIndex, PRBool aNotify);
@@ -741,18 +742,16 @@ public:
   virtual nsIScriptContext* GetContextForEventHandlers(nsresult* aRv)
   {
     return nsContentUtils::GetContextForEventHandlers(this, aRv);
   }
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const
   {
     return NS_ERROR_NOT_IMPLEMENTED;
   }
-  virtual PRBool IsEqualNode(nsINode* aOther);
-  virtual void GetTextContent(nsAString &aTextContent);
 
   // nsIRadioGroupContainer
   NS_IMETHOD WalkRadioGroup(const nsAString& aName,
                             nsIRadioVisitor* aVisitor,
                             PRBool aFlushContent);
   NS_IMETHOD SetCurrentRadioButton(const nsAString& aName,
                                    nsIDOMHTMLInputElement* aRadio);
   NS_IMETHOD GetCurrentRadioButton(const nsAString& aName,
--- a/content/base/src/nsDocumentEncoder.cpp
+++ b/content/base/src/nsDocumentEncoder.cpp
@@ -372,19 +372,17 @@ nsDocumentEncoder::SerializeNodeStart(ns
     mozilla::dom::Element* originalElement =
       aOriginalNode && aOriginalNode->IsElement() ?
         aOriginalNode->AsElement() : nsnull;
     mSerializer->AppendElementStart(node->AsElement(),
                                     originalElement, aStr);
     return NS_OK;
   }
 
-  PRUint16 type;
-  node->GetNodeType(&type);
-  switch (type) {
+  switch (node->NodeType()) {
     case nsIDOMNode::TEXT_NODE:
     {
       mSerializer->AppendText(static_cast<nsIContent*>(node),
                               aStartOffset, aEndOffset, aStr);
       break;
     }
     case nsIDOMNode::CDATA_SECTION_NODE:
     {
--- a/content/base/src/nsDocumentFragment.cpp
+++ b/content/base/src/nsDocumentFragment.cpp
@@ -45,90 +45,37 @@
 #include "nsGenericElement.h"
 #include "nsINameSpaceManager.h"
 #include "nsINodeInfo.h"
 #include "nsNodeInfoManager.h"
 #include "nsIDocument.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOMAttr.h"
 #include "nsDOMError.h"
-#include "nsIDOM3Node.h"
 #include "nsGkAtoms.h"
 #include "nsDOMString.h"
 #include "nsIDOMUserDataHandler.h"
 
 class nsDocumentFragment : public nsGenericElement,
                            public nsIDOMDocumentFragment
 {
 public:
-  nsDocumentFragment(already_AddRefed<nsINodeInfo> aNodeInfo);
-  virtual ~nsDocumentFragment();
-
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
+  // interface nsIDOMNode
+  NS_FORWARD_NSIDOMNODE(nsGenericElement::)
+
   // interface nsIDOMDocumentFragment