merging from cvs-trunk-mirror
authorjst@mozilla.com
Fri, 20 Jul 2007 14:18:36 -0700
changeset 3716 d7e93861f3f330b0411d1fc47babc60b5a5331a2
parent 3626 1dd3d4d3fe83076f2d1bfeb72c1c24154dc908ac (current diff)
parent 3715 84d34646101578f1d19bbb0256a2648eca11d457 (diff)
child 3717 0274c1b7e716dbf5e38c54c3f130881ac6972ad0
push id1
push userbsmedberg@mozilla.com
push dateThu, 20 Mar 2008 16:49:24 +0000
treeherdermozilla-central@61007906a1f8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone1.9a7pre
merging from cvs-trunk-mirror
client.mk
config/autoconf.mk.in
configure.in
intl/lwbrk/src/nsPangoLineBreaker.cpp
intl/lwbrk/src/nsPangoLineBreaker.h
widget/src/os2/resource.h
xpinstall/wizard/libxpnet/GUSI/README
xpinstall/wizard/libxpnet/GUSI/get_GUSI_source.txt
xpinstall/wizard/libxpnet/GUSI/include/GUSIBasics.h
xpinstall/wizard/libxpnet/GUSI/include/GUSIBuffer.h
xpinstall/wizard/libxpnet/GUSI/include/GUSIConfig.h
xpinstall/wizard/libxpnet/GUSI/include/GUSIContext.h
xpinstall/wizard/libxpnet/GUSI/include/GUSIContextQueue.h
xpinstall/wizard/libxpnet/GUSI/include/GUSIDCon.h
xpinstall/wizard/libxpnet/GUSI/include/GUSIDescriptor.h
xpinstall/wizard/libxpnet/GUSI/include/GUSIDevice.h
xpinstall/wizard/libxpnet/GUSI/include/GUSIDiag.h
xpinstall/wizard/libxpnet/GUSI/include/GUSIFSWrappers.h
xpinstall/wizard/libxpnet/GUSI/include/GUSIFactory.h
xpinstall/wizard/libxpnet/GUSI/include/GUSIFileSpec.h
xpinstall/wizard/libxpnet/GUSI/include/GUSIForeignThreads.h
xpinstall/wizard/libxpnet/GUSI/include/GUSIInet.h
xpinstall/wizard/libxpnet/GUSI/include/GUSIInternal.h
xpinstall/wizard/libxpnet/GUSI/include/GUSIMPW.h
xpinstall/wizard/libxpnet/GUSI/include/GUSIMSL.h
xpinstall/wizard/libxpnet/GUSI/include/GUSIMTInet.h
xpinstall/wizard/libxpnet/GUSI/include/GUSIMTNetDB.h
xpinstall/wizard/libxpnet/GUSI/include/GUSIMTTcp.h
xpinstall/wizard/libxpnet/GUSI/include/GUSIMTUdp.h
xpinstall/wizard/libxpnet/GUSI/include/GUSIMacFile.h
xpinstall/wizard/libxpnet/GUSI/include/GUSINetDB.h
xpinstall/wizard/libxpnet/GUSI/include/GUSINull.h
xpinstall/wizard/libxpnet/GUSI/include/GUSIOTInet.h
xpinstall/wizard/libxpnet/GUSI/include/GUSIOTNetDB.h
xpinstall/wizard/libxpnet/GUSI/include/GUSIOpenTransport.h
xpinstall/wizard/libxpnet/GUSI/include/GUSIPOSIX.h
xpinstall/wizard/libxpnet/GUSI/include/GUSIPPC.h
xpinstall/wizard/libxpnet/GUSI/include/GUSIPThread.h
xpinstall/wizard/libxpnet/GUSI/include/GUSIPipe.h
xpinstall/wizard/libxpnet/GUSI/include/GUSISIOUX.h
xpinstall/wizard/libxpnet/GUSI/include/GUSISIOW.h
xpinstall/wizard/libxpnet/GUSI/include/GUSISignal.h
xpinstall/wizard/libxpnet/GUSI/include/GUSISocket.h
xpinstall/wizard/libxpnet/GUSI/include/GUSISocketMixins.h
xpinstall/wizard/libxpnet/GUSI/include/GUSISpecific.h
xpinstall/wizard/libxpnet/GUSI/include/GUSITimer.h
xpinstall/wizard/libxpnet/GUSI/include/arpa/inet.h
xpinstall/wizard/libxpnet/GUSI/include/compat.h
xpinstall/wizard/libxpnet/GUSI/include/dirent.h
xpinstall/wizard/libxpnet/GUSI/include/errno.h
xpinstall/wizard/libxpnet/GUSI/include/fcntl.h
xpinstall/wizard/libxpnet/GUSI/include/inttypes.h
xpinstall/wizard/libxpnet/GUSI/include/machine/ansi.h
xpinstall/wizard/libxpnet/GUSI/include/machine/endian.h
xpinstall/wizard/libxpnet/GUSI/include/machine/signal.h
xpinstall/wizard/libxpnet/GUSI/include/net/if.h
xpinstall/wizard/libxpnet/GUSI/include/netdb.h
xpinstall/wizard/libxpnet/GUSI/include/netinet/in.h
xpinstall/wizard/libxpnet/GUSI/include/netinet/tcp.h
xpinstall/wizard/libxpnet/GUSI/include/pthread.h
xpinstall/wizard/libxpnet/GUSI/include/sched.h
xpinstall/wizard/libxpnet/GUSI/include/signal.h
xpinstall/wizard/libxpnet/GUSI/include/sys/cdefs.h
xpinstall/wizard/libxpnet/GUSI/include/sys/errno.h
xpinstall/wizard/libxpnet/GUSI/include/sys/filio.h
xpinstall/wizard/libxpnet/GUSI/include/sys/ioccom.h
xpinstall/wizard/libxpnet/GUSI/include/sys/ioctl.h
xpinstall/wizard/libxpnet/GUSI/include/sys/ppc.h
xpinstall/wizard/libxpnet/GUSI/include/sys/signal.h
xpinstall/wizard/libxpnet/GUSI/include/sys/socket.h
xpinstall/wizard/libxpnet/GUSI/include/sys/sockio.h
xpinstall/wizard/libxpnet/GUSI/include/sys/stat.h
xpinstall/wizard/libxpnet/GUSI/include/sys/time.h
xpinstall/wizard/libxpnet/GUSI/include/sys/ttycom.h
xpinstall/wizard/libxpnet/GUSI/include/sys/types.h
xpinstall/wizard/libxpnet/GUSI/include/sys/uio.h
xpinstall/wizard/libxpnet/GUSI/include/sys/un.h
xpinstall/wizard/libxpnet/GUSI/include/sys/unistd.h
xpinstall/wizard/libxpnet/GUSI/include/unistd.h
xpinstall/wizard/libxpnet/GUSI/include/utime.h
xpinstall/wizard/libxpnet/GUSI/lib/GUSI_Core.PPC.Lib
xpinstall/wizard/libxpnet/GUSI/lib/GUSI_ForeignThreads.PPC.Lib
xpinstall/wizard/libxpnet/GUSI/lib/GUSI_MPW.PPC.Lib
xpinstall/wizard/libxpnet/GUSI/lib/GUSI_MSL.PPC.Lib
xpinstall/wizard/libxpnet/GUSI/lib/GUSI_SIOUX.PPC.Lib
xpinstall/wizard/libxpnet/GUSI/lib/GUSI_Sfio.PPC.Lib
xpinstall/wizard/libxpnet/GUSI/test/GUSIConfig_MTINET.cp
xpinstall/wizard/libxpnet/Makefile.in
xpinstall/wizard/libxpnet/src/Makefile.in
xpinstall/wizard/libxpnet/src/nsFTPConn.cpp
xpinstall/wizard/libxpnet/src/nsFTPConn.h
xpinstall/wizard/libxpnet/src/nsHTTPConn.cpp
xpinstall/wizard/libxpnet/src/nsHTTPConn.h
xpinstall/wizard/libxpnet/src/nsSocket.cpp
xpinstall/wizard/libxpnet/src/nsSocket.h
xpinstall/wizard/libxpnet/test/Makefile.in
xpinstall/wizard/libxpnet/test/TestLibxpnet.cpp
xpinstall/wizard/mac/rsrc/MIWCommon.rsrc
xpinstall/wizard/mac/rsrc/MacInstallerVersion.r
xpinstall/wizard/mac/rsrc/Mozilla.rsrc
xpinstall/wizard/mac/src/AdditionsWin.c
xpinstall/wizard/mac/src/CheckboxLDEF.c
xpinstall/wizard/mac/src/CheckboxLDEF.h
xpinstall/wizard/mac/src/ComponentsWin.c
xpinstall/wizard/mac/src/Deflation.c
xpinstall/wizard/mac/src/EvtHandlers.c
xpinstall/wizard/mac/src/GreyButton.cp
xpinstall/wizard/mac/src/InstAction.c
xpinstall/wizard/mac/src/LicenseWin.c
xpinstall/wizard/mac/src/MacInstallWizard.c
xpinstall/wizard/mac/src/MacInstallWizard.h
xpinstall/wizard/mac/src/Parser.c
xpinstall/wizard/mac/src/SetupTypeWin.c
xpinstall/wizard/mac/src/TerminalWin.c
xpinstall/wizard/mac/src/WelcomeWin.c
xpinstall/wizard/mac/src/XPInstallGlue.c
xpinstall/wizard/mac/src/sdinst.h
xpinstall/wizard/os2/Makefile.in
xpinstall/wizard/os2/builder/build.pl
xpinstall/wizard/os2/nsinstall/Makefile.in
xpinstall/wizard/os2/nsinstall/nsINIParser.cpp
xpinstall/wizard/os2/nsinstall/nsINIParser.h
xpinstall/wizard/os2/nsinstall/resource.h
xpinstall/wizard/os2/nsinstall/stubinstall.cpp
xpinstall/wizard/os2/nsinstall/stubinstall.ico
xpinstall/wizard/os2/nsinstall/stubinstall.rc
xpinstall/wizard/os2/setup/Makefile.in
xpinstall/wizard/os2/setup/dialogs.c
xpinstall/wizard/os2/setup/dialogs.h
xpinstall/wizard/os2/setup/extern.h
xpinstall/wizard/os2/setup/extra.c
xpinstall/wizard/os2/setup/extra.h
xpinstall/wizard/os2/setup/ifuncns.c
xpinstall/wizard/os2/setup/ifuncns.h
xpinstall/wizard/os2/setup/logging.c
xpinstall/wizard/os2/setup/logging.h
xpinstall/wizard/os2/setup/nsEscape.cpp
xpinstall/wizard/os2/setup/nsEscape.h
xpinstall/wizard/os2/setup/nsINIParser.cpp
xpinstall/wizard/os2/setup/nsINIParser.h
xpinstall/wizard/os2/setup/resource.h
xpinstall/wizard/os2/setup/setup.c
xpinstall/wizard/os2/setup/setup.h
xpinstall/wizard/os2/setup/setup.ico
xpinstall/wizard/os2/setup/setup.ini
xpinstall/wizard/os2/setup/setup.rc
xpinstall/wizard/os2/setup/shortcut.h
xpinstall/wizard/os2/setup/winforos2.h
xpinstall/wizard/os2/setup/wizverreg.h
xpinstall/wizard/os2/setup/xperr.h
xpinstall/wizard/os2/setup/xpi.c
xpinstall/wizard/os2/setup/xpi.h
xpinstall/wizard/os2/setup/xpistub.h
xpinstall/wizard/os2/setup/xpnetHook.cpp
xpinstall/wizard/os2/setup/xpnetHook.h
xpinstall/wizard/os2/setup/zipfile.h
xpinstall/wizard/os2/setuprsc/Makefile.in
xpinstall/wizard/os2/setuprsc/bitmap1.bmp
xpinstall/wizard/os2/setuprsc/box_ch_d.bmp
xpinstall/wizard/os2/setuprsc/box_chec.bmp
xpinstall/wizard/os2/setuprsc/box_unch.bmp
xpinstall/wizard/os2/setuprsc/downloadLogo.bmp
xpinstall/wizard/os2/setuprsc/setup.ico
xpinstall/wizard/os2/setuprsc/setuprsc.cpp
xpinstall/wizard/os2/setuprsc/setuprsc.h
xpinstall/wizard/os2/setuprsc/setuprsc.rc
xpinstall/wizard/os2/test/Makefile.in
xpinstall/wizard/os2/test/test1.js
xpinstall/wizard/os2/test/test1.txt
xpinstall/wizard/os2/test/test2.js
xpinstall/wizard/os2/test/test2.txt
xpinstall/wizard/os2/test/testxpi.c
xpinstall/wizard/os2/test/testxpi.h
xpinstall/wizard/os2/test/xpi.c
xpinstall/wizard/os2/test/xpi.h
xpinstall/wizard/os2/uninstall/Makefile.in
xpinstall/wizard/os2/uninstall/dialogs.c
xpinstall/wizard/os2/uninstall/dialogs.h
xpinstall/wizard/os2/uninstall/extern.h
xpinstall/wizard/os2/uninstall/extra.c
xpinstall/wizard/os2/uninstall/extra.h
xpinstall/wizard/os2/uninstall/ifuncns.c
xpinstall/wizard/os2/uninstall/ifuncns.h
xpinstall/wizard/os2/uninstall/logkeys.h
xpinstall/wizard/os2/uninstall/nsINIParser.cpp
xpinstall/wizard/os2/uninstall/nsINIParser.h
xpinstall/wizard/os2/uninstall/parser.c
xpinstall/wizard/os2/uninstall/parser.h
xpinstall/wizard/os2/uninstall/rdi.c
xpinstall/wizard/os2/uninstall/rdi.h
xpinstall/wizard/os2/uninstall/resource.h
xpinstall/wizard/os2/uninstall/uninstall.c
xpinstall/wizard/os2/uninstall/uninstall.h
xpinstall/wizard/os2/uninstall/uninstall.ico
xpinstall/wizard/os2/uninstall/uninstall.rc
xpinstall/wizard/unix/Makefile.in
xpinstall/wizard/unix/src2/.LIBSREQD.list
xpinstall/wizard/unix/src2/MPL-1.1.txt
xpinstall/wizard/unix/src2/Makefile.in
xpinstall/wizard/unix/src2/README
xpinstall/wizard/unix/src2/XIDefines.h
xpinstall/wizard/unix/src2/XIErrors.h
xpinstall/wizard/unix/src2/check_off.xpm
xpinstall/wizard/unix/src2/check_on.xpm
xpinstall/wizard/unix/src2/config.ini
xpinstall/wizard/unix/src2/installer.ini
xpinstall/wizard/unix/src2/logo.xpm
xpinstall/wizard/unix/src2/mozilla-installer
xpinstall/wizard/unix/src2/nsComponent.cpp
xpinstall/wizard/unix/src2/nsComponent.h
xpinstall/wizard/unix/src2/nsComponentList.cpp
xpinstall/wizard/unix/src2/nsComponentList.h
xpinstall/wizard/unix/src2/nsComponentsDlg.cpp
xpinstall/wizard/unix/src2/nsComponentsDlg.h
xpinstall/wizard/unix/src2/nsINIParser.cpp
xpinstall/wizard/unix/src2/nsINIParser.h
xpinstall/wizard/unix/src2/nsInstallDlg.cpp
xpinstall/wizard/unix/src2/nsInstallDlg.h
xpinstall/wizard/unix/src2/nsLegacyCheck.cpp
xpinstall/wizard/unix/src2/nsLegacyCheck.h
xpinstall/wizard/unix/src2/nsLicenseDlg.cpp
xpinstall/wizard/unix/src2/nsLicenseDlg.h
xpinstall/wizard/unix/src2/nsObjectIgnore.cpp
xpinstall/wizard/unix/src2/nsObjectIgnore.h
xpinstall/wizard/unix/src2/nsRunApp.cpp
xpinstall/wizard/unix/src2/nsRunApp.h
xpinstall/wizard/unix/src2/nsSetupType.cpp
xpinstall/wizard/unix/src2/nsSetupType.h
xpinstall/wizard/unix/src2/nsSetupTypeDlg.cpp
xpinstall/wizard/unix/src2/nsSetupTypeDlg.h
xpinstall/wizard/unix/src2/nsWelcomeDlg.cpp
xpinstall/wizard/unix/src2/nsWelcomeDlg.h
xpinstall/wizard/unix/src2/nsXIContext.cpp
xpinstall/wizard/unix/src2/nsXIContext.h
xpinstall/wizard/unix/src2/nsXIEngine.cpp
xpinstall/wizard/unix/src2/nsXIEngine.h
xpinstall/wizard/unix/src2/nsXIOptions.cpp
xpinstall/wizard/unix/src2/nsXIOptions.h
xpinstall/wizard/unix/src2/nsXInstaller.cpp
xpinstall/wizard/unix/src2/nsXInstaller.h
xpinstall/wizard/unix/src2/nsXInstallerDlg.cpp
xpinstall/wizard/unix/src2/nsXInstallerDlg.h
xpinstall/wizard/unix/src2/nsZipExtractor.cpp
xpinstall/wizard/unix/src2/nsZipExtractor.h
xpinstall/wizard/windows/GetShortPathName/GetShortPathName.c
xpinstall/wizard/windows/GetShortPathName/Makefile.in
xpinstall/wizard/windows/Makefile.in
xpinstall/wizard/windows/builder/Makefile.in
xpinstall/wizard/windows/builder/build.pl
xpinstall/wizard/windows/builder/build_gre.pl
xpinstall/wizard/windows/builder/build_mfcembed.pl
xpinstall/wizard/windows/builder/build_static.pl
xpinstall/wizard/windows/builder/readme.txt
xpinstall/wizard/windows/ds32/Makefile.in
xpinstall/wizard/windows/ds32/ds32.cpp
xpinstall/wizard/windows/nsinstall/Makefile.in
xpinstall/wizard/windows/nsinstall/nsinstall.cpp
xpinstall/wizard/windows/nsinstall/nsinstall.ico
xpinstall/wizard/windows/nsinstall/nsinstall.rc
xpinstall/wizard/windows/nsinstall/resource.h
xpinstall/wizard/windows/nsztool/Makefile.in
xpinstall/wizard/windows/nsztool/nsztool.c
xpinstall/wizard/windows/nsztool/nsztool.h
xpinstall/wizard/windows/ren8dot3/Makefile.in
xpinstall/wizard/windows/ren8dot3/example.ini
xpinstall/wizard/windows/ren8dot3/ren8dot3.c
xpinstall/wizard/windows/setup/Makefile.in
xpinstall/wizard/windows/setup/dialogs.c
xpinstall/wizard/windows/setup/dialogs.h
xpinstall/wizard/windows/setup/extern.h
xpinstall/wizard/windows/setup/extra.c
xpinstall/wizard/windows/setup/extra.h
xpinstall/wizard/windows/setup/ifuncns.c
xpinstall/wizard/windows/setup/ifuncns.h
xpinstall/wizard/windows/setup/logging.c
xpinstall/wizard/windows/setup/logging.h
xpinstall/wizard/windows/setup/nsEscape.cpp
xpinstall/wizard/windows/setup/nsEscape.h
xpinstall/wizard/windows/setup/process.c
xpinstall/wizard/windows/setup/process.h
xpinstall/wizard/windows/setup/resource.h
xpinstall/wizard/windows/setup/setup.c
xpinstall/wizard/windows/setup/setup.h
xpinstall/wizard/windows/setup/setup.ico
xpinstall/wizard/windows/setup/setup.ini
xpinstall/wizard/windows/setup/setup.rc
xpinstall/wizard/windows/setup/shortcut.cpp
xpinstall/wizard/windows/setup/shortcut.h
xpinstall/wizard/windows/setup/supersede.c
xpinstall/wizard/windows/setup/supersede.h
xpinstall/wizard/windows/setup/version.c
xpinstall/wizard/windows/setup/version.h
xpinstall/wizard/windows/setup/wizverreg.h
xpinstall/wizard/windows/setup/xperr.h
xpinstall/wizard/windows/setup/xpi.c
xpinstall/wizard/windows/setup/xpi.h
xpinstall/wizard/windows/setup/xpistub.h
xpinstall/wizard/windows/setup/xpnetHook.cpp
xpinstall/wizard/windows/setup/xpnetHook.h
xpinstall/wizard/windows/setup/zipfile.h
xpinstall/wizard/windows/setuprsc/Makefile.in
xpinstall/wizard/windows/setuprsc/bitmap1.bmp
xpinstall/wizard/windows/setuprsc/box_ch_d.bmp
xpinstall/wizard/windows/setuprsc/box_chec.bmp
xpinstall/wizard/windows/setuprsc/box_unch.bmp
xpinstall/wizard/windows/setuprsc/downloadLogo.bmp
xpinstall/wizard/windows/setuprsc/setup.ico
xpinstall/wizard/windows/setuprsc/setuprsc.cpp
xpinstall/wizard/windows/setuprsc/setuprsc.h
xpinstall/wizard/windows/setuprsc/setuprsc.rc
xpinstall/wizard/windows/setuprsc/turbo-systray.bmp
xpinstall/wizard/windows/test/buildDelayRemove.bat
xpinstall/wizard/windows/test/delayRemove.c
xpinstall/wizard/windows/test/makefile.win
xpinstall/wizard/windows/test/test1.js
xpinstall/wizard/windows/test/test1.txt
xpinstall/wizard/windows/test/test2.js
xpinstall/wizard/windows/test/test2.txt
xpinstall/wizard/windows/test/testxpi.c
xpinstall/wizard/windows/test/testxpi.h
xpinstall/wizard/windows/test/xpi.c
xpinstall/wizard/windows/test/xpi.h
xpinstall/wizard/windows/uninstall/Makefile.in
xpinstall/wizard/windows/uninstall/dialogs.c
xpinstall/wizard/windows/uninstall/dialogs.h
xpinstall/wizard/windows/uninstall/extern.h
xpinstall/wizard/windows/uninstall/extra.c
xpinstall/wizard/windows/uninstall/extra.h
xpinstall/wizard/windows/uninstall/ifuncns.c
xpinstall/wizard/windows/uninstall/ifuncns.h
xpinstall/wizard/windows/uninstall/logkeys.h
xpinstall/wizard/windows/uninstall/parser.c
xpinstall/wizard/windows/uninstall/parser.h
xpinstall/wizard/windows/uninstall/process.c
xpinstall/wizard/windows/uninstall/process.h
xpinstall/wizard/windows/uninstall/rdi.c
xpinstall/wizard/windows/uninstall/rdi.h
xpinstall/wizard/windows/uninstall/resource.h
xpinstall/wizard/windows/uninstall/uninstall.c
xpinstall/wizard/windows/uninstall/uninstall.h
xpinstall/wizard/windows/uninstall/uninstall.ico
xpinstall/wizard/windows/uninstall/uninstall.rc
--- a/allmakefiles.sh
+++ b/allmakefiles.sh
@@ -638,29 +638,16 @@ xpcom/tests/windows/Makefile
 MAKEFILES_string="$MAKEFILES_xpcom"
 
 MAKEFILES_xpinstall="
 xpinstall/Makefile
 xpinstall/public/Makefile
 xpinstall/res/Makefile
 xpinstall/src/Makefile
 xpinstall/stub/Makefile
-xpinstall/wizard/libxpnet/Makefile
-xpinstall/wizard/libxpnet/src/Makefile
-xpinstall/wizard/libxpnet/test/Makefile
-xpinstall/wizard/unix/src2/Makefile
-xpinstall/wizard/windows/builder/Makefile
-xpinstall/wizard/windows/nsinstall/Makefile
-xpinstall/wizard/windows/nsztool/Makefile
-xpinstall/wizard/windows/uninstall/Makefile
-xpinstall/wizard/windows/setup/Makefile
-xpinstall/wizard/windows/setuprsc/Makefile
-xpinstall/wizard/windows/ren8dot3/Makefile
-xpinstall/wizard/windows/ds32/Makefile
-xpinstall/wizard/windows/GetShortPathName/Makefile
 "
 
 MAKEFILES_xpfe="
 widget/src/xremoteclient/Makefile
 toolkit/components/Makefile
 toolkit/components/remote/Makefile
 xpfe/Makefile
 xpfe/browser/Makefile
--- a/browser/app/Makefile.in
+++ b/browser/app/Makefile.in
@@ -67,17 +67,19 @@ DEFINES += -DAPP_UA_NAME="$(APP_UA_NAME)
 
 DIST_FILES = application.ini
 
 GRE_MILESTONE = $(shell $(PYTHON) $(topsrcdir)/config/printconfigsetting.py $(LIBXUL_DIST)/bin/platform.ini Build Milestone)
 GRE_BUILDID = $(shell $(PYTHON) $(topsrcdir)/config/printconfigsetting.py $(LIBXUL_DIST)/bin/platform.ini Build BuildID)
 
 DEFINES += -DGRE_MILESTONE=$(GRE_MILESTONE) -DGRE_BUILDID=$(GRE_BUILDID)
 
-ifndef LIBXUL_SDK
+ifdef LIBXUL_SDK
+include $(topsrcdir)/config/rules.mk
+else
 # Build a binary bootstrapping with XRE_main
 
 ifeq ($(USE_SHORT_LIBNAME), 1)
 PROGRAM = $(MOZ_APP_NAME)$(BIN_SUFFIX)
 else
 PROGRAM = $(MOZ_APP_NAME)-bin$(BIN_SUFFIX)
 endif
 
--- a/browser/app/macbuild/Contents/Info.plist.in
+++ b/browser/app/macbuild/Contents/Info.plist.in
@@ -116,24 +116,16 @@
 			<string>ftp URL</string>
 			<key>CFBundleURLSchemes</key>
 			<array>
 				<string>ftp</string>
 			</array>
 		</dict>
 		<dict>
 			<key>CFBundleURLName</key>
-			<string>gopher URL</string>
-			<key>CFBundleURLSchemes</key>
-			<array>
-				<string>gopher</string>
-			</array>
-		</dict>
-		<dict>
-			<key>CFBundleURLName</key>
 			<string>file URL</string>
 			<key>CFBundleURLSchemes</key>
 			<array>
 				<string>file</string>
 			</array>
 		</dict>
 	</array>
 	<key>CFBundleVersion</key>
--- a/browser/components/nsBrowserContentHandler.js
+++ b/browser/components/nsBrowserContentHandler.js
@@ -588,26 +588,19 @@ var nsBrowserContentHandler = {
                                  .getService(nsIWebNavigationInfo);
       if (!webNavInfo.isTypeSupported(contentType, null)) {
         throw NS_ERROR_WONT_HANDLE_CONTENT;
       }
     } catch (e) {
       throw NS_ERROR_WONT_HANDLE_CONTENT;
     }
 
-    var parentWin;
-    try {
-      parentWin = context.getInterface(nsIDOMWindow);
-    }
-    catch (e) {
-    }
-
     request.QueryInterface(nsIChannel);
-    
-    openWindow(parentWin, request.URI, "_blank", null, null);
+    handURIToExistingBrowser(request.URI,
+      nsIBrowserDOMWindow.OPEN_DEFAULTWINDOW, null);
     request.cancel(NS_BINDING_ABORTED);
   },
 
   /* nsICommandLineValidator */
   validate : function bch_validate(cmdLine) {
     // Other handlers may use osint so only handle the osint flag if the url
     // flag is also present and the command line is valid.
     var osintFlagIdx = cmdLine.findFlag("osint", false);
--- a/browser/components/places/content/controller.js
+++ b/browser/components/places/content/controller.js
@@ -1240,18 +1240,18 @@ PlacesController.prototype = {
                                                uri) + suffix);
         htmlString += (PlacesUtils.wrapNode(node, PlacesUtils.TYPE_HTML,
                                                uri) + suffix);
         
         var placeSuffix = i < (nodes.length - 1) ? "," : "";
         return PlacesUtils.wrapNode(node, type, overrideURI) + placeSuffix;
       }
 
-        // all items wrapped as TYPE_X_MOZ_PLACE
-        placeString += generateChunk(PlacesUtils.TYPE_X_MOZ_PLACE);
+      // all items wrapped as TYPE_X_MOZ_PLACE
+      placeString += generateChunk(PlacesUtils.TYPE_X_MOZ_PLACE);
     }
 
     function addData(type, data) {
       xferable.addDataFlavor(type);
       xferable.setTransferData(type, PlacesUtils._wrapString(data), data.length * 2);
     }
     // This order is _important_! It controls how this and other applications 
     // select data to be inserted based on type.
@@ -1341,17 +1341,17 @@ PlacesController.prototype = {
         }
         return transactions;
       }
       catch (e) {
         // getAnyTransferData will throw if there is no data of the specified
         // type on the clipboard. 
         // unwrapNodes will throw if the data that is present is malformed in
         // some way. 
-        // In either case, don't fail horribly, just return no data. 
+        // In either case, don't fail horribly, just return no data.
       }
       return [];
     }
 
     // Get transactions to paste any folders, separators or links that might
     // be on the clipboard, aggregate them and execute them. 
     var transactions = getTransactions([PlacesUtils.TYPE_X_MOZ_PLACE,
                                         PlacesUtils.TYPE_X_MOZ_URL, 
--- a/browser/components/places/content/utils.js
+++ b/browser/components/places/content/utils.js
@@ -451,31 +451,31 @@ var PlacesUtils = {
    * @param   [optional] aOverrideURI
    *          Used instead of the node's URI if provided.
    *          This is useful for wrapping a container as TYPE_X_MOZ_URL,
    *          TYPE_HTML or TYPE_UNICODE.
    * @returns A string serialization of the node
    */
   wrapNode: function PU_wrapNode(aNode, aType, aOverrideURI) {
     var self = this;
-    
+
     // when wrapping a node, we want all the items, even if the original
     // query options are excluding them.
     // this can happen when copying from the left hand pane of the bookmarks
     // organizer
     function convertNode(cNode) {
       try {
         if (self.nodeIsFolder(cNode) && cNode.queryOptions.excludeItems)
           return self.getFolderContents(cNode.itemId, false, true).root;
       }
       catch (e) {
       }
       return cNode;
     }
-    
+
     switch (aType) {
       case this.TYPE_X_MOZ_PLACE:
       case this.TYPE_X_MOZ_PLACE_SEPARATOR:
       case this.TYPE_X_MOZ_PLACE_CONTAINER:
         function gatherDataPlace(bNode) {
           var nodeId = 0;
           if (bNode.itemId != -1)
             nodeId = bNode.itemId;
@@ -489,28 +489,29 @@ var PlacesUtils = {
           var nodeAnnos = self.getAnnotationsForItem(bNode.itemId);
           var nodeType = "";
           if (self.nodeIsContainer(bNode))
             nodeType = self.TYPE_X_MOZ_PLACE_CONTAINER;
           else if (self.nodeIsURI(bNode)) // a bookmark or a history visit
             nodeType = self.TYPE_X_MOZ_PLACE;
           else if (self.nodeIsSeparator(bNode))
             nodeType = self.TYPE_X_MOZ_PLACE_SEPARATOR;
-            
+
           var node = { id: nodeId,
                        uri: nodeUri,
                        title: nodeTitle,
                        parent: nodeParentId,
                        index: nodeIndex,
                        keyword: nodeKeyword,
                        annos: nodeAnnos,
                        type: nodeType };
-          
+
           // Recurse down children if the node is a folder
           if (self.nodeIsContainer(bNode)) {
+            asContainer(bNode);
             if (self.nodeIsLivemarkContainer(bNode)) {
               // just save the livemark info, reinstantiate on other end
               var feedURI = self.livemarks.getFeedURI(bNode.itemId).spec;
               var siteURI = self.livemarks.getSiteURI(bNode.itemId).spec;
               node.uri = { feed: feedURI,
                            site: siteURI };
             }
             else { // bookmark folders + history containers
@@ -529,95 +530,94 @@ var PlacesUtils = {
                        children: childNodes,
                        type: self.TYPE_X_MOZ_PLACE_CONTAINER };
               bNode.containerOpen = wasOpen;
             }
           } 
           return node;
         }
         return this.toJSONString(gatherDataPlace(convertNode(aNode)));
-        
+
       case this.TYPE_X_MOZ_URL:
         function gatherDataUrl(bNode) {
           if (self.nodeIsLivemarkContainer(bNode)) {
             var siteURI = self.livemarks.getSiteURI(bNode.itemId).spec;
             return siteURI + "\n" + bNode.title;
           }
-          else if (self.nodeIsURI(bNode))
+          if (self.nodeIsURI(bNode))
             return (aOverrideURI || bNode.uri) + "\n" + bNode.title;
-          else // ignore containers and separators - items without valid URIs
-            return "";
+          // ignore containers and separators - items without valid URIs
+          return "";
         }
         return gatherDataUrl(convertNode(aNode));
-        
+
       case this.TYPE_HTML:
         function gatherDataHtml(bNode) {
           function htmlEscape(s) {
             s = s.replace(/&/g, "&amp;");
             s = s.replace(/>/g, "&gt;");
             s = s.replace(/</g, "&lt;");
             s = s.replace(/"/g, "&quot;");
             s = s.replace(/'/g, "&apos;");
             return s;
           }
           // escape out potential HTML in the title
           var escapedTitle = htmlEscape(bNode.title);
           if (self.nodeIsLivemarkContainer(bNode)) {
             var siteURI = self.livemarks.getSiteURI(bNode.itemId).spec;
             return "<A HREF=\"" + siteURI + "\">" + escapedTitle + "</A>\n";
           }
-          else if (self.nodeIsContainer(bNode)) {
+          if (self.nodeIsContainer(bNode)) {
+            asContainer(bNode);
             var wasOpen = bNode.containerOpen;
             if (!wasOpen)
               bNode.containerOpen = true;
-            
+
             var childString = "<DL><DT>" + escapedTitle + "</DT>\n";
             var cc = bNode.childCount;
             for (var i = 0; i < cc; ++i)
               childString += "<DD>\n"
                              + gatherDataHtml(bNode.getChild(i))
                              + "</DD>\n";
             bNode.containerOpen = wasOpen;
             return childString + "</DL>\n";
           }
-          else if (self.nodeIsURI(bNode))
+          if (self.nodeIsURI(bNode))
             return "<A HREF=\"" + bNode.uri + "\">" + escapedTitle + "</A>\n";
-          else if (self.nodeIsSeparator(bNode))
+          if (self.nodeIsSeparator(bNode))
             return "<HR>\n";
-          else
-            return "";
+          return "";
         }
         return gatherDataHtml(convertNode(aNode));
     }
     // case this.TYPE_UNICODE:
     function gatherDataText(bNode) {
-      if (self.nodeIsLivemarkContainer(bNode)) {
+      if (self.nodeIsLivemarkContainer(bNode))
         return self.livemarks.getSiteURI(bNode.itemId).spec;
-      }
-      else if (self.nodeIsContainer(bNode)) {
+      if (self.nodeIsContainer(bNode)) {
+        asContainer(bNode);
         var wasOpen = bNode.containerOpen;
         if (!wasOpen)
           bNode.containerOpen = true;
           
         var childString = bNode.title + "\n";
         var cc = bNode.childCount;
         for (var i = 0; i < cc; ++i) {
           var child = bNode.getChild(i);
           var suffix = i < (cc - 1) ? "\n" : "";
           childString += gatherDataText(child) + suffix;
         }
         bNode.containerOpen = wasOpen;
         return childString;
       }
-      else if (self.nodeIsURI(bNode))
+      if (self.nodeIsURI(bNode))
         return (aOverrideURI || bNode.uri);
-      else if (self.nodeIsSeparator(bNode))
+      if (self.nodeIsSeparator(bNode))
         return "--------------------";
-      else
-        return "";
+      return "";
     }
 
     return gatherDataText(convertNode(aNode));
   },
 
   /**
    * Get a transaction for copying a uri item from one container to another
    * as a bookmark.
@@ -695,28 +695,28 @@ var PlacesUtils = {
           index = aIndex + i;
           
         if (node.type == self.TYPE_X_MOZ_PLACE_CONTAINER) {
           if (node.folder) {
             var title = node.folder.title;
             var annos = node.folder.annos;
             var folderItemsTransactions =
               getChildItemsTransactions(node.children);
-            txn = this.ptm.createFolder(title, -1, aIndex, annos,
+            txn = self.ptm.createFolder(title, -1, index, annos,
                                         folderItemsTransactions);
           }
           else { // node is a livemark
             var feedURI = self._uri(node.uri.feed);
             var siteURI = self._uri(node.uri.site);
-            txn = this.ptm.createLivemark(feedURI, siteURI, node.title,
+            txn = self.ptm.createLivemark(feedURI, siteURI, node.title,
                                           aContainer, index, node.annos);
           }
         }
         else if (node.type == self.TYPE_X_MOZ_PLACE_SEPARATOR)
-          txn = this.ptm.createSeparator(-1, aIndex);
+          txn = self.ptm.createSeparator(-1, index);
         else if (node.type == self.TYPE_X_MOZ_PLACE)
           txn = self._getBookmarkItemCopyTransaction(node, -1, index);
 
         NS_ASSERT(txn, "Unexpected item under a bookmarks folder");
         if (txn)
           childItemsTransactions.push(txn);
       }
       return childItemsTransactions;
--- a/browser/fuel/src/fuelApplication.js
+++ b/browser/fuel/src/fuelApplication.js
@@ -33,16 +33,18 @@
  * 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 ***** */
 
 const Ci = Components.interfaces;
 const Cc = Components.classes;
 
+Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+
 //=================================================
 // Shutdown - used to store cleanup functions which will
 //            be called on Application shutdown
 var gShutdown = [];
 
 //=================================================
 // Console constructor
 function Console() {
@@ -65,17 +67,19 @@ Console.prototype = {
       var wWatch = Components.classes["@mozilla.org/embedcomp/window-watcher;1"]
                              .getService(Ci.nsIWindowWatcher);
       wWatch.openWindow(null, "chrome://global/content/console.xul", "_blank",
                         "chrome,dialog=no,all", cmdLine);
     } else {
       // console was already open
       console.focus();
     }
-  }
+  },
+  
+  QueryInterface : XPCOMUtils.generateQI([Ci.fuelIConsole])
 };
 
 
 //=================================================
 // EventItem constructor
 function EventItem(aType, aData) {
   this._type = aType;
   this._data = aData;
@@ -91,17 +95,19 @@ EventItem.prototype = {
   },
   
   get data() {
     return this._data;
   },
   
   preventDefault : function ei_pd() {
     this._cancel = true;
-  }
+  },
+  
+  QueryInterface : XPCOMUtils.generateQI([Ci.fuelIEventItem])
 };
 
 
 //=================================================
 // Events constructor
 function Events() {
   this._listeners = [];
 }
@@ -136,17 +142,19 @@ Events.prototype = {
       if (key.event == aEvent) {
         key.listener.handleEvent ?
           key.listener.handleEvent(eventItem) :
           key.listener(eventItem);
       }
     });
     
     return !eventItem._cancel;
-  }
+  },
+  
+  QueryInterface : XPCOMUtils.generateQI([Ci.fuelIEvents])
 };
 
 
 //=================================================
 // PreferenceBranch constructor
 function PreferenceBranch(aBranch) {
   if (!aBranch)
     aBranch = "";
@@ -156,17 +164,18 @@ function PreferenceBranch(aBranch) {
                           .getService(Ci.nsIPrefService);
 
   if (aBranch)
     this._prefs = this._prefs.getBranch(aBranch);
     
   this._prefs.QueryInterface(Ci.nsIPrefBranch);
   this._prefs.QueryInterface(Ci.nsIPrefBranch2);
   
-  this._prefs.addObserver(this._root, this, false);
+  // we want to listen to "all" changes for this branch, so pass in a blank domain
+  this._prefs.addObserver("", this, true);
   this._events = new Events();
   
   var self = this;
   gShutdown.push(function() { self._shutdown(); });
 }
 
 //=================================================
 // PreferenceBranch implementation
@@ -258,17 +267,19 @@ PreferenceBranch.prototype = {
         break;
       default:
         throw("Unknown preference value specified.");
     }
   },
   
   reset : function prefs_reset() {
     this._prefs.resetBranch("");
-  }
+  },
+  
+  QueryInterface : XPCOMUtils.generateQI([Ci.fuelIPreferenceBranch, Ci.nsISupportsWeakReference])
 };
 
 
 //=================================================
 // Preference constructor
 function Preference(aName, aBranch) {
   this._name = aName;
   this._branch = aBranch;
@@ -333,17 +344,19 @@ Preference.prototype = {
   },
   
   get events() {
     return this._events;
   },
   
   reset : function pref_reset() {
     this.branch._prefs.clearUserPref(this.name);
-  }
+  },
+  
+  QueryInterface : XPCOMUtils.generateQI([Ci.fuelIPreference])
 };
 
 
 //=================================================
 // SessionStorage constructor
 function SessionStorage() {
   this._storage = {};
   this._events = new Events();
@@ -362,17 +375,19 @@ SessionStorage.prototype = {
   
   set : function ss_set(aName, aValue) {
     this._storage[aName] = aValue;
     this._events.dispatch("change", aName);
   },
   
   get : function ss_get(aName, aDefaultValue) {
     return this.has(aName) ? this._storage[aName] : aDefaultValue;
-  }
+  },
+  
+  QueryInterface : XPCOMUtils.generateQI([Ci.fuelISessionStorage])
 };
 
 
 //=================================================
 // Extension constructor
 function Extension(aItem) {
   this._item = aItem;
   this._firstRun = false;
@@ -447,17 +462,19 @@ Extension.prototype = {
   },
   
   get prefs() {
     return this._prefs;
   },
   
   get events() {
     return this._events;
-  }
+  },
+  
+  QueryInterface : XPCOMUtils.generateQI([Ci.fuelIExtension])
 };
 
 
 //=================================================
 // Extensions constructor
 function Extensions() {
   this._extmgr = Components.classes["@mozilla.org/extensions/manager;1"]
                            .getService(Ci.nsIExtensionManager);
@@ -513,17 +530,19 @@ Extensions.prototype = {
     // getItemForID never returns null for a non-existent id, so we
     // check the type of the returned update item, which should be
     // greater than 1 for a valid extension.
     return !!(this._extmgr.getItemForID(aId).type);
   },
   
   get : function exts_get(aId) {
     return this.has(aId) ? this._get(aId) : null;
-  }
+  },
+  
+  QueryInterface : XPCOMUtils.generateQI([Ci.fuelIExtensions])
 };
 
 //=================================================
 // Singleton that holds services and utilities
 var Utilities = {
   _bookmarks : null,
   get bookmarks() {
     if (!this._bookmarks) {
@@ -607,27 +626,27 @@ Window.prototype = {
   get events() {
     return this._events;
   },
 
   /*
    * Helper used to setup event handlers on the XBL element. Note that the events
    * are actually dispatched to tabs, so we capture them.
    */
-  _watch : function(aType) {
+  _watch : function win_watch(aType) {
     var self = this;
     this._tabbrowser.addEventListener(aType, 
       this._cleanup[aType] = function(e){ self._event(e); },
       true);
   },
   
   /*
    * Helper event callback used to redirect events made on the XBL element
    */
-  _event : function(aEvent) {
+  _event : function win_event(aEvent) {
     this._events.dispatch(aEvent.type, "");
   },
   
   get tabs() {
     var tabs = [];
     var browsers = this._tabbrowser.browsers;
     
     for (var i=0; i<browsers.length; i++)
@@ -635,29 +654,31 @@ Window.prototype = {
     
     return tabs;
   },
   
   get activeTab() {
     return new BrowserTab(this._window, this._tabbrowser.selectedBrowser);
   },
   
-  open : function(aURI) {
+  open : function win_open(aURI) {
     return new BrowserTab(this._window, this._tabbrowser.addTab(aURI.spec).linkedBrowser);
   },
   
-  _shutdown : function() {
+  _shutdown : function win_shutdown() {
     for (var type in this._cleanup)
       this._tabbrowser.removeEventListener(type, this._cleanup[type], true);
     this._cleanup = null;
 
     this._window = null;
     this._tabbrowser = null;
     this._events = null;
-  }
+  },
+  
+  QueryInterface : XPCOMUtils.generateQI([Ci.fuelIWindow])
 };
 
 
 //=================================================
 // BrowserTab implementation
 function BrowserTab(aWindow, aBrowser) {
   this._window = aWindow;
   this._tabbrowser = aWindow.getBrowser();
@@ -695,103 +716,112 @@ BrowserTab.prototype = {
   
   get document() {
     return this._browser.contentDocument;
   },
   
   /*
    * Helper used to setup event handlers on the XBL element
    */
-  _watch : function(aType) {
+  _watch : function bt_watch(aType) {
     var self = this;
     this._browser.addEventListener(aType,
       this._cleanup[aType] = function(e){ self._event(e); },
       true);
   },
   
   /*
    * Helper event callback used to redirect events made on the XBL element
    */
-  _event : function(aEvent) {
-    if (aEvent.type == "load" && (!aEvent.originalTarget instanceof Ci.nsIDOMHTMLDocument ||
-      aEvent.originalTarget.defaultView.frameElement))
-      return;
+  _event : function bt_event(aEvent) {
+    if (aEvent.type == "load") {
+      if (!(aEvent.originalTarget instanceof Ci.nsIDOMHTMLDocument))
+        return;
+        
+      if (aEvent.originalTarget.defaultView instanceof Ci.nsIDOMWindowInternal &&
+          aEvent.originalTarget.defaultView.frameElement)
+        return;
+    }
       
     this._events.dispatch(aEvent.type, "");
   },
   
   /*
    * Helper used to determine the index offset of the browsertab
    */
-  _getTab : function() {
+  _getTab : function bt_gettab() {
     var tabs = this._tabbrowser.mTabs;
     return tabs[this.index] || null;
   },
   
-  load : function(aURI) {
+  load : function bt_load(aURI) {
     this._browser.loadURI(aURI.spec, null, null);
   },
   
-  focus : function() {
+  focus : function bt_focus() {
     this._tabbrowser.selectedTab = this._getTab();
     this._tabbrowser.focus();
   },
   
-  close : function() {
+  close : function bt_close() {
     this._tabbrowser.removeTab(this._getTab());
   },
   
-  moveBefore : function(aBefore) {
+  moveBefore : function bt_movebefore(aBefore) {
     this._tabbrowser.moveTabTo(this._getTab(), aBefore.index);
   },
   
-  moveToEnd : function() {
+  moveToEnd : function bt_moveend() {
     this._tabbrowser.moveTabTo(this._getTab(), this._tabbrowser.browsers.length);
   },
   
-  _shutdown : function() {
+  _shutdown : function bt_shutdown() {
     for (var type in this._cleanup)
       this._browser.removeEventListener(type, this._cleanup[type], true);
     this._cleanup = null;
     
     this._window = null;
     this._tabbrowser = null;
     this._browser = null;
     this._events = null;
-  }
+  },
+  
+  QueryInterface : XPCOMUtils.generateQI([Ci.fuelIBrowserTab])
 };
 
 
 //=================================================
 // Annotations implementation
 function Annotations(aId) {
   this._id = aId;
 }
 
 Annotations.prototype = {
   get names() {
     return Utilities.annotations.getItemAnnotationNames(this._id, {});
   },
   
-  has : function(aName) {
+  has : function ann_has(aName) {
     return Utilities.annotations.itemHasAnnotation(this._id, aName);
   },
   
   get : function(aName) {
     return Utilities.annotations.getItemAnnotation(this._id, aName);
   },
   
   set : function(aName, aValue, aExpiration) {
     Utilities.annotations.setItemAnnotation(this._id, aName, aValue, 0, aExpiration);
   },
     
-  remove : function(aName) {
+  remove : function ann_remove(aName) {
     if (aName)
       Utilities.annotations.removeItemAnnotation(this._id, aName);
-  }
+  },
+  
+  QueryInterface : XPCOMUtils.generateQI([Ci.fuelIAnnotations])
 };
 
 
 //=================================================
 // Bookmark implementation
 function Bookmark(aId, aParent, aType) {
   this._id = aId;
   this._parent = aParent;
@@ -801,17 +831,17 @@ function Bookmark(aId, aParent, aType) {
 
   Utilities.bookmarks.addObserver(this, false);  
                                  
   var self = this;
   gShutdown.push(function() { self._shutdown(); });
 }
 
 Bookmark.prototype = {
-  _shutdown : function() {
+  _shutdown : function bm_shutdown() {
     this._annotations = null;
     this._events = null;
     
     Utilities.bookmarks.removeObserver(this);  
   },
   
   get id() {
     return this._id;
@@ -865,59 +895,52 @@ Bookmark.prototype = {
   get annotations() {
     return this._annotations;
   },
   
   get events() {
     return this._events;
   },
   
-  remove : function() {
+  remove : function bm_remove() {
     Utilities.bookmarks.removeItem(this._id);
   },
   
   // observer
-  onBeginUpdateBatch : function() {
+  onBeginUpdateBatch : function bm_obub() {
   },
 
-  onEndUpdateBatch : function() {
+  onEndUpdateBatch : function bm_oeub() {
   },
 
-  onItemAdded : function(aId, aFolder, aIndex) {
+  onItemAdded : function bm_oia(aId, aFolder, aIndex) {
     // bookmark object doesn't exist at this point
   },
 
-  onItemRemoved : function(aId, aFolder, aIndex) {
+  onItemRemoved : function bm_oir(aId, aFolder, aIndex) {
     if (this._id == aId)
       this._events.dispatch("remove", aId);
   },
 
-  onItemChanged : function(aId, aProperty, aIsAnnotationProperty, aValue) {
+  onItemChanged : function bm_oic(aId, aProperty, aIsAnnotationProperty, aValue) {
     if (this._id == aId)
       this._events.dispatch("change", aProperty);
   },
 
-  onItemVisited: function(aId, aVisitID, aTime) {
+  onItemVisited: function bm_oiv(aId, aVisitID, aTime) {
   },
 
-  onItemMoved: function(aId, aOldParent, aOldIndex, aNewParent, aNewIndex) {
+  onItemMoved: function bm_oim(aId, aOldParent, aOldIndex, aNewParent, aNewIndex) {
     if (this._id == aId) {
       this._parent = new BookmarkFolder(aNewParent, Utilities.bookmarks.getFolderIdForItem(aNewParent));    
       this._events.dispatch("move", aId);
     }
   },
 
-  QueryInterface: function(aIID) {
-    if (aIID.equals(Ci.fuelIBookmark) ||
-        aIID.equals(Ci.nsINavBookmarkObserver) ||
-        aIID.equals(Ci.nsISupports)) {
-      return this;
-    }
-    throw Component.result.NS_ERROR_NO_INTERFACE;
-  }
+  QueryInterface : XPCOMUtils.generateQI([Ci.fuelIBookmark, Ci.nsINavBookmarkObserver])
 }; 
 
 
 //=================================================
 // BookmarkFolder implementation
 function BookmarkFolder(aId, aParent) {
   this._id = aId;
   if (this._id == null)
@@ -930,17 +953,17 @@ function BookmarkFolder(aId, aParent) {
 
   Utilities.bookmarks.addObserver(this, false);  
 
   var self = this;
   gShutdown.push(function() { self._shutdown(); });
 }
 
 BookmarkFolder.prototype = {
-  _shutdown : function() {
+  _shutdown : function bmf_shutdown() {
     this._annotations = null;
     this._events = null;
     
     Utilities.bookmarks.removeObserver(this);  
   },
   
   get id() {
     return this._id;
@@ -1008,90 +1031,83 @@ BookmarkFolder.prototype = {
         items.push(bookmark);
       }
     }
     rootNode.containerOpen = false;
 
     return items;
   },
   
-  addBookmark : function(aTitle, aUri) {
+  addBookmark : function bmf_addbm(aTitle, aUri) {
     var newBookmarkID = Utilities.bookmarks.insertBookmark(this._id, aUri, Utilities.bookmarks.DEFAULT_INDEX, aTitle);
     var newBookmark = new Bookmark(newBookmarkID, this, "bookmark");
     return newBookmark;
   },
   
-  addSeparator : function() {
+  addSeparator : function bmf_addsep() {
     var newBookmarkID = Utilities.bookmarks.insertSeparator(this._id, Utilities.bookmarks.DEFAULT_INDEX);
     var newBookmark = new Bookmark(newBookmarkID, this, "separator");
     return newBookmark;
   },
   
-  addFolder : function(aTitle) {
+  addFolder : function bmf_addfolder(aTitle) {
     var newFolderID = Utilities.bookmarks.createFolder(this._id, aTitle, Utilities.bookmarks.DEFAULT_INDEX);
     var newFolder = new BookmarkFolder(newFolderID, this);
     return newFolder;
   },
   
-  remove : function() {
+  remove : function bmf_remove() {
     Utilities.bookmarks.removeFolder(this._id);
   },
   
   // observer
-  onBeginUpdateBatch : function() {
+  onBeginUpdateBatch : function bmf_obub() {
   },
 
-  onEndUpdateBatch : function() {
+  onEndUpdateBatch : function bmf_oeub() {
   },
 
-  onItemAdded : function(aId, aFolder, aIndex) {
+  onItemAdded : function bmf_oia(aId, aFolder, aIndex) {
     // handle root folder events
     if (!this._parent)
       this._events.dispatch("add", aId);
     
     // handle this folder events  
     if (this._id == aFolder)
       this._events.dispatch("addchild", aId);
   },
 
-  onItemRemoved : function(aId, aFolder, aIndex) {
+  onItemRemoved : function bmf_oir(aId, aFolder, aIndex) {
     // handle root folder events
     if (!this._parent || this._id == aId)
       this._events.dispatch("remove", aId);
 
     // handle this folder events      
     if (this._id == aFolder)
       this._events.dispatch("removechild", aId);
   },
 
-  onItemChanged : function(aId, aProperty, aIsAnnotationProperty, aValue) {
+  onItemChanged : function bmf_oic(aId, aProperty, aIsAnnotationProperty, aValue) {
     // handle root folder and this folder events
     if (!this._parent || this._id == aId)
       this._events.dispatch("change", aProperty);
   },
 
-  onItemVisited: function(aId, aVisitID, aTime) {
+  onItemVisited: function bmf_oiv(aId, aVisitID, aTime) {
   },
 
-  onItemMoved: function(aId, aOldParent, aOldIndex, aNewParent, aNewIndex) {
+  onItemMoved: function bmf_oim(aId, aOldParent, aOldIndex, aNewParent, aNewIndex) {
     // handle this folder event, root folder cannot be moved
     if (this._id == aId) {
       this._parent = new BookmarkFolder(aNewParent, Utilities.bookmarks.getFolderIdForItem(aNewParent));    
       this._events.dispatch("move", aId);
     }
   },
 
-  QueryInterface: function(aIID) {
-    if (aIID.equals(Ci.fuelIBookmarkFolder) ||
-        aIID.equals(Ci.nsINavBookmarkObserver) ||
-        aIID.equals(Ci.nsISupports)) {
-      return this;
-    }
-    throw Component.result.NS_ERROR_NO_INTERFACE;
-  }
+  QueryInterface : XPCOMUtils.generateQI([Ci.fuelIBookmarkFolder, Ci.nsINavBookmarkObserver])
 }; 
 
 
 const CLASS_ID = Components.ID("fe74cf80-aa2d-11db-abbd-0800200c9a66");
 const CLASS_NAME = "Application wrapper";
 const CONTRACT_ID = "@mozilla.org/fuel/application;1";
 
 //=================================================
@@ -1190,27 +1206,17 @@ Application.prototype = {
     return interfaces;
   },
 
   getHelperForLanguage : function app_ghfl(aCount) {
     return null;
   },
   
   // for nsISupports
-  QueryInterface: function app_qi(aIID) {
-    // add any other interfaces you support here
-    if (aIID.equals(Ci.fuelIApplication) ||
-        aIID.equals(Ci.nsIObserver) ||
-        aIID.equals(Ci.nsIClassInfo) ||
-        aIID.equals(Ci.nsISupports))
-    {
-      return this;
-    }
-    throw Components.results.NS_ERROR_NO_INTERFACE;
-  },
+  QueryInterface : XPCOMUtils.generateQI([Ci.fuelIApplication, Ci.nsIObserver, Ci.nsIClassInfo]),
   
   get console() {
     if (this._console == null)
         this._console = new Console();
 
     return this._console;
   },
   
new file mode 100644
--- /dev/null
+++ b/browser/fuel/test/ContentWithFrames.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" >
+<head>
+    <title>Content Page with Frames</title>
+</head>
+<body>
+<h1>Content Page with Frames</h1>
+<div id="desc">This is a simple framed content page used for testing FUEL Browser API</div>
+<iframe src="ContentA.html"></iframe>
+<iframe src="ContentB.html"></iframe>
+</body>
+</html>
--- a/browser/fuel/test/Makefile.in
+++ b/browser/fuel/test/Makefile.in
@@ -44,14 +44,16 @@ relativesrcdir = browser/fuel/test
 include $(DEPTH)/config/autoconf.mk
 include $(topsrcdir)/config/rules.mk
 
 _BROWSER_FILES =browser_Application.js \
 		browser_ApplicationPrefs.js \
 		browser_ApplicationStorage.js \
 		browser_Browser.js \
 		browser_Bookmarks.js \
+		browser_Extensions.js \
 		ContentA.html \
 		ContentB.html \
+		ContentWithFrames.html \
 		$(NULL)
 
 libs::	$(_BROWSER_FILES)
 	$(INSTALL) $^ $(DEPTH)/_tests/testing/mochitest/browser/$(relativesrcdir)
--- a/browser/fuel/test/browser_Browser.js
+++ b/browser/fuel/test/browser_Browser.js
@@ -4,16 +4,17 @@ const Cc = Components.classes;
 function url(spec) {
   var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
   return ios.newURI(spec, null, null);
 }
 
 var gTabOpenCount = 0;
 var gTabCloseCount = 0;
 var gTabMoveCount = 0;
+var gPageLoadCount = 0;
 
 function test() {
   var windows = Application.windows;
   ok(windows, "Check access to browser windows");
   ok(windows.length, "There should be at least one browser window open");
 
   var activeWin = Application.activeWindow;
   activeWin.events.addListener("TabOpen", onTabOpen);
@@ -46,34 +47,51 @@ function test() {
     // test moving tab
     pageA.moveToEnd();
     is(pageA.index, 2, "Checking index after moving tab");
 
     // check event
     is(gTabMoveCount, 1, "Checking event handler for tab move");
 
     // test loading new content into a tab
-    // the event will be checked in afterClose
+    // the event will be checked in onPageLoad
     pageA.events.addListener("load", onPageLoad);
     pageA.load(pageB.uri);
+
+    // test loading new content with a frame into a tab
+    // the event will be checked in afterClose
+    pageB.events.addListener("load", onPageLoadWithFrames);
+    pageB.load(url("chrome://mochikit/content/browser/browser/fuel/test/ContentWithFrames.html"));
   }
 
   function onPageLoad(event) {
     is(pageA.uri.spec, "chrome://mochikit/content/browser/browser/fuel/test/ContentB.html", "Checking 'BrowserTab.uri' after loading new content");
 
     // start testing closing tabs
-    pageA.close();
-    pageB.close();
-    setTimeout(afterClose, 1000);
+    // the event will be checked in afterClose
+    // use a setTimeout so the pageloadwithframes
+    // has a chance to finish first
+    setTimeout(function() {
+      pageA.close();
+      pageB.close();
+      setTimeout(afterClose, 1000);
+     }, 1000);
   }
 
+  function onPageLoadWithFrames(event) {
+    gPageLoadCount++;
+  }
+  
   function afterClose() {
-    // check event
+    // check close event
     is(gTabCloseCount, 2, "Checking event handler for tab close");
 
+    // check page load with frame event
+    is(gPageLoadCount, 1, "Checking 'BrowserTab.uri' after loading new content with a frame");
+
     is(activeWin.tabs.length, 1, "Checking length of 'Browser.tabs' after closing 2 tabs");
 
     finish();
   }
 }
 
 function onTabOpen(event) {
   gTabOpenCount++;
--- a/browser/fuel/test/browser_Extensions.js
+++ b/browser/fuel/test/browser_Extensions.js
@@ -1,14 +1,16 @@
 // The various pieces that we'll be testing
 var testdata = {
   dummyid: "fuel-dummy-extension@mozilla.org",
   dummyname: "Dummy Extension",
   inspectorid: "inspector@mozilla.org",
-  inspectorname: "DOM Inspector"
+  inspectorname: "DOM Inspector",
+  missing: "fuel.fuel-test-missing",
+  dummy: "fuel.fuel-test"
 };
 var gLastEvent = "";
 
 function test() {
   // test to see if a non-existant extension exists
   ok(!Application.extensions.has(testdata.dummyid), "Check non-existant extension for existance");
 
   // test to see if an extension exists
@@ -18,20 +20,17 @@ function test() {
   is(inspector.id, testdata.inspectorid, "Check 'Extension.id' for known extension");
   is(inspector.name, testdata.inspectorname, "Check 'Extension.name' for known extension");
   // The known version number changes too frequently to hardcode in
   ok(inspector.version, "Check 'Extension.version' for known extension");
   ok(inspector.firstRun, "Check 'Extension.firstRun' for known extension");
   
   // test to see if extension find works
   is(Application.extensions.all.length, 1, "Check a find for all extensions");
-
-  // test the value of the preference root
-  is(Application.extensions.all[0].prefs.root, "extensions.inspector@mozilla.org.", "Check an extension preference root");
-  
+  // STORAGE TESTING
   // Make sure the we are given the same extension (cached) so things like .storage work right
   inspector.storage.set("test", "simple check");
   ok(inspector.storage.has("test"), "Checking that extension storage worked");
 
   var inspector2 = Application.extensions.get(testdata.inspectorid);
   is(inspector2.id, testdata.inspectorid, "Check 'Extension.id' for known extension - from cache");
   ok(inspector.storage.has("test"), "Checking that extension storage worked - from cache");
   is(inspector2.storage.get("test", "cache"), inspector.storage.get("test", "original"), "Checking that the storage of same extension is correct - from cache");
@@ -52,17 +51,69 @@ function test() {
   extmgr.enableItem(testdata.inspectorid);
   is(gLastEvent, "cancel", "Checking that enable (cancel) event is fired");
 
   extmgr.uninstallItem(testdata.inspectorid);
   is(gLastEvent, "uninstall", "Checking that uninstall event is fired");
 
   extmgr.cancelUninstallItem(testdata.inspectorid);
   is(gLastEvent, "cancel", "Checking that cancel event is fired");
+
+  // PREF TESTING
+  // Reset the install event preference, so that we can test it again later
+  inspector.prefs.get("install-event-fired").reset();
+
+  // test the value of the preference root
+  is(Application.extensions.all[0].prefs.root, "extensions.inspector@mozilla.org.", "Check an extension preference root");
+
+  // test getting non-existing values
+  var itemValue = inspector.prefs.getValue(testdata.missing, "default");
+  is(itemValue, "default", "Check 'Extension.prefs.getValue' for non-existing item");
   
-  // Reset the install event preference, so that we can test it again later [do this last in test]
-  inspector.prefs.get("install-event-fired").reset();
+  is(inspector.prefs.get(testdata.missing), null, "Check 'Extension.prefs.get' for non-existing item");
+  
+  // test setting and getting a value
+  inspector.prefs.setValue(testdata.dummy, "dummy");
+  itemValue = inspector.prefs.getValue(testdata.dummy, "default");
+  is(itemValue, "dummy", "Check 'Extension.prefs.getValue' for existing item");
+
+  // test for overwriting an existing value
+  inspector.prefs.setValue(testdata.dummy, "smarty");
+  itemValue = inspector.prefs.getValue(testdata.dummy, "default");
+  is(itemValue, "smarty", "Check 'Extension.prefs.getValue' for overwritten item");
+  
+  // test setting and getting a value
+  inspector.prefs.get(testdata.dummy).value = "dummy2";
+  itemValue = inspector.prefs.get(testdata.dummy).value;
+  is(itemValue, "dummy2", "Check 'Extension.prefs.get().value' for existing item");
+
+  // test resetting a pref [since there is no default value, the pref should disappear]
+  inspector.prefs.get(testdata.dummy).reset();
+  var itemValue = inspector.prefs.getValue(testdata.dummy, "default");
+  is(itemValue, "default", "Check 'Extension.prefs.getValue' for reset pref");
+  
+  // test to see if a non-existant property exists
+  ok(!inspector.prefs.has(testdata.dummy), "Check non-existant property for existance");
+
+  waitForExplicitFinish();
+  inspector.prefs.events.addListener("change", onPrefChange);
+  inspector.prefs.setValue("fuel.fuel-test", "change event");
 }
 
 function onGenericEvent(event) {
-  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
   gLastEvent = event.type;
 }
+
+function onPrefChange(evt) {
+  var inspector3 = Application.extensions.get(testdata.inspectorid);
+
+  is(evt.data, testdata.dummy, "Check 'Extension.prefs.set' fired a change event");
+  inspector3.prefs.events.removeListener("change", onPrefChange);
+
+  inspector3.prefs.get("fuel.fuel-test").events.addListener("change", onPrefChange2);
+  inspector3.prefs.setValue("fuel.fuel-test", "change event2");
+}
+
+function onPrefChange2(evt) {
+  is(evt.data, testdata.dummy, "Check 'Extension.prefs.set' fired a change event for a single preference");
+  
+  finish();
+}
--- a/browser/installer/removed-files.in
+++ b/browser/installer/removed-files.in
@@ -59,16 +59,17 @@ component.reg
 components/compreg.dat
 components/@DLL_PREFIX@myspell@DLL_SUFFIX@
 components/@DLL_PREFIX@spellchecker@DLL_SUFFIX@
 components/spellchecker.xpt
 components/@DLL_PREFIX@spellchk@DLL_SUFFIX@
 components/xpti.dat
 components/xptitemp.dat
 components/nsBackgroundUpdateService.js
+components/nsCloseAllWindows.js
 #ifndef XP_MACOSX
 components/autocomplete.xpt
 #endif
 @DLL_PREFIX@zlib@DLL_SUFFIX@
 #Remove Talkback files from old location (in case user updates from 1.0.x)
 components/BrandRes.dll
 components/fullsoft.dll
 components/master.ini
--- a/browser/installer/unix/packages-static
+++ b/browser/installer/unix/packages-static
@@ -48,16 +48,17 @@ bin/@MOZ_APP_NAME@
 bin/application.ini
 bin/platform.ini
 bin/mozilla-xremote-client
 bin/run-mozilla.sh
 bin/plugins/libnullplugin.so
 bin/res/cmessage.txt
 bin/res/effective_tld_names.dat
 bin/xpicleanup
+bin/libsqlite3.so
 
 ; [Components]
 bin/components/accessibility.xpt
 bin/components/appshell.xpt
 bin/components/appstartup.xpt
 bin/components/autocomplete.xpt
 bin/components/autoconfig.xpt
 bin/components/browsercompsbase.xpt
--- a/browser/installer/windows/packages-static
+++ b/browser/installer/windows/packages-static
@@ -51,16 +51,17 @@ bin\@MOZ_APP_NAME@.exe
 bin\application.ini
 bin\platform.ini
 bin\plugins\npnul32.dll
 bin\res\cmessage.txt
 bin\res\effective_tld_names.dat
 bin\xpicleanup.exe
 bin\LICENSE
 bin\README.txt
+bin\sqlite3.dll
 
 ; [Components]
 bin\components\alerts.xpt
 bin\AccessibleMarshal.dll
 bin\components\accessibility.xpt
 bin\components\accessibility-msaa.xpt
 bin\components\appshell.xpt
 bin\components\appstartup.xpt
--- a/config/autoconf.mk.in
+++ b/config/autoconf.mk.in
@@ -457,19 +457,16 @@ MOZ_ENABLE_GLITZ        = @MOZ_ENABLE_GL
 MOZ_ENABLE_GTK2		= @MOZ_ENABLE_GTK2@
 MOZ_ENABLE_PHOTON	= @MOZ_ENABLE_PHOTON@
 MOZ_ENABLE_COCOA	= @MOZ_ENABLE_COCOA@
 MOZ_ENABLE_XREMOTE	= @MOZ_ENABLE_XREMOTE@
 
 MOZ_GTK2_CFLAGS		= @MOZ_GTK2_CFLAGS@
 MOZ_GTK2_LIBS		= @MOZ_GTK2_LIBS@
 
-MOZ_LIBCURL_CFLAGS      = @MOZ_LIBCURL_CFLAGS@
-MOZ_LIBCURL_LIBS        = @MOZ_LIBCURL_LIBS@
-
 MOZ_DBUS_GLIB_CFLAGS    = @MOZ_DBUS_GLIB_CFLAGS@
 MOZ_DBUS_GLIB_LIBS      = @MOZ_DBUS_GLIB_LIBS@
 MOZ_ENABLE_DBUS         = @MOZ_ENABLE_DBUS@
 
 MOZ_ENABLE_FREETYPE2   = @MOZ_ENABLE_FREETYPE2@
 FT2_CFLAGS             = @FT2_CFLAGS@
 FT2_LIBS               = @FT2_LIBS@
 
--- a/config/static-config.mk
+++ b/config/static-config.mk
@@ -78,25 +78,17 @@ STATIC_EXTRA_LIBS	+= \
 endif
 
 ifdef MOZ_LDAP_XPCOM
 STATIC_EXTRA_LIBS	+= \
 		$(LDAP_LIBS) \
 		$(NULL)
 endif
 
-ifndef MOZ_ENABLE_CAIRO_GFX
-ifdef MOZ_SVG
 STATIC_EXTRA_LIBS	+= $(MOZ_CAIRO_LIBS)
-else # not MOZ_SVG
-ifdef MOZ_ENABLE_CANVAS # not SVG, but yes on canvas
-STATIC_EXTRA_LIBS	+= $(MOZ_CAIRO_LIBS)
-endif
-endif
-endif
 
 ifdef MOZ_ENABLE_GTK2
 STATIC_EXTRA_LIBS	+= $(XLDFLAGS) $(XT_LIBS) -lgthread-2.0
 endif
 
 ifdef MOZ_ENABLE_XFT
 STATIC_EXTRA_LIBS	+= $(MOZ_XFT_LIBS)
 endif
--- a/config/system-headers
+++ b/config/system-headers
@@ -501,16 +501,17 @@ Packages.h
 Palettes.h
 PALM_CMN.H
 pango-engine.h
 pango-glyph.h
 pango-modules.h
 pango/pangofc-decoder.h
 pango/pangofc-font.h
 pango/pangofc-fontmap.h
+pango/pango-break.h
 pango/pango-fontmap.h
 pango/pango.h
 pango/pangoxft.h
 pango/pangox.h
 pango-types.h
 pascal.h
 Patches.h
 Path.h
--- a/configure.in
+++ b/configure.in
@@ -5319,42 +5319,33 @@ fi
 MOZ_ARG_DISABLE_BOOL(airbag,
 [  --disable-airbag          Disable airbag crash reporting],
     MOZ_AIRBAG=,
     MOZ_AIRBAG=1)
 
 if test -n "$MOZ_AIRBAG"; then
    AC_DEFINE(MOZ_AIRBAG)
 
-  if test "$OS_ARCH" = "Linux"; then
-    PKG_CHECK_MODULES(MOZ_LIBCURL, libcurl, _CURL_FOUND=1, _CURL_FOUND=)
-    if test -z "$_CURL_FOUND"; then
-       AC_PATH_PROGS(CURL_CONFIG, $CURL_CONFIG curl-config)
-       if test -n "$CURL_CONFIG"; then
-          AC_MSG_CHECKING(MOZ_LIBCURL_CFLAGS)
-          MOZ_LIBCURL_CFLAGS=`${CURL_CONFIG} --cflags`
-          AC_MSG_RESULT($MOZ_LIBCURL_CFLAGS)
-
-          AC_MSG_CHECKING(MOZ_LIBCURL_LIBS)
-          MOZ_LIBCURL_LIBS=`${CURL_CONFIG} --libs`
-          AC_MSG_RESULT($MOZ_LIBCURL_LIBS)
-
-          _CURL_FOUND=1
-       fi
-    fi
-
-    if test -z "$_CURL_FOUND" && test -z "$SKIP_LIBRARY_CHECKS"; then
+  if test "$OS_ARCH" = "Linux" && \
+     test -z "$SKIP_LIBRARY_CHECKS"; then
+     _SAVE_LDFLAGS=$LDFLAGS
+     LDFLAGS="$LDFLAGS -lcurl"
+     AC_CACHE_CHECK(for libcurl,
+                    ac_cv_have_libcurl,
+                    [AC_TRY_LINK([#include <curl/curl.h>],
+                                 [curl_easy_init();],
+                                 ac_cv_have_libcurl="yes",
+                                 ac_cv_have_libcurl="no")])
+    if test "$ac_cv_have_libcurl" = "no"; then
         AC_MSG_ERROR([Couldn't find libcurl, which is required for the crash reporter.  Use --disable-airbag to disable the crash reporter.])
     fi
+    LDFLAGS=$_SAVE_LDFLAGS
   fi
 fi
 
-AC_SUBST(MOZ_LIBCURL_CFLAGS)
-AC_SUBST(MOZ_LIBCURL_LIBS)
-
 dnl ========================================================
 dnl = Build mochitest JS/DOM tests (on by default)
 dnl ========================================================
 MOZ_ARG_DISABLE_BOOL(mochitest,
 [  --disable-mochitest        Disable mochitest harness],
     MOZ_MOCHITEST=,
     MOZ_MOCHITEST=1 )
 
@@ -5405,16 +5396,22 @@ if test `echo "$MOZ_EXTENSIONS" | grep -
 fi
 
 dnl cookie must be built before tridentprofile. put it at list's end.
 if test `echo "$MOZ_EXTENSIONS" | grep -c tridentprofile` -ne 0; then
   MOZ_EXTENSIONS=`echo $MOZ_EXTENSIONS | sed -e 's|tridentprofile||'`
   MOZ_EXTENSIONS="$MOZ_EXTENSIONS tridentprofile"
 fi
 
+dnl schema-validation requires webservices
+if test -z "$MOZ_WEBSERVICES" && test `echo "$MOZ_EXTENSIONS" | grep -c schema-validation` -ne 0; then
+    AC_MSG_WARN([Cannot build schema-validation without webservices.  Removing schema-validation from MOZ_EXTENSIONS.])
+    MOZ_EXTENSIONS=`echo $MOZ_EXTENSIONS | sed -e 's|schema-validation||g'`
+fi
+
 dnl xforms requires xtf and webservices and schema-validation
 if test -z "$MOZ_XTF" && test `echo "$MOZ_EXTENSIONS" | grep -c xforms` -ne 0; then
     AC_MSG_WARN([Cannot build XForms without XTF support.  Removing XForms from MOZ_EXTENSIONS.])
     MOZ_EXTENSIONS=`echo $MOZ_EXTENSIONS | sed -e 's|xforms||g'`
 fi
 if test -z "$MOZ_WEBSERVICES" && test `echo "$MOZ_EXTENSIONS" | grep -c xforms` -ne 0; then
     AC_MSG_WARN([Cannot build XForms without webservices.  Removing XForms from MOZ_EXTENSIONS.])
     MOZ_EXTENSIONS=`echo $MOZ_EXTENSIONS | sed -e 's|xforms||g'`
--- a/content/base/public/nsLineBreaker.h
+++ b/content/base/public/nsLineBreaker.h
@@ -91,21 +91,22 @@ public:
     return !((0x0030 <= u && u <= 0x0039) ||
              (0x0041 <= u && u <= 0x005A) ||
              (0x0061 <= u && u <= 0x007A));
   }
 
   static inline PRBool IsComplexChar(PRUnichar u)
   {
     return IsComplexASCIIChar(u) ||
-           (0x1100 <= u && u <= 0x11ff) ||
-           (0x2000 <= u && u <= 0x21ff) ||
-           (0x2e80 <= u && u <= 0xd7ff) ||
-           (0xf900 <= u && u <= 0xfaff) ||
-           (0xff00 <= u && u <= 0xffef);
+           (0x0e01 <= u && u <= 0x0edf) || // Thai & Lao
+           (0x1100 <= u && u <= 0x11ff) || // Hangul Jamo
+           (0x2000 <= u && u <= 0x21ff) || // Punctuations and Symbols
+           (0x2e80 <= u && u <= 0xd7ff) || // several CJK blocks
+           (0xf900 <= u && u <= 0xfaff) || // CJK Compatibility Idographs
+           (0xff00 <= u && u <= 0xffef);   // Halfwidth and Fullwidth Forms
   }
 
   // Normally, break opportunities exist at the end of each run of whitespace
   // (see IsSpace above). Break opportunities can also exist inside runs of
   // non-whitespace, as determined by nsILineBreaker. We pass a whitespace-
   // delimited word to nsILineBreaker if it contains at least one character
   // matching IsComplexChar.
   // We provide flags to control on a per-chunk basis where breaks are allowed.
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -3600,16 +3600,17 @@ nsContentUtils::CheckSecurityBeforeLoad(
                                         nsIPrincipal* aLoadingPrincipal,
                                         PRUint32 aCheckLoadFlags,
                                         PRBool aAllowData,
                                         PRUint32 aContentPolicyType,
                                         nsISupports* aContext,
                                         const nsACString& aMimeGuess,
                                         nsISupports* aExtra)
 {
+  // XXXbz do we want to fast-path skin stylesheets loading XBL here somehow?
   nsCOMPtr<nsIURI> loadingURI;
   nsresult rv = aLoadingPrincipal->GetURI(getter_AddRefs(loadingURI));
   NS_ENSURE_SUCCESS(rv, rv);
 
   // CheckLoadURIWithPrincipal
   rv = sSecurityManager->
     CheckLoadURIWithPrincipal(aLoadingPrincipal, aURIToLoad, aCheckLoadFlags);
   NS_ENSURE_SUCCESS(rv, rv);
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -3401,18 +3401,32 @@ nsDocument::AddBinding(nsIDOMElement* aC
 
   nsCOMPtr<nsIContent> content(do_QueryInterface(aContent));
 
   nsCOMPtr<nsIURI> uri;
   rv = NS_NewURI(getter_AddRefs(uri), aURI);
   if (NS_FAILED(rv)) {
     return rv;
   }
+
+  // Figure out the right principal to use
+  nsCOMPtr<nsIPrincipal> subject;
+  nsIScriptSecurityManager* secMan = nsContentUtils::GetSecurityManager();
+  if (secMan) {
+    rv = secMan->GetSubjectPrincipal(getter_AddRefs(subject));
+    NS_ENSURE_SUCCESS(rv, rv);
+  }
+
+  if (!subject) {
+    // Fall back to our principal.  Or should we fall back to the null
+    // principal?  The latter would just mean no binding loads....
+    subject = NodePrincipal();
+  }
   
-  return mBindingManager->AddLayeredBinding(content, uri);
+  return mBindingManager->AddLayeredBinding(content, uri, subject);
 }
 
 NS_IMETHODIMP
 nsDocument::RemoveBinding(nsIDOMElement* aContent, const nsAString& aURI)
 {
   NS_ENSURE_ARG(aContent);
 
   nsresult rv = nsContentUtils::CheckSameOrigin(this, aContent);
@@ -3434,17 +3448,31 @@ NS_IMETHODIMP
 nsDocument::LoadBindingDocument(const nsAString& aURI)
 {
   nsCOMPtr<nsIURI> uri;
   nsresult rv = NS_NewURI(getter_AddRefs(uri), aURI,
                           mCharacterSet.get(),
                           static_cast<nsIDocument *>(this)->GetBaseURI());
   NS_ENSURE_SUCCESS(rv, rv);
 
-  mBindingManager->LoadBindingDocument(this, uri);
+  // Figure out the right principal to use
+  nsCOMPtr<nsIPrincipal> subject;
+  nsIScriptSecurityManager* secMan = nsContentUtils::GetSecurityManager();
+  if (secMan) {
+    rv = secMan->GetSubjectPrincipal(getter_AddRefs(subject));
+    NS_ENSURE_SUCCESS(rv, rv);
+  }
+
+  if (!subject) {
+    // Fall back to our principal.  Or should we fall back to the null
+    // principal?  The latter would just mean no binding loads....
+    subject = NodePrincipal();
+  }
+  
+  mBindingManager->LoadBindingDocument(this, uri, subject);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDocument::GetBindingParent(nsIDOMNode* aNode, nsIDOMElement** aResult)
 {
   *aResult = nsnull;
--- a/content/base/src/nsObjectLoadingContent.cpp
+++ b/content/base/src/nsObjectLoadingContent.cpp
@@ -32,17 +32,17 @@
  * 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 ***** */
 
 /*
- * A base class implementING nsIObjectLoadingContent for use by
+ * A base class implementing nsIObjectLoadingContent for use by
  * various content nodes that want to provide plugin/document/image
  * loading functionality (eg <embed>, <object>, <applet>, etc).
  */
 
 // Interface headers
 #include "imgILoader.h"
 #include "nsIContent.h"
 #include "nsIDocShell.h"
@@ -279,20 +279,56 @@ IsSupportedImage(const nsCString& aMimeT
 static PRBool
 IsSupportedPlugin(const nsCString& aMIMEType)
 {
   nsCOMPtr<nsIPluginHost> host(do_GetService("@mozilla.org/plugin/host;1"));
   if (!host) {
     return PR_FALSE;
   }
   nsresult rv = host->IsPluginEnabledForType(aMIMEType.get());
-  // XXX do plugins expect to work via extension too?
   return NS_SUCCEEDED(rv);
 }
 
+static void
+GetExtensionFromURI(nsIURI* uri, nsCString& ext)
+{
+  nsCOMPtr<nsIURL> url(do_QueryInterface(uri));
+  if (url) {
+    url->GetFileExtension(ext);
+  } else {
+    nsCString spec;
+    uri->GetSpec(spec);
+
+    PRInt32 offset = spec.RFindChar('.');
+    if (offset != kNotFound) {
+      ext = Substring(spec, offset + 1, spec.Length());
+    }
+  }
+}
+
+/**
+ * Checks whether a plugin exists and is enabled for the extension
+ * in the given URI. The MIME type is returned in the mimeType out parameter.
+ */
+static PRBool
+IsPluginEnabledByExtension(nsIURI* uri, nsCString& mimeType)
+{
+  nsCAutoString ext;
+  GetExtensionFromURI(uri, ext);
+
+  nsCOMPtr<nsIPluginHost> host(do_GetService("@mozilla.org/plugin/host;1"));
+  const char* typeFromExt;
+  if (host &&
+      NS_SUCCEEDED(host->IsPluginEnabledForExtension(ext.get(), typeFromExt))) {
+    mimeType = typeFromExt;
+    return PR_TRUE;
+  }
+  return PR_FALSE;
+}
+
 nsObjectLoadingContent::nsObjectLoadingContent()
   : mPendingInstantiateEvent(nsnull)
   , mChannel(nsnull)
   , mType(eType_Loading)
   , mInstantiating(PR_FALSE)
   , mUserDisabled(PR_FALSE)
   , mSuppressed(PR_FALSE)
   , mTypeUnsupported(PR_FALSE)
@@ -561,16 +597,17 @@ nsObjectLoadingContent::EnsureInstantiat
 
     nsCOMPtr<nsIContent> thisContent = 
       do_QueryInterface(static_cast<nsIImageLoadingContent*>(this));
     NS_ASSERTION(thisContent, "must be a content");
 
     nsIDocument* doc = thisContent->GetCurrentDoc();
     if (!doc) {
       // Nothing we can do while plugin loading is done in layout...
+      mInstantiating = PR_FALSE;
       return NS_OK;
     }
 
     nsPresShellIterator iter(doc);
     nsCOMPtr<nsIPresShell> shell;
     while ((shell = iter.GetNextShell())) {
       shell->RecreateFramesFor(thisContent);
     }
@@ -853,18 +890,30 @@ nsObjectLoadingContent::LoadObject(nsIUR
   nsresult rv = NS_ERROR_UNEXPECTED;
   // This fallback variable MUST be declared after the notifier variable. Do NOT
   // change the order of the declarations!
   AutoFallback fallback(this, &rv);
 
   PRUint32 caps = GetCapabilities();
   LOG(("OBJLC [%p]: Capabilities: %04x\n", this, caps));
 
-  if ((caps & eOverrideServerType) && !aTypeHint.IsEmpty()) {
-    ObjectType newType = GetTypeOfContent(aTypeHint);
+  nsCAutoString overrideType;
+  if ((caps & eOverrideServerType) &&
+      (!aTypeHint.IsEmpty() ||
+       (aURI && IsPluginEnabledByExtension(aURI, overrideType)))) {
+    NS_ASSERTION(aTypeHint.IsEmpty() ^ overrideType.IsEmpty(),
+                 "Exactly one of aTypeHint and overrideType should be empty!");
+
+    ObjectType newType;
+    if (overrideType.IsEmpty()) {
+      newType = GetTypeOfContent(aTypeHint);
+    } else {
+      newType = eType_Plugin;
+    }
+
     if (newType != mType) {
       LOG(("OBJLC [%p]: (eOverrideServerType) Changing type from %u to %u\n", this, mType, newType));
 
       UnloadContent();
 
       // Must have a frameloader before creating a frame, or the frame will
       // create its own.
       if (!mFrameLoader && newType == eType_Document) {
@@ -1361,37 +1410,17 @@ nsObjectLoadingContent::Instantiate(cons
   nsIObjectFrame* frame = GetFrame();
   if (!frame) {
     LOG(("OBJLC [%p]: Attempted to instantiate, but have no frame\n", this));
     return NS_OK; // Not a failure to have no frame
   }
 
   nsCString typeToUse(aMIMEType);
   if (typeToUse.IsEmpty() && aURI) {
-    nsCAutoString ext;
-    
-    nsCOMPtr<nsIURL> url(do_QueryInterface(aURI));
-    if (url) {
-      url->GetFileExtension(ext);
-    } else {
-      nsCString spec;
-      aURI->GetSpec(spec);
-
-      PRInt32 offset = spec.RFindChar('.');
-      if (offset != kNotFound) {
-        ext = Substring(spec, offset + 1, spec.Length());
-      }
-    }
-
-    nsCOMPtr<nsIPluginHost> host(do_GetService("@mozilla.org/plugin/host;1"));
-    const char* typeFromExt;
-    if (host &&
-        NS_SUCCEEDED(host->IsPluginEnabledForExtension(ext.get(), typeFromExt))) {
-      typeToUse = typeFromExt;
-    }
+    IsPluginEnabledByExtension(aURI, typeToUse);
   }
 
   nsCOMPtr<nsIURI> baseURI;
   if (!aURI) {
     // We need some URI. If we have nothing else, use the base URI.
     // XXX(biesi): The code used to do this. Not sure why this is correct...
     nsCOMPtr<nsIContent> thisContent = 
       do_QueryInterface(static_cast<nsIImageLoadingContent*>(this));
--- a/content/base/test/test_bug382113.html
+++ b/content/base/test/test_bug382113.html
@@ -22,18 +22,18 @@ https://bugzilla.mozilla.org/show_bug.cg
 <script class="testbody" type="application/javascript">
 
 SimpleTest.waitForExplicitFinish();
 var childGotOnload = false;
 var objectGotOnload = false;
 
 /** Test for Bug 100533 **/
 function checkEvents() {
-  // todo(childGotOnload, true, "Child got load event");
-  // todo(objectGotOnload, true, "Object got load event");
+  is(childGotOnload, true, "Child got load event");
+  is(objectGotOnload, true, "Object got load event");
   SimpleTest.finish();
 }
 </script>
 
 </pre>
 </body>
 </html>
 
--- a/content/html/content/src/nsHTMLObjectElement.cpp
+++ b/content/html/content/src/nsHTMLObjectElement.cpp
@@ -226,18 +226,21 @@ nsHTMLObjectElement::SetAttr(PRInt32 aNa
                              PRBool aNotify)
 {
   // If we plan to call LoadObject, we want to do it first so that the
   // object load kicks off _before_ the reflow triggered by the SetAttr.  But if
   // aNotify is false, we are coming from the parser or some such place; we'll
   // get bound after all the attributes have been set, so we'll do the
   // object load from BindToTree/DoneAddingChildren.
   // Skip the LoadObject call in that case.
-  if (aNotify && aNameSpaceID == kNameSpaceID_None &&
-      aName == nsGkAtoms::data) {
+  // We also don't want to start loading the object when we're not yet in
+  // a document, just in case that the caller wants to set additional
+  // attributes before inserting the node into the document.
+  if (aNotify && IsInDoc() && mIsDoneAddingChildren &&
+      aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::data) {
     nsAutoString type;
     GetAttr(kNameSpaceID_None, nsGkAtoms::type, type);
     LoadObject(aValue, aNotify, NS_ConvertUTF16toUTF8(type), PR_TRUE);
   }
 
   return nsGenericHTMLFormElement::SetAttr(aNameSpaceID, aName, aPrefix,
                                            aValue, aNotify);
 }
--- a/content/html/content/src/nsHTMLSharedObjectElement.cpp
+++ b/content/html/content/src/nsHTMLSharedObjectElement.cpp
@@ -269,18 +269,21 @@ nsHTMLSharedObjectElement::SetAttr(PRInt
                                    PRBool aNotify)
 {
   // If we plan to call LoadObject, we want to do it first so that the
   // object load kicks off _before_ the reflow triggered by the SetAttr.  But if
   // aNotify is false, we are coming from the parser or some such place; we'll
   // get bound after all the attributes have been set, so we'll do the
   // object load from BindToTree/DoneAddingChildren.
   // Skip the LoadObject call in that case.
-  if (aNotify && aNameSpaceID == kNameSpaceID_None &&
-      aName == URIAttrName()) {
+  // We also don't want to start loading the object when we're not yet in
+  // a document, just in case that the caller wants to set additional
+  // attributes before inserting the node into the document.
+  if (aNotify && IsInDoc() && mIsDoneAddingChildren &&
+      aNameSpaceID == kNameSpaceID_None && aName == URIAttrName()) {
     nsCAutoString type;
     GetTypeAttrValue(type);
     LoadObject(aValue, aNotify, type, PR_TRUE);
   }
 
   return nsGenericHTMLElement::SetAttr(aNameSpaceID, aName, aPrefix, aValue,
                                        aNotify);
 }
--- a/content/xbl/public/nsIXBLService.h
+++ b/content/xbl/public/nsIXBLService.h
@@ -50,41 +50,48 @@
 class nsIContent;
 class nsIDocument;
 class nsPIDOMEventTarget;
 class nsIDOMNodeList;
 class nsXBLBinding;
 class nsIXBLDocumentInfo;
 class nsIURI;
 class nsIAtom;
+class nsIPrincipal;
 
 #define NS_IXBLSERVICE_IID      \
-  { 0xefda61b3, 0x5d04, 0x43b0, \
-    { 0x98, 0x0c, 0x32, 0x62, 0x72, 0xc8, 0x5c, 0x68 } }
+{ 0x98b28f4e, 0x698f, 0x4f77,   \
+ { 0xa8, 0x9e, 0x65, 0xf5, 0xd0, 0xde, 0x6a, 0xbf } }
 
 class nsIXBLService : public nsISupports
 {
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_IXBLSERVICE_IID)
 
   // This function loads a particular XBL file and installs all of the bindings
-  // onto the element.
-  NS_IMETHOD LoadBindings(nsIContent* aContent, nsIURI* aURL, PRBool aAugmentFlag,
+  // onto the element.  aOriginPrincipal must not be null here.
+  NS_IMETHOD LoadBindings(nsIContent* aContent, nsIURI* aURL,
+                          nsIPrincipal* aOriginPrincipal, PRBool aAugmentFlag,
                           nsXBLBinding** aBinding, PRBool* aResolveStyle) = 0;
 
   // Indicates whether or not a binding is fully loaded.
   NS_IMETHOD BindingReady(nsIContent* aBoundElement, nsIURI* aURI, PRBool* aIsReady) = 0;
 
   // Retrieves our base class (e.g., tells us what type of frame and content node to build)
   NS_IMETHOD ResolveTag(nsIContent* aContent, PRInt32* aNameSpaceID, nsIAtom** aResult) = 0;
 
-  // This method checks the hashtable and then calls FetchBindingDocument on a miss.
-  NS_IMETHOD LoadBindingDocumentInfo(nsIContent* aBoundElement, nsIDocument* aBoundDocument,
+  // This method checks the hashtable and then calls FetchBindingDocument on a
+  // miss.  aOriginPrincipal or aBoundDocument may be null to bypass security
+  // checks.
+  NS_IMETHOD LoadBindingDocumentInfo(nsIContent* aBoundElement,
+                                     nsIDocument* aBoundDocument,
                                      nsIURI* aBindingURI,
-                                     PRBool aForceSyncLoad, nsIXBLDocumentInfo** aResult) = 0;
+                                     nsIPrincipal* aOriginPrincipal,
+                                     PRBool aForceSyncLoad,
+                                     nsIXBLDocumentInfo** aResult) = 0;
 
   // Hooks up the global key event handlers to the document root.
   NS_IMETHOD AttachGlobalKeyHandler(nsPIDOMEventTarget* aTarget)=0;
   
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsIXBLService, NS_IXBLSERVICE_IID)
 
--- a/content/xbl/src/nsBindingManager.cpp
+++ b/content/xbl/src/nsBindingManager.cpp
@@ -685,30 +685,31 @@ nsBindingManager::GetSingleInsertionPoin
   if (binding)
     return binding->GetSingleInsertionPoint(aIndex, aMultipleInsertionPoints);
 
   *aMultipleInsertionPoints = PR_FALSE;
   return nsnull;
 }
 
 nsresult
-nsBindingManager::AddLayeredBinding(nsIContent* aContent, nsIURI* aURL)
+nsBindingManager::AddLayeredBinding(nsIContent* aContent, nsIURI* aURL,
+                                    nsIPrincipal* aOriginPrincipal)
 {
   // First we need to load our binding.
   nsresult rv;
   nsCOMPtr<nsIXBLService> xblService = 
            do_GetService("@mozilla.org/xbl;1", &rv);
   if (!xblService)
     return rv;
 
   // Load the bindings.
   nsRefPtr<nsXBLBinding> binding;
   PRBool dummy;
-  xblService->LoadBindings(aContent, aURL, PR_TRUE, getter_AddRefs(binding),
-                           &dummy);
+  xblService->LoadBindings(aContent, aURL, aOriginPrincipal, PR_TRUE,
+                           getter_AddRefs(binding), &dummy);
   if (binding) {
     AddToAttachedQueue(binding);
     ProcessAttachedQueue();
   }
 
   return NS_OK;
 }
 
@@ -761,31 +762,33 @@ nsBindingManager::RemoveLayeredBinding(n
   nsIPresShell *presShell = doc->GetPrimaryShell();
   NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
 
   return presShell->RecreateFramesFor(aContent);;
 }
 
 nsresult
 nsBindingManager::LoadBindingDocument(nsIDocument* aBoundDoc,
-                                      nsIURI* aURL)
+                                      nsIURI* aURL,
+                                      nsIPrincipal* aOriginPrincipal)
 {
   NS_PRECONDITION(aURL, "Must have a URI to load!");
   
   // First we need to load our binding.
   nsresult rv;
   nsCOMPtr<nsIXBLService> xblService = 
            do_GetService("@mozilla.org/xbl;1", &rv);
   if (!xblService)
     return rv;
 
   // Load the binding doc.
   nsCOMPtr<nsIXBLDocumentInfo> info;
   xblService->LoadBindingDocumentInfo(nsnull, aBoundDoc, aURL,
-                                      PR_TRUE, getter_AddRefs(info));
+                                      aOriginPrincipal, PR_TRUE,
+                                      getter_AddRefs(info));
   if (!info)
     return NS_ERROR_FAILURE;
 
   return NS_OK;
 }
 
 nsresult
 nsBindingManager::AddToAttachedQueue(nsXBLBinding* aBinding)
--- a/content/xbl/src/nsBindingManager.h
+++ b/content/xbl/src/nsBindingManager.h
@@ -57,16 +57,17 @@ class nsIDocument;
 class nsIURI;
 class nsIXBLDocumentInfo;
 class nsIStreamListener;
 class nsStyleSet;
 class nsXBLBinding;
 template<class E> class nsRefPtr;
 typedef nsTArray<nsRefPtr<nsXBLBinding> > nsBindingList;
 template<class T> class nsRunnableMethod;
+class nsIPrincipal;
 
 class nsBindingManager : public nsIMutationObserver
 {
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_NSIMUTATIONOBSERVER
 
   nsBindingManager();
@@ -149,19 +150,21 @@ public:
   /**
    * Return the unfiltered insertion point for the specified parent
    * element. If other filtered insertion points exist,
    * aMultipleInsertionPoints will be set to true.
    */
   nsIContent* GetSingleInsertionPoint(nsIContent* aParent, PRUint32* aIndex,
                                       PRBool* aMultipleInsertionPoints);
 
-  nsresult AddLayeredBinding(nsIContent* aContent, nsIURI* aURL);
+  nsresult AddLayeredBinding(nsIContent* aContent, nsIURI* aURL,
+                             nsIPrincipal* aOriginPrincipal);
   nsresult RemoveLayeredBinding(nsIContent* aContent, nsIURI* aURL);
-  nsresult LoadBindingDocument(nsIDocument* aBoundDoc, nsIURI* aURL);
+  nsresult LoadBindingDocument(nsIDocument* aBoundDoc, nsIURI* aURL,
+                               nsIPrincipal* aOriginPrincipal);
 
   nsresult AddToAttachedQueue(nsXBLBinding* aBinding);
   void ProcessAttachedQueue();
 
   void ExecuteDetachedHandlers();
 
   nsresult PutXBLDocumentInfo(nsIXBLDocumentInfo* aDocumentInfo);
   nsIXBLDocumentInfo* GetXBLDocumentInfo(nsIURI* aURI);
--- a/content/xbl/src/nsXBLService.cpp
+++ b/content/xbl/src/nsXBLService.cpp
@@ -481,19 +481,22 @@ nsXBLService::~nsXBLService(void)
     delete gClassTable;
     gClassTable = nsnull;
   }
 }
 
 // This function loads a particular XBL file and installs all of the bindings
 // onto the element.
 NS_IMETHODIMP
-nsXBLService::LoadBindings(nsIContent* aContent, nsIURI* aURL, PRBool aAugmentFlag,
+nsXBLService::LoadBindings(nsIContent* aContent, nsIURI* aURL,
+                           nsIPrincipal* aOriginPrincipal, PRBool aAugmentFlag,
                            nsXBLBinding** aBinding, PRBool* aResolveStyle) 
-{ 
+{
+  NS_PRECONDITION(aOriginPrincipal, "Must have an origin principal");
+  
   *aBinding = nsnull;
   *aResolveStyle = PR_FALSE;
 
   nsresult rv;
 
   nsCOMPtr<nsIDocument> document = aContent->GetOwnerDoc();
 
   // XXX document may be null if we're in the midst of paint suppression
@@ -517,36 +520,20 @@ nsXBLService::LoadBindings(nsIContent* a
         if (NS_SUCCEEDED(uri->Equals(aURL, &equal)) && equal)
           return NS_OK;
         FlushStyleBindings(aContent);
         binding = nsnull;
       }
     }
   }
 
-  // Security check - Enforce same-origin policy, except to chrome.
-  // We have to be careful to not pass aContent as the context here. 
-  // Otherwise, if there is a JS-implemented content policy, we will attempt
-  // to wrap the content node, which will try to load XBL bindings for it, if
-  // any. Since we're not done loading this binding yet, that will reenter
-  // this method and we'll end up creating a binding and then immediately
-  // clobbering it in our table.  That makes things very confused, leading to
-  // misbehavior and crashes.
-  rv = nsContentUtils::CheckSecurityBeforeLoad(aURL,
-                                               document->NodePrincipal(),
-                                               nsIScriptSecurityManager::ALLOW_CHROME,
-                                               PR_TRUE,
-                                               nsIContentPolicy::TYPE_XBL,
-                                               document);
-  NS_ENSURE_SUCCESS(rv, rv);
-
   PRBool ready;
   nsRefPtr<nsXBLBinding> newBinding;
-  if (NS_FAILED(rv = GetBinding(aContent, aURL, PR_FALSE, &ready,
-                                getter_AddRefs(newBinding)))) {
+  if (NS_FAILED(rv = GetBinding(aContent, aURL, PR_FALSE, aOriginPrincipal,
+                                &ready, getter_AddRefs(newBinding)))) {
     return rv;
   }
 
   if (!newBinding) {
 #ifdef DEBUG
     nsCAutoString spec;
     aURL->GetSpec(spec);
     nsCAutoString str(NS_LITERAL_CSTRING("Failed to locate XBL binding. XBL is now using id instead of name to reference bindings. Make sure you have switched over.  The invalid binding name is: ") + spec);
@@ -752,33 +739,35 @@ nsXBLService::FlushMemory()
 }
 
 // Internal helper methods ////////////////////////////////////////////////////////////////
 
 NS_IMETHODIMP nsXBLService::BindingReady(nsIContent* aBoundElement, 
                                          nsIURI* aURI, 
                                          PRBool* aIsReady)
 {
-  return GetBinding(aBoundElement, aURI, PR_TRUE, aIsReady, nsnull);
+  // Don't do a security check here; we know this binding is set to go.
+  return GetBinding(aBoundElement, aURI, PR_TRUE, nsnull, aIsReady, nsnull);
 }
 
 nsresult
 nsXBLService::GetBinding(nsIContent* aBoundElement, nsIURI* aURI, 
-                         PRBool aPeekOnly, PRBool* aIsReady, 
-                         nsXBLBinding** aResult)
+                         PRBool aPeekOnly, nsIPrincipal* aOriginPrincipal,
+                         PRBool* aIsReady, nsXBLBinding** aResult)
 {
   // More than 6 binding URIs are rare, see bug 55070 comment 18.
   nsTArray<nsIURI*> uris(6);
-  return GetBinding(aBoundElement, aURI, aPeekOnly, aIsReady, aResult, uris);
+  return GetBinding(aBoundElement, aURI, aPeekOnly, aOriginPrincipal, aIsReady,
+                    aResult, uris);
 }
 
 nsresult
 nsXBLService::GetBinding(nsIContent* aBoundElement, nsIURI* aURI, 
-                         PRBool aPeekOnly, PRBool* aIsReady,
-                         nsXBLBinding** aResult,
+                         PRBool aPeekOnly, nsIPrincipal* aOriginPrincipal,
+                         PRBool* aIsReady, nsXBLBinding** aResult,
                          nsTArray<nsIURI*>& aDontExtendURIs)
 {
   NS_ASSERTION(aPeekOnly || aResult,
                "Must have non-null out param if not just peeking to see "
                "whether the binding is ready");
   
   if (aResult)
     *aResult = nsnull;
@@ -791,18 +780,21 @@ nsXBLService::GetBinding(nsIContent* aBo
   nsCAutoString ref;
   nsCOMPtr<nsIURL> url(do_QueryInterface(aURI));
   if (url)
     url->GetRef(ref);
 
   nsCOMPtr<nsIDocument> boundDocument = aBoundElement->GetOwnerDoc();
 
   nsCOMPtr<nsIXBLDocumentInfo> docInfo;
-  LoadBindingDocumentInfo(aBoundElement, boundDocument, aURI, PR_FALSE,
-                          getter_AddRefs(docInfo));
+  nsresult rv = LoadBindingDocumentInfo(aBoundElement, boundDocument, aURI,
+                                        aOriginPrincipal,
+                                        PR_FALSE, getter_AddRefs(docInfo));
+  NS_ENSURE_SUCCESS(rv, rv);
+  
   if (!docInfo)
     return NS_ERROR_FAILURE;
 
   // Get our doc info and determine our script access.
   nsCOMPtr<nsIDocument> doc;
   docInfo->GetDocument(getter_AddRefs(doc));
   PRBool allowScripts;
   docInfo->GetScriptAccess(&allowScripts);
@@ -825,19 +817,21 @@ nsXBLService::GetBinding(nsIContent* aBo
     return NS_ERROR_FAILURE; // The binding isn't ready yet.
   }
 
   // If our prototype already has a base, then don't check for an "extends" attribute.
   nsRefPtr<nsXBLBinding> baseBinding;
   PRBool hasBase = protoBinding->HasBasePrototype();
   nsXBLPrototypeBinding* baseProto = protoBinding->GetBasePrototype();
   if (baseProto) {
-    nsresult rv = GetBinding(aBoundElement, baseProto->BindingURI(), aPeekOnly,
-                             aIsReady, getter_AddRefs(baseBinding),
-                             aDontExtendURIs);
+    // Use the NodePrincipal() of the <binding> element in question
+    // for the security check.
+    rv = GetBinding(aBoundElement, baseProto->BindingURI(), aPeekOnly,
+                    child->NodePrincipal(), aIsReady,
+                    getter_AddRefs(baseBinding), aDontExtendURIs);
     if (NS_FAILED(rv))
       return rv; // We aren't ready yet.
   }
   else if (hasBase) {
     // Check for the presence of 'extends' and 'display' attributes
     nsAutoString display, extends;
     child->GetAttr(kNameSpaceID_None, nsGkAtoms::display, display);
     child->GetAttr(kNameSpaceID_None, nsGkAtoms::extends, extends);
@@ -894,20 +888,19 @@ nsXBLService::GetBinding(nsIContent* aBo
           }
         }
       }
 
       if (hasExtends && (hasDisplay || nameSpace.IsEmpty())) {
         // Look up the prefix.
         // We have a base class binding. Load it right now.
         nsCOMPtr<nsIURI> bindingURI;
-        nsresult rv =
-          NS_NewURI(getter_AddRefs(bindingURI), value,
-                    doc->GetDocumentCharacterSet().get(),
-                    doc->GetBaseURI());
+        rv = NS_NewURI(getter_AddRefs(bindingURI), value,
+                       doc->GetDocumentCharacterSet().get(),
+                       doc->GetBaseURI());
         NS_ENSURE_SUCCESS(rv, rv);
         
         PRUint32 count = aDontExtendURIs.Length();
         for (PRUint32 index = 0; index < count; ++index) {
           PRBool equal;
           rv = aDontExtendURIs[index]->Equals(bindingURI, &equal);
           NS_ENSURE_SUCCESS(rv, rv);
           if (equal) {
@@ -921,17 +914,20 @@ nsXBLService::GetBinding(nsIContent* aBo
                                             boundDocument->GetDocumentURI(),
                                             EmptyString(), 0, 0,
                                             nsIScriptError::warningFlag,
                                             "XBL");
             return NS_ERROR_ILLEGAL_VALUE;
           }
         }
 
-        rv = GetBinding(aBoundElement, bindingURI, aPeekOnly, aIsReady,
+        // Use the NodePrincipal() of the <binding> element in question
+        // for the security check.
+        rv = GetBinding(aBoundElement, bindingURI, aPeekOnly,
+                        child->NodePrincipal(), aIsReady,
                         getter_AddRefs(baseBinding), aDontExtendURIs);
         if (NS_FAILED(rv))
           return rv; // Binding not yet ready or an error occurred.
         if (!aPeekOnly) {
           // Make sure to set the base prototype.
           baseProto = baseBinding->PrototypeBinding();
           protoBinding->SetBasePrototype(baseProto);
           child->UnsetAttr(kNameSpaceID_None, nsGkAtoms::extends, PR_FALSE);
@@ -955,25 +951,36 @@ nsXBLService::GetBinding(nsIContent* aBo
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXBLService::LoadBindingDocumentInfo(nsIContent* aBoundElement,
                                       nsIDocument* aBoundDocument,
                                       nsIURI* aBindingURI,
+                                      nsIPrincipal* aOriginPrincipal,
                                       PRBool aForceSyncLoad,
                                       nsIXBLDocumentInfo** aResult)
 {
   NS_PRECONDITION(aBindingURI, "Must have a binding URI");
+  NS_PRECONDITION(!aOriginPrincipal || aBoundDocument,
+                  "If we're doing a security check, we better have a document!");
   
   nsresult rv;
-  if (aBoundDocument) {
+  if (aOriginPrincipal) {
+    // Security check - Enforce same-origin policy, except to chrome.
+    // We have to be careful to not pass aContent as the context here. 
+    // Otherwise, if there is a JS-implemented content policy, we will attempt
+    // to wrap the content node, which will try to load XBL bindings for it, if
+    // any. Since we're not done loading this binding yet, that will reenter
+    // this method and we'll end up creating a binding and then immediately
+    // clobbering it in our table.  That makes things very confused, leading to
+    // misbehavior and crashes.
     rv = nsContentUtils::
-      CheckSecurityBeforeLoad(aBindingURI, aBoundDocument->NodePrincipal(),
+      CheckSecurityBeforeLoad(aBindingURI, aOriginPrincipal,
                               nsIScriptSecurityManager::ALLOW_CHROME,
                               PR_TRUE,
                               nsIContentPolicy::TYPE_XBL,
                               aBoundDocument);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   *aResult = nsnull;
--- a/content/xbl/src/nsXBLService.h
+++ b/content/xbl/src/nsXBLService.h
@@ -60,30 +60,36 @@ class nsHashtable;
 
 class nsXBLService : public nsIXBLService,
                      public nsIObserver,
                      public nsSupportsWeakReference
 {
   NS_DECL_ISUPPORTS
 
   // This function loads a particular XBL file and installs all of the bindings
-  // onto the element.
-  NS_IMETHOD LoadBindings(nsIContent* aContent, nsIURI* aURL, PRBool aAugmentFlag,
+  // onto the element.  aOriginPrincipal must not be null here.
+  NS_IMETHOD LoadBindings(nsIContent* aContent, nsIURI* aURL,
+                          nsIPrincipal* aOriginPrincipal, PRBool aAugmentFlag,
                           nsXBLBinding** aBinding, PRBool* aResolveStyle);
 
   // Indicates whether or not a binding is fully loaded.
   NS_IMETHOD BindingReady(nsIContent* aBoundElement, nsIURI* aURI, PRBool* aIsReady);
 
   // Gets the object's base class type.
   NS_IMETHOD ResolveTag(nsIContent* aContent, PRInt32* aNameSpaceID, nsIAtom** aResult);
 
-  // This method checks the hashtable and then calls FetchBindingDocument on a miss.
-  NS_IMETHOD LoadBindingDocumentInfo(nsIContent* aBoundElement, nsIDocument* aBoundDocument,
+  // This method checks the hashtable and then calls FetchBindingDocument on a
+  // miss.  aOriginPrincipal or aBoundDocument may be null to bypass security
+  // checks.
+  NS_IMETHOD LoadBindingDocumentInfo(nsIContent* aBoundElement,
+                                     nsIDocument* aBoundDocument,
                                      nsIURI* aBindingURI,
-                                     PRBool aForceSyncLoad, nsIXBLDocumentInfo** aResult);
+                                     nsIPrincipal* aOriginPrincipal,
+                                     PRBool aForceSyncLoad,
+                                     nsIXBLDocumentInfo** aResult);
 
   // Used by XUL key bindings and for window XBL.
   NS_IMETHOD AttachGlobalKeyHandler(nsPIDOMEventTarget* aTarget);
 
   NS_DECL_NSIOBSERVER
 
 public:
   nsXBLService();
@@ -103,36 +109,39 @@ protected:
 
   nsIXBLDocumentInfo* GetXBLDocumentInfo(nsIURI* aURI,
                                          nsIContent* aBoundElement);
 
   /**
    * This method calls the one below with an empty |aDontExtendURIs| array.
    */
   nsresult GetBinding(nsIContent* aBoundElement, nsIURI* aURI,
-                      PRBool aPeekFlag, PRBool* aIsReady,
-                      nsXBLBinding** aResult);
+                      PRBool aPeekFlag, nsIPrincipal* aOriginPrincipal,
+                      PRBool* aIsReady, nsXBLBinding** aResult);
 
   /**
    * This method loads a binding doc and then builds the specific binding
    * required. It can also peek without building.
    * @param aBoundElement the element to get a binding for
    * @param aURI the binding URI
    * @param aPeekFlag if true then just peek to see if the binding is ready
    * @param aIsReady [out] if the binding is ready or not
    * @param aResult [out] where to store the resulting binding (not used if
    *                      aPeekFlag is true, otherwise it must be non-null)
    * @param aDontExtendURIs a set of URIs that are already bound to this
    *        element. If a binding extends any of these then further loading
    *        is aborted (because it would lead to the binding extending itself)
    *        and NS_ERROR_ILLEGAL_VALUE is returned.
+   *
+   * @note This method always calls LoadBindingDocumentInfo(), so it's
+   *       enough to funnel all security checks through that function.
    */
   nsresult GetBinding(nsIContent* aBoundElement, nsIURI* aURI,
-                      PRBool aPeekFlag, PRBool* aIsReady,
-                      nsXBLBinding** aResult,
+                      PRBool aPeekFlag, nsIPrincipal* aOriginPrincipal,
+                      PRBool* aIsReady, nsXBLBinding** aResult,
                       nsTArray<nsIURI*>& aDontExtendURIs);
 
 // MEMBER VARIABLES
 public:
   static PRUint32 gRefCnt;                   // A count of XBLservice instances.
 
   static PRBool gDisableChromeCache;
 
--- a/content/xbl/src/nsXBLWindowKeyHandler.cpp
+++ b/content/xbl/src/nsXBLWindowKeyHandler.cpp
@@ -114,29 +114,31 @@ void nsXBLSpecialDocInfo::LoadDocInfo()
   // Obtain the platform doc info
   nsCOMPtr<nsIURI> bindingURI;
   NS_NewURI(getter_AddRefs(bindingURI), sHTMLBindingStr);
   if (!bindingURI) {
     return;
   }
   xblService->LoadBindingDocumentInfo(nsnull, nsnull,
                                       bindingURI,
+                                      nsnull,
                                       PR_TRUE, 
                                       getter_AddRefs(mHTMLBindings));
 
   const nsAdoptingCString& userHTMLBindingStr =
     nsContentUtils::GetCharPref("dom.userHTMLBindings.uri");
   if (!userHTMLBindingStr.IsEmpty()) {
     NS_NewURI(getter_AddRefs(bindingURI), userHTMLBindingStr);
     if (!bindingURI) {
       return;
     }
 
     xblService->LoadBindingDocumentInfo(nsnull, nsnull,
                                         bindingURI,
+                                        nsnull,
                                         PR_TRUE, 
                                         getter_AddRefs(mUserHTMLBindings));
   }
 }
 
 //
 // GetHandlers
 //
--- a/content/xul/templates/public/nsIXULTemplateQueryProcessor.idl
+++ b/content/xul/templates/public/nsIXULTemplateQueryProcessor.idl
@@ -14,16 +14,17 @@
  *
  * The Original Code is mozilla.org code.
  *
  * The Initial Developer of the Original Code is Neil Deakin.
  * Portions created by the Initial Developer are Copyright (C) 2005
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s):
+ *  Laurent Jouanneau <laurent.jouanneau@disruptive-innovations.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
@@ -33,16 +34,17 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "domstubs.idl"
 #include "nsISupports.idl"
 
 interface nsIAtom;
+interface nsIArray;
 interface nsISimpleEnumerator;
 interface nsIXULTemplateResult;
 interface nsIXULTemplateRuleFilter;
 interface nsIXULTemplateBuilder;
 
 /**
  * A query processor takes a template query and generates results for it given
  * a datasource and a reference point. There is a one-to-one relationship
@@ -100,20 +102,49 @@ interface nsIXULTemplateBuilder;
  * initializeForBuilding, compileQuery and addBinding methods may not be
  * called after generateResults has been called until the builder indicates
  * that the generated output is being removed by calling the done method.
  *
  * Currently, the datasource supplied to the methods will always be an
  * nsIRDFDataSource or a DOM node, and will always be the same one in between
  * calls to initializeForBuilding and done.
  */
-[scriptable, uuid(11c63d9e-0c0c-444f-b252-f06c546c2ec7)]
+[scriptable, uuid(970f1c36-5d2e-4cbc-a1cf-e3327b50df71)]
 interface nsIXULTemplateQueryProcessor : nsISupports
 {
   /**
+   * Retrieve the datasource to use for the query processor. The list of
+   * datasources in a template is specified using the datasources attribute as
+   * a space separated list of URIs. This list is processed by the builder and
+   * supplied to the query processor in the aDataSources array as a list of
+   * nsIURI objects or nsIDOMNode objects. This method may return an object
+   * corresponding to these URIs and the builder will supply this object to
+   * other query processor methods. For example, for an XML source, the
+   * datasource might be an nsIDOMNode.
+   * All of these URIs are checked by the builder so it is safe to use them.
+   * If the query processor needs to load the datasource asynchronously, it
+   * may set the aShouldDelayBuilding returned parameter to true to delay
+   * building the template content, and call the builder's Rebuild method when
+   * the data is available.
+   *
+   * @param aDataSources  the list of nsIURI objects and/or nsIDOMNode objects
+   * @param aRootNode     the root node the builder is attached to
+   * @param aIsTrusted    true if the template is in a trusted document
+   * @param aBuilder      the template builder
+   * @param aShouldDelayBuilding [out] whether the builder should wait to
+   *                                   build the content or not
+   * @returns a datasource object
+   */
+  nsISupports getDatasource(in nsIArray aDataSources,
+                            in nsIDOMNode aRootNode,
+                            in boolean aIsTrusted,
+                            in nsIXULTemplateBuilder aBuilder,
+                            out boolean aShouldDelayBuilding);
+
+  /**
    * Initialize for query generation. This will be called before the rules are
    * processed and whenever the template is rebuilt. This method must be
    * called once before any of the other query processor methods except for
    * translateRef.
    *
    * @param aDatasource datasource for the data
    * @param aBuilder the template builder
    * @param aRootNode the root node the builder is attached to
--- a/content/xul/templates/src/nsXULTemplateBuilder.cpp
+++ b/content/xul/templates/src/nsXULTemplateBuilder.cpp
@@ -21,16 +21,17 @@
  *
  * Contributor(s):
  *   Robert Churchill <rjc@netscape.com>
  *   David Hyatt <hyatt@netscape.com>
  *   Chris Waterson <waterson@netscape.com>
  *   Pierre Phaneuf <pp@ludusdesign.com>
  *   Joe Hewitt <hewitt@netscape.com>
  *   Neil Deakin <enndeakin@sympatico.ca>
+ *   Laurent Jouanneau <laurent.jouanneau@disruptive-innovations.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
@@ -76,16 +77,17 @@
 #include "nsIXULTemplateBuilder.h"
 #include "nsIXULBuilderListener.h"
 #include "nsIRDFRemoteDataSource.h"
 #include "nsIRDFService.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsIServiceManager.h"
 #include "nsISimpleEnumerator.h"
 #include "nsISupportsArray.h"
+#include "nsIMutableArray.h"
 #include "nsIURL.h"
 #include "nsIXPConnect.h"
 #include "nsContentCID.h"
 #include "nsRDFCID.h"
 #include "nsXULContentUtils.h"
 #include "nsString.h"
 #include "nsVoidArray.h"
 #include "nsXPIDLString.h"
@@ -1085,16 +1087,17 @@ nsXULTemplateBuilder::ContentRemoved(nsI
         if (xulcontent) {
             xulcontent->ClearLazyState(nsXULElement::eTemplateContentsBuilt);
             xulcontent->ClearLazyState(nsXULElement::eContainerContentsBuilt);
         }
 
         mDB = nsnull;
         mCompDB = nsnull;
         mRoot = nsnull;
+        mDataSource = nsnull;
     }
 }
 
 void
 nsXULTemplateBuilder::NodeWillBeDestroyed(const nsINode* aNode)
 {
     // The call to RemoveObserver could release the last reference to
     // |this|, so hold another reference.
@@ -1129,45 +1132,24 @@ nsXULTemplateBuilder::LoadDataSources(ns
     nsresult rv;
     PRBool isRDFQuery = PR_FALSE;
   
     // we'll set these again later, after we create a new composite ds
     mDB = nsnull;
     mCompDB = nsnull;
     mDataSource = nsnull;
 
-    *aShouldDelayBuilding = PR_TRUE;
+    *aShouldDelayBuilding = PR_FALSE;
 
     nsAutoString datasources;
     mRoot->GetAttr(kNameSpaceID_None, nsGkAtoms::datasources, datasources);
 
     nsAutoString querytype;
     mRoot->GetAttr(kNameSpaceID_None, nsGkAtoms::querytype, querytype);
 
-    // if the datasources begins with '#', it is a reference to a node
-    // within the same document.
-    PRBool shouldLoadUrls = PR_TRUE;
-    if (datasources.CharAt(0) == '#') {
-        shouldLoadUrls = PR_FALSE;
-
-        if (querytype.IsEmpty()) {
-            querytype.AssignLiteral("xml");
-        }
-
-        nsCOMPtr<nsIDOMDocument> domdoc = do_QueryInterface(aDocument);
-
-        nsCOMPtr<nsIDOMElement> dsnode;
-        domdoc->GetElementById(Substring(datasources, 1),
-                               getter_AddRefs(dsnode));
-        if (dsnode) {
-            mDataSource = dsnode;
-            *aShouldDelayBuilding = PR_FALSE;
-        }
-    }
-  
     // create the query processor. The querytype attribute on the root element
     // may be used to create one of a specific type.
   
     // XXX should non-chrome be restricted to specific names?
     if (querytype.IsEmpty())
         querytype.AssignLiteral("rdf");
 
     if (querytype.EqualsLiteral("rdf")) {
@@ -1175,30 +1157,26 @@ nsXULTemplateBuilder::LoadDataSources(ns
         mQueryProcessor = new nsXULTemplateQueryProcessorRDF();
         NS_ENSURE_TRUE(mQueryProcessor, NS_ERROR_OUT_OF_MEMORY);
     }
     else if (querytype.EqualsLiteral("xml")) {
         mQueryProcessor = new nsXULTemplateQueryProcessorXML();
         NS_ENSURE_TRUE(mQueryProcessor, NS_ERROR_OUT_OF_MEMORY);
     }
     else {
-        shouldLoadUrls = PR_FALSE;
-
         nsCAutoString cid(NS_QUERY_PROCESSOR_CONTRACTID_PREFIX);
         AppendUTF16toUTF8(querytype, cid);
         mQueryProcessor = do_CreateInstance(cid.get(), &rv);
         // XXXndeakin log an error here - bug 321169
         NS_ENSURE_TRUE(mQueryProcessor, rv);
     }
 
-    if (shouldLoadUrls) {
-        rv = LoadDataSourceUrls(aDocument, datasources,
-                                isRDFQuery, aShouldDelayBuilding);
-        NS_ENSURE_SUCCESS(rv, rv);
-    }
+    rv = LoadDataSourceUrls(aDocument, datasources,
+                            isRDFQuery, aShouldDelayBuilding);
+    NS_ENSURE_SUCCESS(rv, rv);
 
     // Now set the database on the element, so that script writers can
     // access it.
     nsCOMPtr<nsIXULDocument> xuldoc = do_QueryInterface(aDocument);
     if (xuldoc)
         xuldoc->SetTemplateBuilderFor(mRoot, this);
 
     if (!mRoot->IsNodeOfType(nsINode::eXUL)) {
@@ -1221,59 +1199,27 @@ nsXULTemplateBuilder::LoadDataSourceUrls
 
     NS_ASSERTION(docPrincipal == mRoot->NodePrincipal(),
                  "Principal mismatch?  Which one to use?");
 
     PRBool isTrusted = PR_FALSE;
     nsresult rv = IsSystemPrincipal(docPrincipal, &isTrusted);
     NS_ENSURE_SUCCESS(rv, rv);
 
-    nsCOMPtr<nsIRDFDataSource> localstore;
-    if (isTrusted) {
-        rv = gRDFService->GetDataSource("rdf:local-store", getter_AddRefs(localstore));
-        NS_ENSURE_SUCCESS(rv, rv);
-    }
-
-    if (aIsRDFQuery) {
-        // create a database for the builder
-        mCompDB = do_CreateInstance(NS_RDF_DATASOURCE_CONTRACTID_PREFIX "composite-datasource");
-        if (! mCompDB) {
-            NS_ERROR("unable to construct new composite data source");
-            return NS_ERROR_UNEXPECTED;
-        }
-
-        // check for magical attributes. XXX move to ``flags''?
-        if (mRoot->AttrValueIs(kNameSpaceID_None,
-                               nsGkAtoms::coalesceduplicatearcs,
-                               nsGkAtoms::_false, eCaseMatters))
-            mCompDB->SetCoalesceDuplicateArcs(PR_FALSE);
-
-        if (mRoot->AttrValueIs(kNameSpaceID_None,
-                               nsGkAtoms::allownegativeassertions,
-                               nsGkAtoms::_false, eCaseMatters))
-            mCompDB->SetAllowNegativeAssertions(PR_FALSE);
-
-        if (localstore) {
-            // If we're a privileged (e.g., chrome) document, then add the
-            // local store as the first data source in the db. Note that
-            // we _might_ not be able to get a local store if we haven't
-            // got a profile to read from yet.
-            rv = mCompDB->AddDataSource(localstore);
-            NS_ASSERTION(NS_SUCCEEDED(rv), "unable to add local store to db");
-            NS_ENSURE_SUCCESS(rv, rv);
-        }
-    }
-
     // Parse datasources: they are assumed to be a whitespace
     // separated list of URIs; e.g.,
     //
     //     rdf:bookmarks rdf:history http://foo.bar.com/blah.cgi?baz=9
     //
     nsIURI *docurl = aDocument->GetDocumentURI();
-  
+
+    nsCOMPtr<nsIMutableArray> uriList = do_CreateInstance(NS_ARRAY_CONTRACTID);
+    if (!uriList)
+        return NS_ERROR_FAILURE;
+
     nsAutoString datasources(aDataSources);
     PRUint32 first = 0;
     while (1) {
         while (first < datasources.Length() && nsCRT::IsAsciiSpace(datasources.CharAt(first)))
             ++first;
 
         if (first >= datasources.Length())
             break;
@@ -1285,28 +1231,42 @@ nsXULTemplateBuilder::LoadDataSourceUrls
         nsAutoString uriStr;
         datasources.Mid(uriStr, first, last - first);
         first = last + 1;
 
         // A special 'dummy' datasource
         if (uriStr.EqualsLiteral("rdf:null"))
             continue;
 
+        if (uriStr.CharAt(0) == '#') {
+            // ok, the datasource is certainly a node of the current document
+            nsCOMPtr<nsIDOMDocument> domdoc = do_QueryInterface(aDocument);
+            nsCOMPtr<nsIDOMElement> dsnode;
+
+            domdoc->GetElementById(Substring(uriStr, 1),
+                                   getter_AddRefs(dsnode));
+
+            if (dsnode)
+                uriList->AppendElement(dsnode, PR_FALSE);
+            continue;
+        }
+
         // N.B. that `failure' (e.g., because it's an unknown
         // protocol) leaves uriStr unaltered.
         NS_MakeAbsoluteURI(uriStr, uriStr, docurl);
 
+        nsCOMPtr<nsIURI> uri;
+        rv = NS_NewURI(getter_AddRefs(uri), uriStr);
+        if (NS_FAILED(rv) || !uri)
+            continue; // Necko will barf if our URI is weird
+
         nsCOMPtr<nsIPrincipal> principal;
         if (!isTrusted) {
             // Our document is untrusted, so check to see if we can
             // load the datasource that they've asked for.
-            nsCOMPtr<nsIURI> uri;
-            rv = NS_NewURI(getter_AddRefs(uri), uriStr);
-            if (NS_FAILED(rv) || !uri)
-                continue; // Necko will barf if our URI is weird
 
             rv = gScriptSecurityManager->GetCodebasePrincipal(uri, getter_AddRefs(principal));
             NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get codebase principal");
             NS_ENSURE_SUCCESS(rv, rv);
 
             PRBool same;
             rv = docPrincipal->Equals(principal, &same);
             NS_ASSERTION(NS_SUCCEEDED(rv), "unable to test same origin");
@@ -1315,100 +1275,52 @@ nsXULTemplateBuilder::LoadDataSourceUrls
             if (! same)
                 continue;
 
             // If we get here, we've run the gauntlet, and the
             // datasource's URI has the same origin as our
             // document. Let it load!
         }
 
-        if (aIsRDFQuery) {
+        uriList->AppendElement(uri, PR_FALSE);
+    }
+
+    nsCOMPtr<nsIDOMNode> rootNode = do_QueryInterface(mRoot);
+    rv = mQueryProcessor->GetDatasource(uriList,
+                                        rootNode,
+                                        isTrusted,
+                                        this,
+                                        aShouldDelayBuilding,
+                                        getter_AddRefs(mDataSource));
+    NS_ENSURE_SUCCESS(rv, rv);
+
+
+    if (aIsRDFQuery && mDataSource) {  
+        // check if we were given an inference engine type
+        nsCOMPtr<nsIRDFInferDataSource> inferDB = do_QueryInterface(mDataSource);
+        if (inferDB) {
             nsCOMPtr<nsIRDFDataSource> ds;
-            nsCAutoString uristrC;
-            uristrC.AssignWithConversion(uriStr);
-
-            rv = gRDFService->GetDataSource(uristrC.get(), getter_AddRefs(ds));
-
-            if (NS_FAILED(rv)) {
-                // This is only a warning because the data source may not
-                // be accessible for any number of reasons, including
-                // security, a bad URL, etc.
-  #ifdef DEBUG
-                nsCAutoString msg;
-                msg.Append("unable to load datasource '");
-                msg.AppendWithConversion(uriStr);
-                msg.Append('\'');
-                NS_WARNING(msg.get());
-  #endif
-                continue;
-            }
-
-            mCompDB->AddDataSource(ds);
+            inferDB->GetBaseDataSource(getter_AddRefs(ds));
+            if (ds)
+                mCompDB = do_QueryInterface(ds);
         }
-        else {
-            nsAutoString emptyStr;
-            nsCOMPtr<nsIDOMDocument> domDocument;
-            rv = nsContentUtils::CreateDocument(emptyStr, emptyStr, nsnull,
-                                                docurl, aDocument->GetBaseURI(),
-                                                docPrincipal,
-                                                getter_AddRefs(domDocument));
-            NS_ENSURE_SUCCESS(rv, rv);
-
-            nsCOMPtr<nsIDOMEventTarget> target = do_QueryInterface(domDocument);
-            target->AddEventListener(NS_LITERAL_STRING("load"), this, PR_FALSE);
-  
-            nsCOMPtr<nsIDOMXMLDocument> xmldoc = do_QueryInterface(domDocument);
-
-            PRBool ok;
-            xmldoc->Load(uriStr, &ok);
-            if (ok) {
-                mDataSource = domDocument;
-                *aShouldDelayBuilding = PR_TRUE;
-            }
-  
-            // only one XML datasource is supported currently
-            break;
-        }
+
+        if (!mCompDB)
+            mCompDB = do_QueryInterface(mDataSource);
+
+        mDB = do_QueryInterface(mDataSource);
     }
-  
-    if (aIsRDFQuery) {
-        // check if we were given an inference engine type
-        nsAutoString infer;
-        mRoot->GetAttr(kNameSpaceID_None, nsGkAtoms::infer, infer);
-        if (!infer.IsEmpty()) {
-            nsCString inferCID(NS_RDF_INFER_DATASOURCE_CONTRACTID_PREFIX);
-            AppendUTF16toUTF8(infer, inferCID);
-            nsCOMPtr<nsIRDFInferDataSource> inferDB =
-                do_CreateInstance(inferCID.get());
-
-            if (inferDB) {
-                inferDB->SetBaseDataSource(mCompDB);
-                mDB = do_QueryInterface(inferDB);
-            } else {
-                NS_WARNING("failed to construct inference engine specified on template");
-            }
-        }
-  
-        if (!mDB)
-            mDB = mCompDB;
-        mDataSource = mDB;
-    }
-    else {
-        mDB = localstore;
+
+    if (!mDB && isTrusted) {
+        gRDFService->GetDataSource("rdf:local-store", getter_AddRefs(mDB));
     }
 
     return NS_OK;
 }
 
-NS_IMETHODIMP
-nsXULTemplateBuilder::HandleEvent(nsIDOMEvent* aEvent)
-{
-    return Rebuild();
-}
-
 nsresult
 nsXULTemplateBuilder::InitHTMLTemplateRoot()
 {
     // Use XPConnect and the JS APIs to whack mDB and this as the
     // 'database' and 'builder' properties onto aElement.
     nsresult rv;
 
     nsCOMPtr<nsIDocument> doc = mRoot->GetDocument();
--- a/content/xul/templates/src/nsXULTemplateBuilder.h
+++ b/content/xul/templates/src/nsXULTemplateBuilder.h
@@ -48,17 +48,16 @@
 #include "nsIContent.h"
 #include "nsIRDFCompositeDataSource.h"
 #include "nsIRDFContainer.h"
 #include "nsIRDFContainerUtils.h"
 #include "nsIRDFDataSource.h"
 #include "nsIRDFObserver.h"
 #include "nsIRDFService.h"
 #include "nsIXULTemplateBuilder.h"
-#include "nsIDOMEventListener.h"
 
 #include "nsFixedSizeAllocator.h"
 #include "nsVoidArray.h"
 #include "nsCOMArray.h"
 #include "nsTArray.h"
 #include "nsDataHashtable.h"
 #include "nsTemplateRule.h"
 #include "nsTemplateMatch.h"
@@ -73,17 +72,16 @@ extern PRLogModuleInfo* gXULTemplateLog;
 class nsIXULDocument;
 class nsIRDFCompositeDataSource;
 
 /**
  * An object that translates an RDF graph into a presentation using a
  * set of rules.
  */
 class nsXULTemplateBuilder : public nsIXULTemplateBuilder,
-                             public nsIDOMEventListener,
                              public nsStubDocumentObserver
 {
 public:
     nsXULTemplateBuilder();
     virtual ~nsXULTemplateBuilder();
 
     nsresult InitGlobals();
 
@@ -96,18 +94,16 @@ public:
     // nsISupports interface
     NS_DECL_CYCLE_COLLECTING_ISUPPORTS
     NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsXULTemplateBuilder,
                                              nsIXULTemplateBuilder)
 
     // nsIXULTemplateBuilder interface
     NS_DECL_NSIXULTEMPLATEBUILDER
 
-    NS_DECL_NSIDOMEVENTLISTENER
-
     // nsIMutationObserver
     NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED
     NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
     NS_DECL_NSIMUTATIONOBSERVER_NODEWILLBEDESTROYED
 
     /**
      * Remove an old result and/or add a new result. This method will retrieve
      * the set of containers where the result could be inserted and either add
--- a/content/xul/templates/src/nsXULTemplateQueryProcessorRDF.cpp
+++ b/content/xul/templates/src/nsXULTemplateQueryProcessorRDF.cpp
@@ -21,16 +21,17 @@
  *
  * Contributor(s):
  *   Robert Churchill <rjc@netscape.com>
  *   David Hyatt <hyatt@netscape.com>
  *   Chris Waterson <waterson@netscape.com>
  *   Pierre Phaneuf <pp@ludusdesign.com>
  *   Joe Hewitt <hewitt@netscape.com>
  *   Neil Deakin <enndeakin@sympatico.ca>
+ *   Laurent Jouanneau <laurent.jouanneau@disruptive-innovations.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
@@ -41,26 +42,28 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsCOMPtr.h"
 #include "nsIDOMNode.h"
 #include "nsIRDFNode.h"
 #include "nsIRDFObserver.h"
 #include "nsIRDFRemoteDataSource.h"
+#include "nsIRDFInferDataSource.h"
 #include "nsIRDFService.h"
 #include "nsRDFCID.h"
 #include "nsIServiceManager.h"
 #include "nsINameSpaceManager.h"
 #include "nsGkAtoms.h"
 #include "nsIDocument.h"
 #include "nsIXULDocument.h"
 #include "nsUnicharUtils.h"
 #include "nsAttrName.h"
 #include "rdf.h"
+#include "nsArrayUtils.h"
 
 #include "nsContentTestNode.h"
 #include "nsRDFConInstanceTestNode.h"
 #include "nsRDFConMemberTestNode.h"
 #include "nsRDFPropertyTestNode.h"
 #include "nsInstantiationNode.h"
 #include "nsRDFTestNode.h"
 #include "nsXULContentUtils.h"
@@ -210,16 +213,129 @@ nsXULTemplateQueryProcessorRDF::InitGlob
     return MemoryElement::Init() ? NS_OK : NS_ERROR_FAILURE;
 }
 
 //----------------------------------------------------------------------
 //
 // nsIXULTemplateQueryProcessor interface
 //
 
+NS_IMETHODIMP
+nsXULTemplateQueryProcessorRDF::GetDatasource(nsIArray* aDataSources,
+                                              nsIDOMNode* aRootNode,
+                                              PRBool aIsTrusted,
+                                              nsIXULTemplateBuilder* aBuilder,
+                                              PRBool* aShouldDelayBuilding,
+                                              nsISupports** aResult)
+{
+    nsCOMPtr<nsIRDFCompositeDataSource> compDB;
+    nsCOMPtr<nsIContent> root = do_QueryInterface(aRootNode);
+    nsresult rv;
+
+    *aResult = nsnull;
+    *aShouldDelayBuilding = PR_FALSE;
+
+    NS_ENSURE_TRUE(root, NS_ERROR_UNEXPECTED);
+
+    // make sure the RDF service is set up
+    rv = InitGlobals();
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    // create a database for the builder
+    compDB = do_CreateInstance(NS_RDF_DATASOURCE_CONTRACTID_PREFIX 
+                               "composite-datasource");
+    if (!compDB) {
+        NS_ERROR("unable to construct new composite data source");
+        return NS_ERROR_UNEXPECTED;
+    }
+
+    // check for magical attributes. XXX move to ``flags''?
+    if (root->AttrValueIs(kNameSpaceID_None,
+                          nsGkAtoms::coalesceduplicatearcs,
+                          nsGkAtoms::_false, eCaseMatters))
+        compDB->SetCoalesceDuplicateArcs(PR_FALSE);
+
+    if (root->AttrValueIs(kNameSpaceID_None,
+                          nsGkAtoms::allownegativeassertions,
+                          nsGkAtoms::_false, eCaseMatters))
+        compDB->SetAllowNegativeAssertions(PR_FALSE);
+
+    if (aIsTrusted) {
+        // If we're a privileged (e.g., chrome) document, then add the
+        // local store as the first data source in the db. Note that
+        // we _might_ not be able to get a local store if we haven't
+        // got a profile to read from yet.
+        nsCOMPtr<nsIRDFDataSource> localstore;
+        rv = gRDFService->GetDataSource("rdf:local-store",
+                                        getter_AddRefs(localstore));
+        NS_ENSURE_SUCCESS(rv, rv);
+
+        rv = compDB->AddDataSource(localstore);
+        NS_ASSERTION(NS_SUCCEEDED(rv), "unable to add local store to db");
+        NS_ENSURE_SUCCESS(rv, rv);
+    }
+
+    PRUint32 length, index;
+    rv = aDataSources->GetLength(&length);
+    NS_ENSURE_SUCCESS(rv,rv);
+
+    for (index = 0; index < length; index++) {
+
+        nsCOMPtr<nsIURI> uri = do_QueryElementAt(aDataSources, index);
+        if (!uri) // we ignore other datasources than uri
+            continue;
+
+        nsCOMPtr<nsIRDFDataSource> ds;
+        nsCAutoString uristrC;
+        uri->GetSpec(uristrC);
+
+        rv = gRDFService->GetDataSource(uristrC.get(), getter_AddRefs(ds));
+
+        if (NS_FAILED(rv)) {
+            // This is only a warning because the data source may not
+            // be accessible for any number of reasons, including
+            // security, a bad URL, etc.
+  #ifdef DEBUG
+            nsCAutoString msg;
+            msg.Append("unable to load datasource '");
+            msg.Append(uristrC);
+            msg.Append('\'');
+            NS_WARNING(msg.get());
+  #endif
+            continue;
+        }
+
+        compDB->AddDataSource(ds);
+    }
+
+
+    // check if we were given an inference engine type
+    nsAutoString infer;
+    nsCOMPtr<nsIRDFDataSource> db;
+    root->GetAttr(kNameSpaceID_None, nsGkAtoms::infer, infer);
+    if (!infer.IsEmpty()) {
+        nsCString inferCID(NS_RDF_INFER_DATASOURCE_CONTRACTID_PREFIX);
+        AppendUTF16toUTF8(infer, inferCID);
+        nsCOMPtr<nsIRDFInferDataSource> inferDB =
+            do_CreateInstance(inferCID.get());
+
+        if (inferDB) {
+            inferDB->SetBaseDataSource(compDB);
+            db = do_QueryInterface(inferDB);
+        }
+        else {
+            NS_WARNING("failed to construct inference engine specified on template");
+        }
+    }
+
+    if (!db)
+        db = compDB;
+
+    return CallQueryInterface(db, aResult);
+}
 
 NS_IMETHODIMP
 nsXULTemplateQueryProcessorRDF::InitializeForBuilding(nsISupports* aDatasource,
                                                       nsIXULTemplateBuilder* aBuilder,
                                                       nsIDOMNode* aRootNode)
 {
     if (!mQueryProcessorRDFInited) {
         nsresult rv = InitGlobals();
--- a/content/xul/templates/src/nsXULTemplateQueryProcessorXML.cpp
+++ b/content/xul/templates/src/nsXULTemplateQueryProcessorXML.cpp
@@ -14,16 +14,17 @@
  *
  * The Original Code is mozilla.org code.
  *
  * The Initial Developer of the Original Code is Neil Deakin
  * Portions created by the Initial Developer are Copyright (C) 2006
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s):
+ *   Laurent Jouanneau <laurent.jouanneau@disruptive-innovations.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
@@ -32,24 +33,33 @@
  * 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 "nsCOMPtr.h"
 #include "nsAutoPtr.h"
 #include "nsIDOMDocument.h"
+#include "nsIDOMXMLDocument.h"
 #include "nsIDOMNode.h"
 #include "nsIDOMNodeList.h"
 #include "nsIDOMElement.h"
+#include "nsIDOMEvent.h"
+#include "nsIDOMEventTarget.h"
 #include "nsIDOMXPathNSResolver.h"
+#include "nsIDocument.h"
+#include "nsIContent.h"
 #include "nsINameSpaceManager.h"
 #include "nsGkAtoms.h"
 #include "nsIServiceManager.h"
 #include "nsUnicharUtils.h"
+#include "nsIURI.h"
+#include "nsIArray.h"
+#include "nsContentUtils.h"
+#include "nsArrayUtils.h"
 
 #include "nsXULTemplateBuilder.h"
 #include "nsXULTemplateQueryProcessorXML.h"
 #include "nsXULTemplateResultXML.h"
 
 NS_IMPL_ISUPPORTS1(nsXMLQuery, nsXMLQuery)
 
 //----------------------------------------------------------------------
@@ -91,23 +101,111 @@ nsXULTemplateResultSetXML::GetNext(nsISu
 }
 
 
 //----------------------------------------------------------------------
 //
 // nsXULTemplateQueryProcessorXML
 //
 
-NS_IMPL_ISUPPORTS1(nsXULTemplateQueryProcessorXML, nsIXULTemplateQueryProcessor)
+NS_IMPL_CYCLE_COLLECTION_CLASS(nsXULTemplateQueryProcessorXML)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsXULTemplateQueryProcessorXML)
+    NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mTemplateBuilder)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsXULTemplateQueryProcessorXML)
+    NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mTemplateBuilder)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
+NS_IMPL_CYCLE_COLLECTING_ADDREF_AMBIGUOUS(nsXULTemplateQueryProcessorXML,
+                                          nsIXULTemplateQueryProcessor)
+NS_IMPL_CYCLE_COLLECTING_RELEASE_AMBIGUOUS(nsXULTemplateQueryProcessorXML,
+                                           nsIXULTemplateQueryProcessor)
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsXULTemplateQueryProcessorXML)
+    NS_INTERFACE_MAP_ENTRY(nsIXULTemplateQueryProcessor)
+    NS_INTERFACE_MAP_ENTRY(nsIDOMEventListener)
+    NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXULTemplateQueryProcessor)
+NS_INTERFACE_MAP_END
+
+NS_IMETHODIMP
+nsXULTemplateQueryProcessorXML::GetDatasource(nsIArray* aDataSources,
+                                              nsIDOMNode* aRootNode,
+                                              PRBool aIsTrusted,
+                                              nsIXULTemplateBuilder* aBuilder,
+                                              PRBool* aShouldDelayBuilding,
+                                              nsISupports** aResult)
+{
+    *aResult = nsnull;
+    *aShouldDelayBuilding = PR_FALSE;
+
+    nsresult rv;
+    PRUint32 length;
+
+    aDataSources->GetLength(&length);
+    if (length == 0)
+        return NS_OK;
+
+    nsCOMPtr<nsIContent> root = do_QueryInterface(aRootNode);
+    if (!root)
+        return NS_ERROR_UNEXPECTED;
+
+    nsCOMPtr<nsIDocument> doc = root->GetCurrentDoc();
+    if (!doc)
+        return NS_ERROR_UNEXPECTED;
+
+    nsIURI *docurl = doc->GetDocumentURI();
+    nsIPrincipal *docPrincipal = doc->NodePrincipal();
+
+    // we get only the first item, because the query processor supports only
+    // one document as a datasource
+
+    nsCOMPtr<nsIDOMNode> node = do_QueryElementAt(aDataSources, 0);
+
+    if (node) {
+        return CallQueryInterface(node, aResult);
+    }
+
+    nsCOMPtr<nsIURI> uri = do_QueryElementAt(aDataSources,0);
+    if (!uri)
+        return NS_ERROR_UNEXPECTED;
+
+    nsAutoString emptyStr;
+    nsCOMPtr<nsIDOMDocument> domDocument;
+    rv = nsContentUtils::CreateDocument(emptyStr, emptyStr, nsnull,
+                                        docurl, doc->GetBaseURI(),
+                                        docPrincipal,
+                                        getter_AddRefs(domDocument));
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    mTemplateBuilder = aBuilder;
+    nsCOMPtr<nsIDOMEventTarget> target = do_QueryInterface(domDocument);
+    target->AddEventListener(NS_LITERAL_STRING("load"), this, PR_FALSE);
+
+    nsCOMPtr<nsIDOMXMLDocument> xmldoc = do_QueryInterface(domDocument);
+
+    PRBool ok;
+    nsCAutoString uristrC;
+    uri->GetSpec(uristrC);
+
+    xmldoc->Load(NS_ConvertUTF8toUTF16(uristrC), &ok);
+
+    if (ok) {
+        *aShouldDelayBuilding = PR_TRUE;
+        return CallQueryInterface(domDocument, aResult);
+    }
+
+    return NS_OK;
+}
 
 NS_IMETHODIMP
 nsXULTemplateQueryProcessorXML::InitializeForBuilding(nsISupports* aDatasource,
                                                       nsIXULTemplateBuilder* aBuilder,
                                                       nsIDOMNode* aRootNode)
 {
+    if (mGenerationStarted)
+        return NS_ERROR_UNEXPECTED;
+
     // the datasource is either a document or a DOM element
     nsCOMPtr<nsIDOMDocument> doc = do_QueryInterface(aDatasource);
     if (doc)
         doc->GetDocumentElement(getter_AddRefs(mRoot));
     else
       mRoot = do_QueryInterface(aDatasource);
     NS_ENSURE_STATE(mRoot);
 
@@ -338,8 +436,34 @@ nsXULTemplateQueryProcessorXML::CreateEx
     if (eval) {
         nsresult rv =
              eval->CreateNSResolver(aNode, getter_AddRefs(nsResolver));
         NS_ENSURE_SUCCESS(rv, rv);
     }
 
     return mEvaluator->CreateExpression(aExpr, nsResolver, aCompiledExpr);
 }
+
+NS_IMETHODIMP
+nsXULTemplateQueryProcessorXML::HandleEvent(nsIDOMEvent* aEvent)
+{
+    NS_PRECONDITION(aEvent, "aEvent null");
+    nsAutoString eventType;
+    aEvent->GetType(eventType);
+
+    if (eventType.EqualsLiteral("load") && mTemplateBuilder) {
+        // remove the listener
+        nsCOMPtr<nsIDOMEventTarget> target;
+        aEvent->GetTarget(getter_AddRefs(target));
+        if (target) {
+            target->RemoveEventListener(NS_LITERAL_STRING("load"), this, PR_FALSE);
+        }
+
+        // rebuild the template
+        nsresult rv = mTemplateBuilder->Rebuild();
+
+        // to avoid leak. we don't need it after...
+        mTemplateBuilder = nsnull;
+
+        return rv;
+    }
+    return NS_OK;
+}
--- a/content/xul/templates/src/nsXULTemplateQueryProcessorXML.h
+++ b/content/xul/templates/src/nsXULTemplateQueryProcessorXML.h
@@ -14,16 +14,17 @@
  *
  * The Original Code is mozilla.org code.
  *
  * The Initial Developer of the Original Code is Neil Deakin
  * Portions created by the Initial Developer are Copyright (C) 2006
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s):
+ *    Laurent Jouanneau <laurent.jouanneau@disruptive-innovations.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
@@ -32,27 +33,30 @@
  * 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 ***** */
 
 #ifndef nsXULTemplateQueryProcessorXML_h__
 #define nsXULTemplateQueryProcessorXML_h__
 
+#include "nsIXULTemplateBuilder.h"
 #include "nsIXULTemplateQueryProcessor.h"
 
 #include "nsISimpleEnumerator.h"
 #include "nsString.h"
 #include "nsCOMArray.h"
 #include "nsRefPtrHashtable.h"
 #include "nsIDOMElement.h"
+#include "nsIDOMEventListener.h"
 #include "nsIDOMXPathExpression.h"
 #include "nsIDOMXPathEvaluator.h"
 #include "nsIDOMXPathResult.h"
 #include "nsXMLBinding.h"
+#include "nsCycleCollectionParticipant.h"
 
 class nsXULTemplateQueryProcessorXML;
 
 #define NS_IXMLQUERY_IID \
   {0x0358d692, 0xccce, 0x4a97, \
     { 0xb2, 0x51, 0xba, 0x8f, 0x17, 0x0f, 0x3b, 0x6f }}
  
 class nsXMLQuery : public nsISupports
@@ -135,30 +139,36 @@ public:
                               nsXMLBindingSet* aBindingSet)
         : mQuery(aQuery),
           mBindingSet(aBindingSet),
           mResults(aResults),
           mPosition(0)
     {}
 };
 
-class nsXULTemplateQueryProcessorXML : public nsIXULTemplateQueryProcessor
+class nsXULTemplateQueryProcessorXML : public nsIXULTemplateQueryProcessor,
+                                       public nsIDOMEventListener
 {
 public:
 
     nsXULTemplateQueryProcessorXML()
         : mGenerationStarted(PR_FALSE)
     {}
 
     // nsISupports interface
-    NS_DECL_ISUPPORTS
+    NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+    NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsXULTemplateQueryProcessorXML,
+                                             nsIXULTemplateQueryProcessor)
 
     // nsIXULTemplateQueryProcessor interface
     NS_DECL_NSIXULTEMPLATEQUERYPROCESSOR
 
+    // nsIDOMEventListener interface
+    NS_DECL_NSIDOMEVENTLISTENER
+
     nsXMLBindingSet*
     GetOptionalBindingsForRule(nsIDOMNode* aRuleNode);
 
     // create an XPath expression from aExpr, using aNode for
     // resolving namespaces
     nsresult
     CreateExpression(const nsAString& aExpr,
                      nsIDOMNode* aNode,
@@ -168,12 +178,14 @@ private:
 
     PRBool mGenerationStarted;
 
     nsRefPtrHashtable<nsISupportsHashKey, nsXMLBindingSet> mRuleToBindingsMap;
 
     nsCOMPtr<nsIDOMElement> mRoot;
 
     nsCOMPtr<nsIDOMXPathEvaluator> mEvaluator;
+
+    nsCOMPtr<nsIXULTemplateBuilder> mTemplateBuilder;
 };
 
 
 #endif // nsXULTemplateQueryProcessorXML_h__
--- a/dom/public/idl/sidebar/nsISidebar.idl
+++ b/dom/public/idl/sidebar/nsISidebar.idl
@@ -39,17 +39,17 @@
 /*
 
   The Sidebar API for 3rd parties
 
 */
 
 #include "nsISupports.idl"
 
-[scriptable, uuid(577cb745-8caf-11d3-aaef-00805f8a4905)]
+[scriptable, uuid(67cf6231-c303-4f7e-b9b1-a0e87772ecfd)]
 interface nsISidebar : nsISupports
 {
     void addPanel(in wstring aTitle, in string aContentURL,
                   in string aCustomizeURL);
     void addPersistentPanel(in wstring aTitle, in string aContentURL,
                             in string aCustomizeURL);
     void addSearchEngine(in string engineURL, in string iconURL,
                          in wstring suggestedTitle, in wstring suggestedCategory);
--- a/dom/src/base/nsDOMClassInfo.cpp
+++ b/dom/src/base/nsDOMClassInfo.cpp
@@ -53,16 +53,17 @@
 #include "nsIConsoleService.h"
 #include "nsIScriptError.h"
 #include "nsXPIDLString.h"
 #include "nsReadableUtils.h"
 #include "nsUnicharUtils.h"
 #include "xptcall.h"
 #include "prprf.h"
 #include "nsTArray.h"
+#include "nsCSSValue.h"
 
 // JavaScript includes
 #include "jsapi.h"
 #include "jsnum.h"
 #include "jsdbgapi.h"
 #include "jscntxt.h"
 
 // General helper includes
@@ -6949,29 +6950,30 @@ nsElementSH::PostCreate(nsIXPConnectWrap
   // constructor, since the constructor can destroy the relevant presshell.
   nsRefPtr<nsXBLBinding> binding;
   {
     // Scope for the nsRefPtr
     nsRefPtr<nsStyleContext> sc = pctx->StyleSet()->ResolveStyleFor(content,
                                                                     nsnull);
     NS_ENSURE_TRUE(sc, NS_ERROR_FAILURE);
 
-    nsIURI *bindingURL = sc->GetStyleDisplay()->mBinding;
+    nsCSSValue::URL *bindingURL = sc->GetStyleDisplay()->mBinding;
     if (!bindingURL) {
       // No binding, nothing left to do here.
       return NS_OK;
     }
 
     // We have a binding that must be installed.
     PRBool dummy;
 
     nsCOMPtr<nsIXBLService> xblService(do_GetService("@mozilla.org/xbl;1"));
     NS_ENSURE_TRUE(xblService, NS_ERROR_NOT_AVAILABLE);
 
-    xblService->LoadBindings(content, bindingURL, PR_FALSE,
+    xblService->LoadBindings(content, bindingURL->mURI,
+                             bindingURL->mOriginPrincipal, PR_FALSE,
                              getter_AddRefs(binding), &dummy);
   }
   
   if (binding) {
     binding->ExecuteAttachedHandler();
   }
 
   return NS_OK;
--- a/extensions/spellcheck/hunspell/src/README.hunspell
+++ b/extensions/spellcheck/hunspell/src/README.hunspell
@@ -29,17 +29,17 @@
 * 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 *******
 
-Hunspell Version: 1.1.6
+Hunspell Version: 1.1.8
 
 Hunspell Author: László Németh
 MySpell Author: Kevin Hendricks & David Einstein
 
 Hunspell is a spell checker and morphological analyser library. Hunspell
 is based on OpenOffice.org's Myspell. Documentation, tests, and examples
 are available at http://hunspell.sourceforge.net.
 
--- a/extensions/spellcheck/hunspell/src/affentry.cpp
+++ b/extensions/spellcheck/hunspell/src/affentry.cpp
@@ -770,24 +770,25 @@ char * SfxEntry::check_twosfx_morph(cons
 }
 #endif // END OF HUNSPELL_EXPERIMENTAL CODE
 
 // get next homonym with same affix
 struct hentry * SfxEntry::get_next_homonym(struct hentry * he, int optflags, AffEntry* ppfx, 
     const FLAG cclass, const FLAG needflag)
 {
     PfxEntry* ep = (PfxEntry *) ppfx;
+    FLAG eFlag = ep ? ep->getFlag() : FLAG_NULL;
 
     while (he->next_homonym) {
         he = he->next_homonym;
         if ((TESTAFF(he->astr, aflag, he->alen) || (ep && ep->getCont() && TESTAFF(ep->getCont(), aflag, ep->getContLen()))) && 
                             ((optflags & aeXPRODUCT) == 0 || 
-                            TESTAFF(he->astr, ep->getFlag(), he->alen) ||
+                            TESTAFF(he->astr, eFlag, he->alen) ||
                              // handle conditional suffix
-                            ((contclass) && TESTAFF(contclass, ep->getFlag(), contclasslen))
+                            ((contclass) && TESTAFF(contclass, eFlag, contclasslen))
                             ) &&
                             // handle cont. class
                             ((!cclass) || 
                                 ((contclass) && TESTAFF(contclass, cclass, contclasslen))
                             ) &&
                             // handle required flag
                             ((!needflag) || 
                               (TESTAFF(he->astr, needflag, he->alen) ||
--- a/extensions/spellcheck/hunspell/src/affixmgr.cpp
+++ b/extensions/spellcheck/hunspell/src/affixmgr.cpp
@@ -2988,17 +2988,17 @@ int AffixMgr::get_checksharps()
 {
   return checksharps;
 }
 
 // return the preferred ignore string for suggestions
 char * AffixMgr::get_ignore()
 {
   if (!ignorechars) return NULL;
-  return mystrdup(ignorechars);
+  return ignorechars;
 }
 
 // return the preferred ignore string for suggestions
 unsigned short * AffixMgr::get_ignore_utf16(int * len)
 {
   *len = ignorechars_utf16_len;
   return ignorechars_utf16;
 }
@@ -3931,72 +3931,72 @@ int  AffixMgr::parse_affix(char * line, 
           build_sfxtree((AffEntry *)sfxptr); 
       }
       nptr++;
    }      
    free(ptr);
    return 0;
 }
 
-int AffixMgr::redundant_condition(char ft, char * strip, int stripl, const char * cond, char * line) {
+int AffixMgr::redundant_condition(char ft, char * strip, int stripl, const char * cond, char * WARNVAR) {
   int condl = strlen(cond);
   int i;
   int j;
   int neg;
   int in;
   if (ft == 'P') { // prefix
     if (strncmp(strip, cond, condl) == 0) return 1;
     if (utf8) {
     } else {
       for (i = 0, j = 0; (i < stripl) && (j < condl); i++, j++) {
         if (cond[j] != '[') {
           if (cond[j] != strip[i]) {
-            HUNSPELL_WARNING(stderr, "warning: incompatible stripping characters and condition:\n%s\n", line);
+            HUNSPELL_WARNING(stderr, "warning: incompatible stripping characters and condition:\n%s\n", warnvar);
           }
         } else {
           neg = (cond[j+1] == '^') ? 1 : 0;
           in = 0;
           do {
             j++;
             if (strip[i] == cond[j]) in = 1;
           } while ((j < (condl - 1)) && (cond[j] != ']'));
           if (j == (condl - 1) && (cond[j] != ']')) {
-            HUNSPELL_WARNING(stderr, "error: missing ] in condition:\n%s\n", line);
+            HUNSPELL_WARNING(stderr, "error: missing ] in condition:\n%s\n", warnvar);
             return 0;
           }
           if ((!neg && !in) || (neg && in)) {
-            HUNSPELL_WARNING(stderr, "warning: incompatible stripping characters and condition:\n%s\n", line);
+            HUNSPELL_WARNING(stderr, "warning: incompatible stripping characters and condition:\n%s\n", warnvar);
             return 0;          
           }
         }
       }
       if (j >= condl) return 1;
     }
   } else { // suffix
     if ((stripl >= condl) && strcmp(strip + stripl - condl, cond) == 0) return 1;
     if (utf8) {
     } else {
       for (i = stripl - 1, j = condl - 1; (i >= 0) && (j >= 0); i--, j--) {
         if (cond[j] != ']') {
           if (cond[j] != strip[i]) {
-            HUNSPELL_WARNING(stderr, "warning: incompatible stripping characters and condition:\n%s\n", line);
+            HUNSPELL_WARNING(stderr, "warning: incompatible stripping characters and condition:\n%s\n", warnvar);
           }
         } else {
           in = 0;
           do {
             j--;
             if (strip[i] == cond[j]) in = 1;
           } while ((j > 0) && (cond[j] != '['));
           if ((j == 0) && (cond[j] != '[')) {
-            HUNSPELL_WARNING(stderr, "error: missing ] in condition:\n%s\n", line);
+            HUNSPELL_WARNING(stderr, "error: missing ] in condition:\n%s\n", warnvar);
             return 0;
           }
           neg = (cond[j+1] == '^') ? 1 : 0;
           if ((!neg && !in) || (neg && in)) {
-            HUNSPELL_WARNING(stderr, "warning: incompatible stripping characters and condition:\n%s\n", line);
+            HUNSPELL_WARNING(stderr, "warning: incompatible stripping characters and condition:\n%s\n", warnvar);
             return 0;          
           }
         }
       }
       if (j < 0) return 1;
     }    
   }
   return 0;
--- a/extensions/spellcheck/hunspell/src/atypes.hxx
+++ b/extensions/spellcheck/hunspell/src/atypes.hxx
@@ -55,18 +55,20 @@
  ******* END LICENSE BLOCK *******/
 
 #ifndef _ATYPES_HXX_
 #define _ATYPES_HXX_
 
 #ifndef HUNSPELL_WARNING
 #ifdef HUNSPELL_WARNING_ON
 #define HUNSPELL_WARNING fprintf
+#define WARNVAR warnvar
 #else
-#define HUNSPELL_WARNING
+#define HUNSPELL_WARNING(a,b,...) {}
+#define WARNVAR
 #endif
 #endif
 
 // HUNSTEM def.
 #define HUNSTEM
 
 #include "csutil.hxx"
 #include "hashmgr.hxx"
--- a/extensions/spellcheck/hunspell/src/csutil.cpp
+++ b/extensions/spellcheck/hunspell/src/csutil.cpp
@@ -96,18 +96,18 @@ static NS_DEFINE_CID(kUnicharUtilCID, NS
 using namespace std;
 #endif
 #else
 #ifndef W32
 using namespace std;
 #endif
 #endif
 
-struct unicode_info2 * utf_tbl = NULL;
-int utf_tbl_count = 0; // utf_tbl can be used by multiple Hunspell instances
+static struct unicode_info2 * utf_tbl = NULL;
+static int utf_tbl_count = 0; // utf_tbl can be used by multiple Hunspell instances
 
 /* only UTF-16 (BMP) implementation */
 char * u16_u8(char * dest, int size, const w_char * src, int srclen) {
     char * u8 = dest;
     char * u8_max = u8 + size;
     const w_char * u2 = src;
     const w_char * u2_max = src + srclen;
     while ((u2 < u2_max) && (u8 < u8_max)) {
@@ -153,17 +153,17 @@ char * u16_u8(char * dest, int size, con
 
 
 /* only UTF-16 (BMP) implementation */
 int u8_u16(w_char * dest, int size, const char * src) {
     const char * u8 = src;
     w_char * u2 = dest;
     w_char * u2_max = u2 + size;
     
-    while (*u8 && (u2 < u2_max)) {
+    while ((u2 < u2_max) && *u8) {
     switch ((*u8) & 0xf0) {
         case 0x00:
         case 0x10:
         case 0x20:
         case 0x30:
         case 0x40:
         case 0x50:
         case 0x60:
@@ -284,25 +284,29 @@ int flag_bsearch(unsigned short flags[],
         // that's way different than the locale's
         for (dp = mp; (*dp && *dp != ' ' && *dp != '\t'); dp++);
         if (!*dp) dp = NULL;
       }
       if (dp) {
          *stringp = dp+1;
          int nc = (int)((unsigned long)dp - (unsigned long)mp);
          rv = (char *) malloc(nc+1);
-         memcpy(rv,mp,nc);
-         *(rv+nc) = '\0';
-         return rv;
+	 if (rv) {
+            memcpy(rv,mp,nc);
+            *(rv+nc) = '\0';
+            return rv;
+	 }
       } else {
-        rv = (char *) malloc(n+1);
-        memcpy(rv, mp, n);
-        *(rv+n) = '\0';
-        *stringp = mp + n;
-        return rv;
+         rv = (char *) malloc(n+1);
+         if (rv) {
+    	    memcpy(rv, mp, n);
+            *(rv+n) = '\0';
+            *stringp = mp + n;
+            return rv;
+         }
       }
    }
    return NULL;
  }
 
  
  // replaces strdup with ansi version
  char * mystrdup(const char * s)
@@ -5181,17 +5185,17 @@ int initialize_utf_tbl() {
     }
   } else return 1;
   return 0;
 }
 #endif
 #endif
 
 void free_utf_tbl() {
-  if (utf_tbl_count > 0) utf_tbl--;
+  if (utf_tbl_count > 0) utf_tbl_count--;
   if (utf_tbl && (utf_tbl_count == 0)) {
     free(utf_tbl);
     utf_tbl = NULL;
   }
 }
 
 #ifdef MOZILLA_CLIENT
 static nsCOMPtr<nsICaseConversion>& getcaseConv()
@@ -5339,24 +5343,24 @@ void remove_ignored_chars(char * word, c
       if (!strchr(ignored_chars, *p)) {
         *word = *p;
         word++;
       }
    }
    *word = '\0';
 }
 
-int parse_string(char * line, char ** out, const char * name)
+int parse_string(char * line, char ** out, const char * WARNVAR)
 {
    char * tp = line;
    char * piece;
    int i = 0;
    int np = 0;
    if (*out) {
-      HUNSPELL_WARNING(stderr, "error: duplicate %s line\n", name);
+      HUNSPELL_WARNING(stderr, "error: duplicate %s line\n", warnvar);
       return 1;
    }
    piece = mystrsep(&tp, 0);
    while (piece) {
       if (*piece != '\0') {
           switch(i) {
               case 0: { np++; break; }
               case 1: { 
@@ -5367,17 +5371,17 @@ int parse_string(char * line, char ** ou
               default: break;
           }
           i++;
       }
       free(piece);
       piece = mystrsep(&tp, 0);
    }
    if (np != 2) {
-      HUNSPELL_WARNING(stderr, "error: missing %s information\n", name);
+      HUNSPELL_WARNING(stderr, "error: missing %s information\n", warnvar);
       return 1;
    } 
    return 0;
 }
 
 int parse_array(char * line, char ** out,
         unsigned short ** out_utf16, int * out_utf16_len, const char * name, int utf8) {
    if (parse_string(line, out, name)) return 1;
--- a/extensions/spellcheck/hunspell/src/hashmgr.cpp
+++ b/extensions/spellcheck/hunspell/src/hashmgr.cpp
@@ -155,16 +155,22 @@ HashMgr::~HashMgr()
     }
   }
   if (aliasm) {
     for (int j = 0; j < (numaliasm); j++) free(aliasm[j]);
     free(aliasm);
     aliasm = NULL;
   }  
 
+#ifndef OPENOFFICEORG
+#ifndef MOZILLA_CLIENT
+  if (utf8) free_utf_tbl();
+#endif
+#endif
+
   if (enc) free(enc);
   if (lang) free(lang);
   
   if (ignorechars) free(ignorechars);
   if (ignorechars_utf16) free(ignorechars_utf16);
 }
 
 // lookup a root word in the hashtable
@@ -180,17 +186,21 @@ struct hentry * HashMgr::lookup(const ch
        }
     }
     return NULL;
 }
 
 // add a word to the hash table (private)
 
 int HashMgr::add_word(const char * word, int wl, unsigned short * aff,
-    int al, const char * desc, bool onlyupcase)
+    int al, const char *
+#ifdef HUNSPELL_EXPERIMENTAL
+desc
+#endif
+, bool onlyupcase)
 {
     char * st = mystrdup(word);
     bool upcasehomonym = false;
     if (wl && !st) return 1;
     if (ignorechars != NULL) {
       if (utf8) {
         remove_ignored_chars_utf(st, ignorechars_utf16, ignorechars_utf16_len);
       } else {
@@ -217,41 +227,53 @@ int HashMgr::add_word(const char * word,
             if (desc && !dp->description) return 1;
             if (dp->description && complexprefixes) {
                 if (utf8) reverseword_utf(dp->description); else reverseword(dp->description);
             }
        }
 #endif
     } else {
        struct hentry* hp = (struct hentry *) malloc (sizeof(struct hentry));
-       if (!hp) return 1;
+       if (!hp)
+       {
+           if (st) free(st);
+           return 1;
+       }
        hp->wlen = (short) wl;
        hp->alen = (short) al;
        hp->word = st;
        hp->astr = aff;
        hp->next = NULL;      
        hp->next_homonym = NULL;
 #ifdef HUNSPELL_EXPERIMENTAL       
        if (aliasm) {
             hp->description = (desc) ? get_aliasm(atoi(desc)) : mystrdup(desc);
        } else {
             hp->description = mystrdup(desc);
-            if (desc && !hp->description) return 1;
+            if (desc && !hp->description)
+            {
+                free(hp->word);
+                free(hp->astr);
+                free(hp);
+                return 1;
+            }
             if (dp->description && complexprefixes) {
                 if (utf8) reverseword_utf(hp->description); else reverseword(hp->description);
             }
        }
 #endif
        while (dp->next != NULL) {
          if ((!dp->next_homonym) && (strcmp(hp->word, dp->word) == 0)) {
     	    // remove hidden onlyupcase homonym
             if (!onlyupcase) {
 		if ((dp->astr) && TESTAFF(dp->astr, ONLYUPCASEFLAG, dp->alen)) {
 		    free(dp->astr);
 		    dp->astr = hp->astr;
+		    dp->alen = hp->alen;
+		    dp->alen = hp->alen;
 		    free(hp->word);
 		    free(hp);
 		    return 0;
 		} else {
     		    dp->next_homonym = hp;
     		}
             } else {
         	upcasehomonym = true;
@@ -303,19 +325,22 @@ int HashMgr::put_word(const char * word,
 }
 
 int HashMgr::put_word_pattern(const char * word, int wl, const char * pattern)
 {
     unsigned short * flags;
     struct hentry * dp = lookup(pattern);
     if (!dp || !dp->astr) return 1;
     flags = (unsigned short *) malloc (dp->alen * sizeof(short));
-    memcpy((void *) flags, (void *) dp->astr, dp->alen * sizeof(short));
-    add_word(word, wl, flags, dp->alen, NULL, false);
-    return 0;
+    if (flags) {
+	memcpy((void *) flags, (void *) dp->astr, dp->alen * sizeof(short));
+	add_word(word, wl, flags, dp->alen, NULL, false);
+        return 0;
+    }
+    return 1;
 }
 
 // walk the hash table entry by entry - null at end
 struct hentry * HashMgr::walk_hashtable(int &col, struct hentry * hp) const
 {
   //reset to start
   if ((col < 0) || (hp == NULL)) {
     col = -1;
@@ -435,25 +460,26 @@ int HashMgr::load_tables(const char * tp
     wl = strlen(ts);
 
     // add the word and its index
     if (add_word(ts,wl,flags,al,dp, false)) {
 	fclose(rawdict);
 	return 5;
     }
 
-    // add decapizatalized forms to handle following cases
-    // OpenOffice.org -> OPENOFFICE.ORG
-    // CIA's -> CIA'S
+    // add inner capitalized forms to handle the following allcap forms:
+    // Mixed caps: OpenOffice.org -> OPENOFFICE.ORG
+    // Allcaps with suffixes: CIA's -> CIA'S
     captype = utf8 ? get_captype_utf8(ts, wl, langnum) : get_captype(ts, wl, csconv);
     if (((captype == HUHCAP) || (captype == HUHINITCAP) ||
       ((captype == ALLCAP) && (flags != NULL))) &&
       !((flags != NULL) && TESTAFF(flags, forbiddenword, al))) {
-          unsigned short * flags2 = (unsigned short *) malloc (sizeof(unsigned short *)* (al + 1));
-          memcpy(flags2, flags, al * sizeof(unsigned short *));
+          unsigned short * flags2 = (unsigned short *) malloc (sizeof(unsigned short) * (al+1));
+	  if (!flags2) return 6;
+          if (al) memcpy(flags2, flags, al * sizeof(unsigned short));
           flags2[al] = ONLYUPCASEFLAG;
           if (utf8) {
               char st[MAXDELEN];
               w_char w[MAXDELEN];
               int wlen = u8_u16(w, MAXDELEN, ts);
               mkallsmall_utf(w, wlen, langnum);
               mkallcap_utf(w, 1, langnum);
               u16_u8(st, MAXDELEN, w, wlen);
@@ -493,32 +519,34 @@ int HashMgr::hash(const char * word) con
 }
 
 int HashMgr::decode_flags(unsigned short ** result, char * flags) {
     int len;
     switch (flag_mode) {
       case FLAG_LONG: { // two-character flags (1x2yZz -> 1x 2y Zz)
         len = strlen(flags);
         if (len%2 == 1) HUNSPELL_WARNING(stderr, "error: length of FLAG_LONG flagvector is odd: %s\n", flags);
-        len = len/2;
+        len /= 2;
         *result = (unsigned short *) malloc(len * sizeof(short));
+        if (!*result) return -1;
         for (int i = 0; i < len; i++) {
             (*result)[i] = (((unsigned short) flags[i * 2]) << 8) + (unsigned short) flags[i * 2 + 1]; 
         }
         break;
       }
       case FLAG_NUM: { // decimal numbers separated by comma (4521,23,233 -> 4521 23 233)
         len = 1;
         char * src = flags; 
         unsigned short * dest;
         char * p;
         for (p = flags; *p; p++) {
           if (*p == ',') len++;
         }
         *result = (unsigned short *) malloc(len * sizeof(short));
+        if (!*result) return -1;
         dest = *result;
         for (p = flags; *p; p++) {
           if (*p == ',') {
             *dest = (unsigned short) atoi(src);
             if (*dest == 0) HUNSPELL_WARNING(stderr, "error: 0 is wrong flag id\n");
             src = p + 1;
             dest++;
           }
@@ -526,23 +554,25 @@ int HashMgr::decode_flags(unsigned short
         *dest = (unsigned short) atoi(src);
         if (*dest == 0) HUNSPELL_WARNING(stderr, "error: 0 is wrong flag id\n");
         break;
       }    
       case FLAG_UNI: { // UTF-8 characters
         w_char w[MAXDELEN/2];
         len = u8_u16(w, MAXDELEN/2, flags);
         *result = (unsigned short *) malloc(len * sizeof(short));
+        if (!*result) return -1;
         memcpy(*result, w, len * sizeof(short));
         break;
       }
       default: { // Ispell's one-character flags (erfg -> e r f g)
         unsigned short * dest;
         len = strlen(flags);
         *result = (unsigned short *) malloc(len * sizeof(short));
+        if (!*result) return -1;
         dest = *result;
         for (unsigned char * p = (unsigned char *) flags; *p; p++) {
           *dest = (unsigned short) *p;
           dest++;
         }
       }
     }      
     return len;
--- a/extensions/spellcheck/hunspell/src/hunspell.cpp
+++ b/extensions/spellcheck/hunspell/src/hunspell.cpp
@@ -127,17 +127,16 @@ Hunspell::~Hunspell()
 // set the capitalization type
 // return the length of the "cleaned" (and UTF-8 encoded) word
 
 int Hunspell::cleanword2(char * dest, const char * src, 
     w_char * dest_utf, int * nc, int * pcaptype, int * pabbrev)
 { 
    unsigned char * p = (unsigned char *) dest;
    const unsigned char * q = (const unsigned char * ) src;
-   int firstcap = 0;
 
    // first skip over any leading blanks
    while ((*q != '\0') && (*q == ' ')) q++;
    
    // now strip off any trailing periods (recording their presence)
    *pabbrev = 0;
    int nl = strlen((const char *)q);
    while ((nl > 0) && (*(q+nl-1)=='.')) {
@@ -151,17 +150,17 @@ int Hunspell::cleanword2(char * dest, co
        *p = '\0';
        return 0;
    }
    
    strncpy(dest, (char *) q, nl);
    *(dest + nl) = '\0';
    nl = strlen(dest);
    if (utf8) {
-      *nc = u8_u16(dest_utf, MAXWORDLEN, (const char *) q);
+      *nc = u8_u16(dest_utf, MAXWORDLEN, dest);
       // don't check too long words
       if (*nc >= MAXWORDLEN) return 0;
       if (*nc == -1) { // big Unicode character (non BMP area)
          *pcaptype = NOCAP;
          return nl;
       }
      *pcaptype = get_captype_utf8(dest, nl, langnum);
    } else {
@@ -431,17 +430,18 @@ int Hunspell::spell(const char * word, i
             if (rv) break;
             if (abbv) {
                 memcpy(wspace,cw,wl);
                 *(wspace+wl) = '.';
                 *(wspace+wl+1) = '\0';
                 rv = checkword(wspace, info, root);
                 if (rv) break;
             }
-            // spec. prefix handling for Italian, etc. (SANT'ELIA -> Sant'+Elia)
+            // Spec. prefix handling for Catalan, French, Italian:
+	    // prefixes separated by apostrophe (SANT'ELIA -> Sant'+Elia).
             if (pAMgr && strchr(cw, '\'')) {
                 wl = mkallsmall2(cw, unicw, nc);
         	char * apostrophe = strchr(cw, '\'');
                 if (utf8) {
             	    w_char tmpword[MAXWORDLEN];
             	    *apostrophe = '\0';
             	    wl2 = u8_u16(tmpword, MAXWORDLEN, cw);
             	    *apostrophe = '\'';
@@ -493,18 +493,20 @@ int Hunspell::spell(const char * word, i
              // (for example, ijs -> Ijs instead of IJs in Dutch)
              // use explicit forms in dic: Ijs/F (F = FORBIDDENWORD flag)
              if (*info & SPELL_FORBIDDEN) {
                 rv = NULL;
                 break;
              }             
              if (rv && is_keepcase(rv) && (captype == ALLCAP)) rv = NULL;
              if (rv) break;
+
              rv = checkword(wspace, info, root);
              if (abbv && !rv) {
+
                  *(wspace+wl) = '.';
                  *(wspace+wl+1) = '\0';
                  rv = checkword(wspace, info, root);
                  if (!rv) {
                     memcpy(wspace, cw, wl2);
                     *(wspace+wl2) = '.';
                     *(wspace+wl2+1) = '\0';
     	    	    if (captype == INITCAP) *info += SPELL_INITCAP;
@@ -520,31 +522,27 @@ int Hunspell::spell(const char * word, i
                    // in INITCAP form, too.
                    !(pAMgr->get_checksharps() &&
                       ((utf8 && strstr(wspace, "\xC3\x9F")) ||
                       (!utf8 && strchr(wspace, '\xDF')))))) rv = NULL;             
              break;
            }               
   }
   
-  // check ONLYUPCASE and return
-//  if (rv && !((captype==INITCAP) && (rv->astr) && (pAMgr) &&
-//	TESTAFF(rv->astr, ONLYUPCASEFLAG, rv->alen))) {
-//    return 1;
-//  }
   if (rv) return 1;
 
   // recursive breaking at break points (not good for morphological analysis)
   if (wordbreak) {
     char * s;
     char r;
     int corr = 0;
     // German words beginning with "-" are not accepted
     if (langnum == LANG_de) corr = 1;
-    for (int j = 0; j < pAMgr->get_numbreak(); j++) {
+    int numbreak = pAMgr ? pAMgr->get_numbreak() : 0;
+    for (int j = 0; j < numbreak; j++) {
       s=(char *) strstr(cw + corr, wordbreak[j]);
       if (s) {
         r = *s;
         *s = '\0';
         // examine 2 sides of the break point
         if (spell(cw) && spell(s + strlen(wordbreak[j]))) {
             *s = r;
             return 1;
@@ -756,24 +754,27 @@ int Hunspell::suggest(char*** slst, cons
                     capwords = 1;
      case HUHCAP: { 
                      ns = pSMgr->suggest(slst, cw, ns);
                      if (ns != -1) {
                         int prevns;
     		        // something.The -> something. The
                         char * dot = strchr(cw, '.');
 		        if (dot && (dot > cw)) {
-		    	    int captype = utf8 ? get_captype_utf8(dot+1, strlen(dot+1), langnum) :
+		    	    int captype_ = utf8 ? get_captype_utf8(dot+1, strlen(dot+1), langnum) :
 		        	get_captype(dot+1, strlen(dot+1), csconv);
-		    	    if (captype == INITCAP) {
+		    	    if (captype_ == INITCAP) {
                         	char * st = mystrdup(cw);
-                        	st = (char *) realloc(st, wl + 1);
-                        	st[(dot - cw) + 1] = ' ';
-                        	strcpy(st + (dot - cw) + 2, dot + 1);
-                    		ns = insert_sug(slst, st, ns);
+                        	st = (char *) realloc(st, wl + 2);
+				if (st) {
+                        		st[(dot - cw) + 1] = ' ';
+                        		strcpy(st + (dot - cw) + 2, dot + 1);
+                    			ns = insert_sug(slst, st, ns);
+					free(st);
+				}
 		    	    }
 		        }
                         if (captype == HUHINITCAP) {
                             // TheOpenOffice.org -> The OpenOffice.org
                             memcpy(wspace,cw,(wl+1));
                             mkinitsmall2(wspace, unicw, nc);
                             ns = pSMgr->suggest(slst, wspace, ns);
                         }
@@ -910,17 +911,17 @@ int Hunspell::suggest(char*** slst, cons
   if (abbv && pAMgr && pAMgr->get_sugswithdots()) {
     for (int j = 0; j < ns; j++) {
       (*slst)[j] = (char *) realloc((*slst)[j], strlen((*slst)[j]) + 1 + abbv);
       strcat((*slst)[j], word + strlen(word) - abbv);
     }
   }
 
   // remove bad capitalized and forbidden forms
-  if (pAMgr->get_keepcase() || pAMgr->get_forbiddenword()) {
+  if (pAMgr && (pAMgr->get_keepcase() || pAMgr->get_forbiddenword())) {
   switch (captype) {
     case INITCAP:
     case ALLCAP: {
       int l = 0;
       for (int j=0; j < ns; j++) {
         if (!strchr((*slst)[j],' ') && !spell((*slst)[j])) {
           char s[MAXSWUTF8L];
           w_char w[MAXSWL];
@@ -1753,17 +1754,22 @@ char * Hunspell::morph_with_correction(c
 /* analyze word
  * return line count 
  * XXX need a better data structure for morphological analysis */
 int Hunspell::analyze(char ***out, const char *word) {
   int  n = 0;
   if (!word) return 0;
   char * m = morph(word);
   if(!m) return 0;
-  if (!out) return line_tok(m, out);
+  if (!out)
+  {
+     n = line_tok(m, out);
+     free(m);
+     return n;
+  }
 
   // without memory allocation
   /* BUG missing buffer size checking */
   int i, p;
   for(p = 0, i = 0; m[i]; i++) {
      if(m[i] == '\n' || !m[i+1]) {
        n++;
        strncpy((*out)[n++], m + p, i - p + 1);
--- a/extensions/spellcheck/hunspell/src/hunspell.hxx
+++ b/extensions/spellcheck/hunspell/src/hunspell.hxx
@@ -64,25 +64,31 @@
 #define  SPELL_FORBIDDEN (1 << 1)
 #define  SPELL_ALLCAP    (1 << 2)
 #define  SPELL_NOCAP     (1 << 3)
 #define  SPELL_INITCAP   (1 << 4)
 
 #define MAXSUGGESTION 15
 #define MAXSHARPS 5
 
-#ifdef W32
-#define DLLTEST2_API __declspec(dllexport)
-#endif
-
 #ifndef _MYSPELLMGR_HXX_
 #define _MYSPELLMGR_HXX_
 
+#ifdef HUNSPELL_STATIC
+	#define DLLEXPORT
+#else
+	#ifdef HUNSPELL_EXPORTS
+		#define DLLEXPORT  __declspec( dllexport )
+	#else
+		#define DLLEXPORT  __declspec( dllimport )
+	#endif
+#endif
+
 #ifdef W32
-class DLLTEST2_API Hunspell
+class DLLEXPORT Hunspell
 #else
 class Hunspell
 #endif
 {
   AffixMgr*       pAMgr;
   HashMgr*        pHMgr;
   SuggestMgr*     pSMgr;
   char *          encoding;
--- a/extensions/spellcheck/hunspell/src/suggestmgr.cpp
+++ b/extensions/spellcheck/hunspell/src/suggestmgr.cpp
@@ -104,17 +104,17 @@ SuggestMgr::SuggestMgr(const char * trym
         complexprefixes = pAMgr->get_complexprefixes();
   }
 
   if (tryme) {  
     if (utf8) {
         w_char t[MAXSWL];    
         ctryl = u8_u16(t, MAXSWL, tryme);
         ctry_utf = (w_char *) malloc(ctryl * sizeof(w_char));
-        memcpy(ctry_utf, t, ctryl * sizeof(w_char));
+        if (ctry_utf) memcpy(ctry_utf, t, ctryl * sizeof(w_char));
     } else {
         ctry = mystrdup(tryme);
         ctryl = strlen(ctry);
     }
   }
 }
 
 
@@ -497,17 +497,16 @@ int SuggestMgr::doubletwochars(char** wl
       }
   }
   return ns;
 }
 
 // perhaps we doubled two characters (pattern aba -> ababa, for example vacation -> vacacation)
 int SuggestMgr::doubletwochars_utf(char ** wlst, const w_char * word, int wl, int ns, int cpdsuggest)
 {
-  w_char        tmpc;
   w_char        candidate_utf[MAXSWL];
   char          candidate[MAXSWUTF8L];
   int state=0;
   if (wl < 5 || ! pAMgr) return ns;
   for (int i=2; i < wl; i++) {
       if ((word[i].l==word[i-2].l) && (word[i].h==word[i-2].h))  {
           state++;
           if (state==3) {
@@ -615,17 +614,16 @@ int SuggestMgr::extrachar(char** wlst, c
 
 
 // error is missing a letter it needs
 int SuggestMgr::forgotchar(char ** wlst, const char * word, int ns, int cpdsuggest)
 {
    char candidate[MAXSWUTF8L];
    const char * p;
    char *       q;
-   int cwrd;
    time_t timelimit = time(NULL);
    int timer = MINTIMER;
    int wl = strlen(word);
    // try inserting a tryme character before every letter
    strcpy(candidate + 1, word);
    for (p = word, q = candidate;  *p != 0;  )  {
       for (int i = 0;  i < ctryl;  i++) {
          *q = ctry[i];
@@ -816,16 +814,17 @@ int SuggestMgr::longswapchar_utf(char **
    // try swapping not adjacent chars
    memcpy (candidate_utf, word, wl * sizeof(w_char));
    for (p = candidate_utf;  p < (candidate_utf + wl);  p++) {
      for (q = candidate_utf;  q < (candidate_utf + wl);  q++) {
        if (abs(p-q) > 1) {
          tmpc = *p;
          *p = *q;
          *q = tmpc;
+         u16_u8(candidate, MAXSWUTF8L, candidate_utf, wl);
          ns = testsug(wlst, candidate, strlen(candidate), ns, cpdsuggest, NULL, NULL);
          if (ns == -1) return -1;
          *q = *p;
          *p = tmpc;
        }
      }
    }
    return ns;
@@ -1463,25 +1462,26 @@ char * SuggestMgr::suggest_morph(const c
     
     return (*result) ? mystrdup(line_uniq(delete_zeros(result))) : NULL;
 }
 
 char * SuggestMgr::suggest_morph_for_spelling_error(const char * word)
 {
     char * p = NULL;
     char ** wlst = (char **) calloc(maxSug, sizeof(char *));
+    if (!**wlst) return NULL;
     // we will use only the first suggestion
     for (int i = 0; i < maxSug - 1; i++) wlst[i] = "";
     int ns = suggest(&wlst, word, maxSug - 1);
     if (ns == maxSug) {
         p = suggest_morph(wlst[maxSug - 1]);
         free(wlst[maxSug - 1]);
     }
     if (wlst) free(wlst);
-    return p;    
+    return p;
 }
 #endif // END OF HUNSPELL_EXPERIMENTAL CODE
 
 
 // generate an n-gram score comparing s1 and s2
 int SuggestMgr::ngram(int n, char * s1, const char * s2, int uselen)
 {
   int nscore = 0;
@@ -1664,16 +1664,22 @@ void SuggestMgr::lcs(const char * s, con
     m = u8_u16(su, MAXSWL, s);
     n = u8_u16(su2, MAXSWL, s2);
   } else {
     m = strlen(s);
     n = strlen(s2);
   }
   c = (char *) malloc((m + 1) * (n + 1));
   b = (char *) malloc((m + 1) * (n + 1));
+  if (!c || !b) {
+    if (c) free(c);
+    if (b) free(b);
+    *result = NULL;
+    return;
+  }
   for (i = 1; i <= m; i++) c[i*(n+1)] = 0;
   for (j = 0; j <= n; j++) c[j] = 0;
   for (i = 1; i <= m; i++) {
     for (j = 1; j <= n; j++) {
       if ((utf8) && (*((short *) su+i-1) == *((short *)su2+j-1))
           || (!utf8) && ((*(s+i-1)) == (*(s2+j-1)))) {
         c[i*(n+1) + j] = c[(i-1)*(n+1) + j-1]+1;
         b[i*(n+1) + j] = LCS_UPLEFT;
@@ -1695,22 +1701,23 @@ void SuggestMgr::lcs(const char * s, con
 int SuggestMgr::lcslen(const char * s, const char* s2) {
   int m;
   int n;
   int i;
   int j;
   char * result;
   int len = 0;
   lcs(s, s2, &m, &n, &result);
+  if (!result) return 0;
   i = m;
   j = n;
   while ((i != 0) && (j != 0)) {
     if (result[i*(n+1) + j] == LCS_UPLEFT) {
       len++;
       i--;
       j--;
     } else if (result[i*(n+1) + j] == LCS_UP) {
       i--;
     } else j--;
   }
-  if (result) free(result);
+  free(result);
   return len;
 }
--- a/gfx/thebes/public/gfxTypes.h
+++ b/gfx/thebes/public/gfxTypes.h
@@ -41,17 +41,17 @@
 #include "prtypes.h"
 
 /**
  * Currently needs to be 'double' for Cairo compatibility. Could
  * become 'float', perhaps, in some configurations.
  */
 typedef double gfxFloat;
 
-#if defined(MOZ_ENABLE_LIBXUL) || defined(MOZ_STATIC_BUILD)
+#if defined(MOZ_STATIC_BUILD)
 # define THEBES_API
 #elif defined(IMPL_THEBES)
 # define THEBES_API NS_EXPORT
 #else
 # define THEBES_API NS_IMPORT
 #endif
 
 /**
--- a/intl/build/Makefile.in
+++ b/intl/build/Makefile.in
@@ -101,8 +101,18 @@ EXTRA_DSO_LDOPTS = \
 ifneq (,$(filter mac cocoa,$(MOZ_WIDGET_TOOLKIT)))
 EXTRA_DSO_LDOPTS += \
         $(TK_LIBS) \
         $(NULL)
 endif
 
 include $(topsrcdir)/config/rules.mk
 
+ifdef MOZ_ENABLE_PANGO
+CXXFLAGS	+= \
+		$(MOZ_PANGO_CFLAGS) \
+		$(NULL)
+
+EXTRA_DSO_LDOPTS += \
+		$(MOZ_PANGO_LIBS) \
+		$(NULL)
+endif
+
--- a/intl/lwbrk/public/nsILineBreaker.h
+++ b/intl/lwbrk/public/nsILineBreaker.h
@@ -38,29 +38,25 @@
 #define nsILineBreaker_h__
 
 #include "nsISupports.h"
 
 #include "nscore.h"
 
 #define NS_LINEBREAKER_NEED_MORE_TEXT -1
 
-// {C9C5938E-70EF-4db2-ADEE-E7B2CCFBBEE6}
+// {5ae68851-d9a3-49fd-9388-58586dad8044}
 #define NS_ILINEBREAKER_IID \
-{ 0xc9c5938e, 0x70ef, 0x4db2, \
-    { 0xad, 0xee, 0xe7, 0xb2, 0xcc, 0xfb, 0xbe, 0xe6 } }
+{ 0x5ae68851, 0xd9a3, 0x49fd, \
+    { 0x93, 0x88, 0x58, 0x58, 0x6d, 0xad, 0x80, 0x44 } }
 
 class nsILineBreaker : public nsISupports
 {
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_ILINEBREAKER_IID)
-  virtual PRBool BreakInBetween( const PRUnichar* aText1 , PRUint32 aTextLen1,
-                                 const PRUnichar* aText2 , 
-                                 PRUint32 aTextLen2) = 0;
-
   virtual PRInt32 Next( const PRUnichar* aText, PRUint32 aLen, 
                         PRUint32 aPos) = 0;
 
   virtual PRInt32 Prev( const PRUnichar* aText, PRUint32 aLen, 
                         PRUint32 aPos) = 0;
 
   // Call this on a word with whitespace at either end. We will apply JISx4501
   // rules to find breaks inside the word. aBreakBefore is set to the break-
--- a/intl/lwbrk/src/Makefile.in
+++ b/intl/lwbrk/src/Makefile.in
@@ -47,17 +47,38 @@ LIBRARY_NAME	= lwbrk_s
 FORCE_STATIC_LIB = 1
 LIBXUL_LIBRARY  = 1
 
 REQUIRES	= xpcom \
 		  string \
 		  unicharutil \
 		  $(NULL)
 
-CSRCS		= rulebrk.c
-
 CPPSRCS		= \
 		nsJISx4501LineBreaker.cpp \
 		nsSampleWordBreaker.cpp \
 		nsSemanticUnitScanner.cpp \
 		$(NULL)
 
+ifdef MOZ_ENABLE_PANGO
+CPPSRCS		+= \
+		nsPangoBreaker.cpp \
+		$(NULL)
+else
+CPPSRCS		+= \
+		nsRuleBreaker.cpp \
+		$(NULL)
+
+CSRCS		= rulebrk.c
+endif
+
 include $(topsrcdir)/config/rules.mk
+
+ifdef MOZ_ENABLE_PANGO
+CXXFLAGS	+= \
+		$(MOZ_PANGO_CFLAGS) \
+		$(NULL)
+
+EXTRA_DSO_LDOPTS += \
+		$(MOZ_PANGO_LIBS) \
+		$(NULL)
+endif
+
--- a/intl/lwbrk/src/jisx4501class.h
+++ b/intl/lwbrk/src/jisx4501class.h
@@ -173,8 +173,43 @@ 0x55555555, // U+30C8 - U+30CF
 0x55555555, // U+30D0 - U+30D7
 0x55555555, // U+30D8 - U+30DF
 0x15151555, // U+30E0 - U+30E7
 0x51555555, // U+30E8 - U+30EF
 0x51155555, // U+30F0 - U+30F7
 0x51111555, // U+30F8 - U+30FF
 };
 
+static const PRUint32 gLBClass0E[32] = {
+0x99999999, // U+0E00 - U+0E07
+0x99999999, // U+0E08 - U+0E0F
+0x99999999, // U+0E10 - U+0E17
+0x99999999, // U+0E18 - U+0E1F
+0x99999999, // U+0E20 - U+0E27
+0x19999999, // U+0E28 - U+0E2F
+0x99999999, // U+0E30 - U+0E37
+0x09999999, // U+0E38 - U+0E3F
+0x91999999, // U+0E40 - U+0E47
+0x89999999, // U+0E48 - U+0E4F
+0x66666666, // U+0E50 - U+0E57
+0x99991166, // U+0E58 - U+0E5F
+0x99999999, // U+0E60 - U+0E67
+0x99999999, // U+0E68 - U+0E6F
+0x99999999, // U+0E70 - U+0E77
+0x99999999, // U+0E78 - U+0E7F
+0x99999999, // U+0E80 - U+0E87
+0x99999999, // U+0E88 - U+0E8F
+0x99999999, // U+0E90 - U+0E97
+0x99999999, // U+0E98 - U+0E9F
+0x99999999, // U+0EA0 - U+0EA7
+0x19999999, // U+0EA8 - U+0EAF
+0x99999999, // U+0EB0 - U+0EB7
+0x99999999, // U+0EB8 - U+0EBF
+0x91999999, // U+0EC0 - U+0EC7
+0x99999999, // U+0EC8 - U+0ECF
+0x66666666, // U+0ED0 - U+0ED7
+0x99999966, // U+0ED8 - U+0EDF
+0x99999999, // U+0EE0 - U+0EE7
+0x99999999, // U+0EE8 - U+0EEF
+0x99999999, // U+0EF0 - U+0EF7
+0x99999999, // U+0EF8 - U+0EFF
+};
+
new file mode 100644
--- /dev/null
+++ b/intl/lwbrk/src/nsComplexBreaker.h
@@ -0,0 +1,52 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** 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
+ * Theppitak Karoonboonyanan <thep@linux.thai.net>.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * - Theppitak Karoonboonyanan <thep@linux.thai.net>
+ *
+ * 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 ***** */
+#ifndef nsComplexBreaker_h__
+#define nsComplexBreaker_h__
+
+#include "nsString.h"
+
+/**
+ * Find line break opportunities in aText[] of aLength characters,
+ * filling boolean values indicating line break opportunities for
+ * corresponding charactersin aBreakBefore[] on return.
+ */
+void
+NS_GetComplexLineBreaks(const PRUnichar* aText, PRUint32 aLength,
+                        PRPackedBool* aBreakBefore);
+
+#endif  /* nsComplexBreaker_h__ */
--- a/intl/lwbrk/src/nsJISx4501LineBreaker.cpp
+++ b/intl/lwbrk/src/nsJISx4501LineBreaker.cpp
@@ -37,19 +37,18 @@
 
 
 
 #include "nsJISx4501LineBreaker.h"
 
 #include "pratom.h"
 #include "nsLWBRKDll.h"
 #include "jisx4501class.h"
-#define TH_UNICODE
-#include "th_char.h"
-#include "rulebrk.h"
+#include "nsComplexBreaker.h"
+#include "nsTArray.h"
 #include "nsUnicharUtils.h"
 
 /* 
 
    Simplification of Pair Table in JIS X 4051
 
    1. The Origion Table - in 4.1.3
 
@@ -136,91 +135,92 @@
         9        X                                   
       [b]        X                                  
        15        X        X     X     X    
        16        X                 X  X    
        18        X              X  X  X    
 
 
 
-   4. We add THAI characters and make it breakable w/ all ther class
+   4. We add COMPLEX characters and make it breakable w/ all ther class
+      except after class 1 and before class [a]
 
    Class of
    Leading    Class of Trailing Char Class
    Char        
 
-              1 [a] 7  8  9 [b]15 16 18 THAI
+              1 [a] 7  8  9 [b]15 16 18 COMPLEX
                                      
-        1     X  X  X  X  X  X  X  X  X
+        1     X  X  X  X  X  X  X  X  X  X
       [a]        X                             
         7        X  X                      
         8        X              X    
         9        X                                   
       [b]        X                                  
        15        X        X     X     X    
        16        X                 X  X    
        18        X              X  X  X    
-     THAI                                T
+  COMPLEX        X                       T
       
      T : need special handling
 
    5. Now we use one bit to encode weather it is breakable, and use 2 bytes
       for one row, then the bit table will look like:
 
                  18    <-   1
             
-       1  0000 0001 1111 1111  = 0x01FF
+       1  0000 0011 1111 1111  = 0x03FF
       [a] 0000 0000 0000 0010  = 0x0002
        7  0000 0000 0000 0110  = 0x0006
        8  0000 0000 0100 0010  = 0x0042
        9  0000 0000 0000 0010  = 0x0002
       [b] 0000 0000 0000 0010  = 0x0002
       15  0000 0001 0101 0010  = 0x0152
       16  0000 0001 1000 0010  = 0x0182
       18  0000 0001 1100 0010  = 0x01C2
-    THAI  0000 0000 0000 0000  = 0x0000
+ COMPLEX  0000 0010 0000 0010  = 0x0202
 
    5. Now we map the class to number
       
       0: 1 
       1: [a]- 2, 3, 4, 5, 6
       2: 7
       3: 8
       4: 9
       5: [b]- 10, 11, 12, 17
       6: 15
       7: 16
       8: 18
-      9: THAI
+      9: COMPLEX
 
 */
 
 #define MAX_CLASSES 10
 
 static const PRUint16 gPair[MAX_CLASSES] = {
-  0x01FF, 
+  0x03FF, 
   0x0002, 
   0x0006, 
   0x0042, 
   0x0002, 
   0x0002, 
   0x0152, 
   0x0182, 
   0x01C2,
-  0x0000
+  0x0202
 };
 
 
 static inline int
 GETCLASSFROMTABLE(const PRUint32* t, PRUint16 l)
 {
   return ((((t)[(l>>3)]) >> ((l & 0x0007)<<2)) & 0x000f);
 }
 
-#define CLASS_THAI 9
+#define CLASS_COMPLEX 9
 
 
 
 static inline int
 IS_HALFWIDTH_IN_JISx4051_CLASS3(PRUnichar u)
 {
   return ((0xff66 <= (u)) && ((u) <= 0xff70));
 }
@@ -230,35 +230,41 @@ IS_CJK_CHAR(PRUnichar u)
 {
   return ((0x1100 <= (u) && (u) <= 0x11ff) ||
           (0x2e80 <= (u) && (u) <= 0xd7ff) ||
           (0xf900 <= (u) && (u) <= 0xfaff) ||
           (0xff00 <= (u) && (u) <= 0xffef) );
 }
 
 static inline int
+IS_COMPLEX(PRUnichar u)
+{
+  return (0x0e01 <= (u) && (u) <= 0x0e5b);
+}
+
+static inline int
 IS_SPACE(PRUnichar u)
 {
   return ((u) == 0x0020 || (u) == 0x0009 || (u) == 0x000a || (u) == 0x000d || (u)==0x200b);
 }
 
 static PRInt8 GetClass(PRUnichar u)
 {
    PRUint16 h = u & 0xFF00;
    PRUint16 l = u & 0x00ff;
    PRInt8 c;
    
    // Handle 3 range table first
    if( 0x0000 == h)
    {
      c = GETCLASSFROMTABLE(gLBClass00, l);
    } 
-   else if(th_isthai(u))
+   else if( 0x0E00 == h)
    {
-     c = CLASS_THAI;
+     c = GETCLASSFROMTABLE(gLBClass0E, l);
    }
    else if( 0x2000 == h)
    {
      c = GETCLASSFROMTABLE(gLBClass20, l);
    } 
    else if( 0x2100 == h)
    {
      c = GETCLASSFROMTABLE(gLBClass21, l);
@@ -407,185 +413,74 @@ static PRInt8 ContextualAnalysis(
      // somehow people use this as ' in "it's" sometimes...
      if(U_SPACE != next)
        return CHARACTER_CLASS;
    }
    return GetClass(cur);
 }
 
 
-PRBool nsJISx4051LineBreaker::BreakInBetween(
-  const PRUnichar* aText1 , PRUint32 aTextLen1,
-  const PRUnichar* aText2 , PRUint32 aTextLen2)
+PRInt32 nsJISx4051LineBreaker::WordMove(
+  const PRUnichar* aText, PRUint32 aLen, PRUint32 aPos, PRInt8 aDirection)
 {
-  if(!aText1 || !aText2 || (0 == aTextLen1) || (0==aTextLen2) ||
-     NS_IS_HIGH_SURROGATE(aText1[aTextLen1-1]) && 
-     NS_IS_LOW_SURROGATE(aText2[0]) )  //Do not separate a surrogate pair
-  {
-     return PR_FALSE;
-  }
-
-  //search for CJK characters until a space is found. 
-  //if CJK char is found before space, use 4051, otherwise western
-  PRInt32 cur;
+  PRBool  textNeedsJISx4051 = PR_FALSE;
+  PRInt32 begin, end;
 
-  for (cur= aTextLen1-1; cur>=0; cur--)
-  {
-    if (IS_SPACE(aText1[cur]))
-      break;
-    if (IS_CJK_CHAR(aText1[cur]))
-      goto ROUTE_CJK_BETWEEN;
+  for (begin = aPos; begin > 0 && !IS_SPACE(aText[begin - 1]); --begin) {
+    if (IS_CJK_CHAR(aText[begin]) || IS_COMPLEX(aText[begin])) {
+      textNeedsJISx4051 = PR_TRUE;
+    }
   }
-
-  for (cur= 0; cur < (PRInt32)aTextLen2; cur++)
-  {
-    if (IS_SPACE(aText2[cur]))
-      break;
-    if (IS_CJK_CHAR(aText2[cur]))
-      goto ROUTE_CJK_BETWEEN;
+  for (end = aPos + 1; end < PRInt32(aLen) && !IS_SPACE(aText[end]); ++end) {
+    if (IS_CJK_CHAR(aText[end]) || IS_COMPLEX(aText[end])) {
+      textNeedsJISx4051 = PR_TRUE;
+    }
   }
 
-  //now apply western rule.
-  return IS_SPACE(aText1[aTextLen1-1]) || IS_SPACE(aText2[0]);
-
-ROUTE_CJK_BETWEEN:
-
-  PRInt8 c1, c2;
-  if(NEED_CONTEXTUAL_ANALYSIS(aText1[aTextLen1-1]))
-    c1 = ContextualAnalysis((aTextLen1>1)?aText1[aTextLen1-2]:U_NULL,
-                                  aText1[aTextLen1-1],
-                                  aText2[0]);
-  else 
-    c1 = GetClass(aText1[aTextLen1-1]);
+  PRInt32 ret;
+  nsAutoTArray<PRPackedBool, 2000> breakState;
+  if (!textNeedsJISx4051 || !breakState.AppendElements(end - begin)) {
+    // No complex text character, do not try to do complex line break.
+    // (This is required for serializers. See Bug #344816.)
+    // Also fall back to this when out of memory.
+    if (aDirection < 0) {
+      ret = (begin == PRInt32(aPos)) ? begin - 1 : begin;
+    } else {
+      ret = end;
+    }
+  } else {
+    GetJISx4051Breaks(aText + begin, end - begin, breakState.Elements());
 
-  if(NEED_CONTEXTUAL_ANALYSIS(aText2[0]))
-    c2 = ContextualAnalysis(aText1[aTextLen1-1],
-                            aText2[0],
-                            (aTextLen2>1)?aText2[1]:U_NULL);
-  else 
-    c2 = GetClass(aText2[0]);
+    ret = aPos;
+    do {
+      ret += aDirection;
+    } while (begin < ret && ret < end && !breakState[ret - begin]);
+  }
 
-  /* Handle cases for THAI */
-  if((CLASS_THAI == c1) && (CLASS_THAI == c2))
-  {
-     return (0 == TrbWordBreakPos(aText1, aTextLen1, aText2, aTextLen2));
-  }
-  else 
-  {
-     return GetPair(c1,c2);
-  }
+  return ret;
 }
 
-
 PRInt32 nsJISx4051LineBreaker::Next(
   const PRUnichar* aText, PRUint32 aLen, PRUint32 aPos) 
 {
   NS_ASSERTION(aText, "aText shouldn't be null");
   NS_ASSERTION(aLen > aPos, "Illegal value (length > position)");
 
-  //forward check for CJK characters until a space is found. 
-  //if CJK char is found before space, use 4051, otherwise western
-  PRUint32 cur;
-  for (cur = aPos; cur < aLen; ++cur)
-  {
-    if (IS_SPACE(aText[cur]))
-      return cur;
-    if (IS_CJK_CHAR(aText[cur]))
-      goto ROUTE_CJK_NEXT;
-  }
-  return NS_LINEBREAKER_NEED_MORE_TEXT; // Need more text
-
-ROUTE_CJK_NEXT:
-  PRInt8 c1, c2;
-  cur = aPos;
-  if(NEED_CONTEXTUAL_ANALYSIS(aText[cur]))
-  {
-    c1 = ContextualAnalysis((cur>0)?aText[cur-1]:U_NULL,
-                            aText[cur],
-                            (cur<(aLen-1)) ?aText[cur+1]:U_NULL);
-  } else  {
-    c1 = GetClass(aText[cur]);
-  }
-  
-  if(CLASS_THAI == c1) 
-     return PRUint32(TrbFollowing(aText, aLen, aPos));
-
-  for(cur++; cur <aLen; cur++)
-  {
-     if(NEED_CONTEXTUAL_ANALYSIS(aText[cur]))
-     {
-       c2 = ContextualAnalysis((cur>0)?aText[cur-1]:U_NULL,
-                               aText[cur],
-                               (cur<(aLen-1)) ?aText[cur+1]:U_NULL);
-     } else {
-       c2 = GetClass(aText[cur]);
-     }
-
-     if(GetPair(c1, c2)) {
-       return cur;
-     }
-     c1 = c2;
-  }
-  return NS_LINEBREAKER_NEED_MORE_TEXT; // Need more text
+  PRInt32 nextPos = WordMove(aText, aLen, aPos, 1);
+  return nextPos < PRInt32(aLen) ? nextPos : NS_LINEBREAKER_NEED_MORE_TEXT;
 }
 
 PRInt32 nsJISx4051LineBreaker::Prev( 
   const PRUnichar* aText, PRUint32 aLen, PRUint32 aPos) 
 {
   NS_ASSERTION(aText, "aText shouldn't be null");
-
-  //backward check for CJK characters until a space is found. 
-  //if CJK char is found before space, use 4051, otherwise western
-  PRUint32 cur;
-  for (cur = aPos - 1; cur > 0; --cur)
-  {
-    if (IS_SPACE(aText[cur]))
-    {
-      if (cur != aPos - 1) // XXXldb Why?
-        ++cur;
-      return cur;
-    }
-    if (IS_CJK_CHAR(aText[cur]))
-      goto ROUTE_CJK_PREV;
-  }
-
-  return NS_LINEBREAKER_NEED_MORE_TEXT; // Need more text
+  NS_ASSERTION(aLen >= aPos, "Illegal value (length >= position)");
 
-ROUTE_CJK_PREV:
-  cur = aPos;
-  PRInt8 c1, c2;
-  if(NEED_CONTEXTUAL_ANALYSIS(aText[cur-1]))
-  {
-    c2 = ContextualAnalysis(((cur-1)>0)?aText[cur-2]:U_NULL,
-                            aText[cur-1],
-                            (cur<aLen) ?aText[cur]:U_NULL);
-  } else  {
-    c2 = GetClass(aText[cur-1]);
-  }
-  // To Do: 
-  //
-  // Should handle CLASS_THAI here
-  //
-  for(cur--; cur > 0; cur--)
-  {
-     if(NEED_CONTEXTUAL_ANALYSIS(aText[cur-1]))
-     {
-       c1 = ContextualAnalysis(((cur-1)>0)?aText[cur-2]:U_NULL,
-                               aText[cur-1],
-                               (cur<aLen) ?aText[cur]:U_NULL);
-     } else {
-       c1 = GetClass(aText[cur-1]);
-     }
-
-     if(GetPair(c1, c2)) {
-       return cur;
-     }
-     c2 = c1;
-  }
-  return NS_LINEBREAKER_NEED_MORE_TEXT; // Need more text
+  PRInt32 prevPos = WordMove(aText, aLen, aPos, -1);
+  return prevPos > 0 ? prevPos : NS_LINEBREAKER_NEED_MORE_TEXT;
 }
 
 void
 nsJISx4051LineBreaker::GetJISx4051Breaks(const PRUnichar* aChars, PRUint32 aLength,
                                          PRPackedBool* aBreakBefore)
 {
   PRUint32 cur;
   PRInt8 lastClass = -1;
@@ -599,26 +494,39 @@ nsJISx4051LineBreaker::GetJISx4051Breaks
                               ch,
                               cur + 1 < aLength ? aChars[cur + 1] : U_NULL);
     } else {
       cl = GetClass(ch);
     }
 
     PRBool allowBreak;
     if (cur > 0) {
-      if (CLASS_THAI == lastClass && CLASS_THAI == cl) {
-        allowBreak = 0 == TrbWordBreakPos(aChars, cur, aChars + cur, aLength - cur);
-      } else {
-        allowBreak = GetPair(lastClass, cl);
-      }
+      NS_ASSERTION(CLASS_COMPLEX != lastClass || CLASS_COMPLEX != cl,
+                   "Loop should have prevented adjacent complex chars here");
+      allowBreak = GetPair(lastClass, cl);
     } else {
       allowBreak = PR_FALSE;
     }
     aBreakBefore[cur] = allowBreak;
     lastClass = cl;
+    if (CLASS_COMPLEX == cl) {
+      PRUint32 end = cur + 1;
+
+      while (end < aLength && CLASS_COMPLEX == GetClass(aChars[end])) {
+        ++end;
+      }
+
+      NS_GetComplexLineBreaks(aChars + cur, end - cur, aBreakBefore + cur);
+
+      // restore breakability at chunk begin, which was always set to false
+      // by the complex line breaker
+      aBreakBefore[cur] = allowBreak;
+
+      cur = end - 1;
+    }
   }
 }
 
 void
 nsJISx4051LineBreaker::GetJISx4051Breaks(const PRUint8* aChars, PRUint32 aLength,
                                          PRPackedBool* aBreakBefore)
 {
   PRUint32 cur;
--- a/intl/lwbrk/src/nsJISx4501LineBreaker.h
+++ b/intl/lwbrk/src/nsJISx4501LineBreaker.h
@@ -43,22 +43,23 @@
 class nsJISx4051LineBreaker : public nsILineBreaker
 {
   NS_DECL_ISUPPORTS
 
 public:
   nsJISx4051LineBreaker();
   virtual ~nsJISx4051LineBreaker();
 
-  PRBool BreakInBetween( const PRUnichar* aText1 , PRUint32 aTextLen1,
-                         const PRUnichar* aText2 , PRUint32 aTextLen2);
-
   PRInt32 Next( const PRUnichar* aText, PRUint32 aLen, PRUint32 aPos);
 
   PRInt32 Prev( const PRUnichar* aText, PRUint32 aLen, PRUint32 aPos);
 
   virtual void GetJISx4051Breaks(const PRUnichar* aText, PRUint32 aLength,
                                  PRPackedBool* aBreakBefore);
   virtual void GetJISx4051Breaks(const PRUint8* aText, PRUint32 aLength,
                                  PRPackedBool* aBreakBefore);
+
+private:
+  PRInt32 WordMove(const PRUnichar* aText, PRUint32 aLen, PRUint32 aPos,
+                   PRInt8 aDirection);
 };
 
 #endif  /* nsJISx4501LineBreaker_h__ */
new file mode 100644
--- /dev/null
+++ b/intl/lwbrk/src/nsPangoBreaker.cpp
@@ -0,0 +1,95 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** 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
+ * Theppitak Karoonboonyanan <thep@linux.thai.net>.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * - Theppitak Karoonboonyanan <thep@linux.thai.net>
+ *
+ * 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 ***** */
+
+#include "nsComplexBreaker.h"
+
+#include <pango/pango-break.h>
+#include "nsUTF8Utils.h"
+#include "nsString.h"
+#include "nsTArray.h"
+
+void
+NS_GetComplexLineBreaks(const PRUnichar* aText, PRUint32 aLength,
+                        PRPackedBool* aBreakBefore)
+{
+  NS_ASSERTION(aText, "aText shouldn't be null");
+
+  nsAutoTArray<PangoLogAttr, 2000> attrBuffer;
+  if (!attrBuffer.AppendElements(aLength + 1))
+  {
+    // out of memory, behave as if there were no complex line breaker
+    for (PRUint32 i = 0; i < aLength; ++i) {
+      aBreakBefore[i] = PR_FALSE;
+    }
+  }
+
+  NS_ConvertUTF16toUTF8 aUTF8(aText, aLength);
+
+  const gchar* p = aUTF8.Data();
+  const gchar* end = p + aUTF8.Length();
+  PRUint32     u16Offset = 0;
+
+  static PangoLanguage* language = pango_language_from_string("en");
+
+  while (p < end)
+  {
+    PangoLogAttr* attr = attrBuffer.Elements();
+    pango_get_log_attrs(p, end - p, -1, language, attr, attrBuffer.Length());
+
+    while (p < end)
+    {
+      aBreakBefore[u16Offset] = attr->is_line_break;
+      if (NS_IS_LOW_SURROGATE(aText[u16Offset]))
+        aBreakBefore[++u16Offset] = PR_FALSE; // Skip high surrogate
+      ++u16Offset;
+
+      PRUint32 ch = UTF8CharEnumerator::NextChar(&p, end);
+      ++attr;
+
+      if (ch == 0) {
+        // pango_break (pango 1.16.2) only analyses text before the
+        // first NUL (but sets one extra attr). Workaround loop to call
+        // pango_break again to analyse after the NUL is done somewhere else
+        // (gfx/thebes/src/gfxPangoFonts.cpp: SetupClusterBoundaries()).
+        // So, we do the same here for pango_get_log_attrs.
+        break;
+      }
+    }
+  }
+}
+
deleted file mode 100644
--- a/intl/lwbrk/src/nsPangoLineBreaker.cpp
+++ /dev/null
@@ -1,161 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* ***** 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
- * Theppitak Karoonboonyanan <thep@linux.thai.net>.
- * Portions created by the Initial Developer are Copyright (C) 2007
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * - Theppitak Karoonboonyanan <thep@linux.thai.net>
- *
- * 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 ***** */
-
-
-
-#include "nsPangoLineBreaker.h"
-
-#include <pango/pango.h>
-
-#include "nsLWBRKDll.h"
-#include "nsUnicharUtils.h"
-#include "nsUTF8Utils.h"
-#include "nsString.h"
-#include "nsTArray.h"
-
-
-NS_IMPL_ISUPPORTS1(nsPangoLineBreaker, nsILineBreaker)
-
-PRBool
-nsPangoLineBreaker::BreakInBetween(const PRUnichar* aText1 , PRUint32 aTextLen1,
-                                   const PRUnichar* aText2 , PRUint32 aTextLen2)
-{
-  if (!aText1 || !aText2 || (0 == aTextLen1) || (0 == aTextLen2) ||
-      NS_IS_HIGH_SURROGATE(aText1[aTextLen1-1]) && 
-      NS_IS_LOW_SURROGATE(aText2[0]) )  //Do not separate a surrogate pair
-  {
-    return PR_FALSE;
-  }
-
-  nsAutoString concat(aText1, aTextLen1);
-  concat.Append(aText2, aTextLen2);
-
-  nsAutoTArray<PRPackedBool, 2000> breakState;
-  if (!breakState.AppendElements(concat.Length()))
-    return NS_ERROR_OUT_OF_MEMORY;
-
-  GetJISx4051Breaks(concat.Data(), concat.Length(), breakState.Elements());
-
-  return breakState[aTextLen1];
-}
-
-
-PRInt32
-nsPangoLineBreaker::Next(const PRUnichar* aText, PRUint32 aLen, PRUint32 aPos) 
-{
-  NS_ASSERTION(aText, "aText shouldn't be null");
-  NS_ASSERTION(aLen > aPos, "Illegal value (length > position)");
-
-  nsAutoTArray<PRPackedBool, 2000> breakState;
-  if (!breakState.AppendElements(aLen))
-    return NS_ERROR_OUT_OF_MEMORY;
-
-  GetJISx4051Breaks(aText, aLen, breakState.Elements());
-
-  while (++aPos < aLen)
-    if (breakState[aPos])
-      return aPos;
-
-  return NS_LINEBREAKER_NEED_MORE_TEXT;
-}
-
-
-PRInt32
-nsPangoLineBreaker::Prev(const PRUnichar* aText, PRUint32 aLen, PRUint32 aPos) 
-{
-  NS_ASSERTION(aText, "aText shouldn't be null");
-  NS_ASSERTION(aLen > aPos, "Illegal value (length > position)");
-
-  nsAutoTArray<PRPackedBool, 2000> breakState;
-  if (!breakState.AppendElements(aLen))
-    return NS_ERROR_OUT_OF_MEMORY;
-
-  GetJISx4051Breaks(aText, aLen, breakState.Elements());
-
-  while (aPos > 0)
-    if (breakState[--aPos])
-      return aPos;
-
-  return NS_LINEBREAKER_NEED_MORE_TEXT;
-}
-
-void
-nsPangoLineBreaker::GetJISx4051Breaks(const PRUnichar* aText, PRUint32 aLen,
-                                      PRPackedBool* aBreakBefore)
-{
-  NS_ASSERTION(aText, "aText shouldn't be null");
-  NS_ASSERTION(aLen > aPos, "Illegal value (length > position)");
-
-  nsAutoTArray<PangoLogAttr, 2000> attrBuffer;
-  if (!attrBuffer.AppendElements(aLen + 1))
-    return;
-
-  NS_ConvertUTF16toUTF8 aUTF8(aText, aLen);
-
-  const gchar* p = aUTF8.Data();
-  const gchar* end = p + aUTF8.Length();
-  PRUint32     u16Offset = 0;
-
-  while (p < end)
-  {
-    PangoLogAttr* attr = attrBuffer.Elements();
-    pango_get_log_attrs(p, end - p, -1, pango_language_get_default(),
-                        attr, attrBuffer.Length());
-
-    while (p < end)
-    {
-      aBreakBefore[u16Offset] = attr->is_line_break;
-      if (NS_IS_LOW_SURROGATE(aText[u16Offset]))
-        aBreakBefore[++u16Offset] = PR_FALSE; // Skip high surrogate
-      ++u16Offset;
-
-      PRUint32 ch = UTF8CharEnumerator::NextChar(&p, end);
-      ++attr;
-
-      if (ch == 0) {
-        // pango_break (pango 1.16.2) only analyses text before the
-        // first NUL (but sets one extra attr). Workaround loop to call
-        // pango_break again to analyse after the NUL is done somewhere else
-        // (gfx/thebes/src/gfxPangoFonts.cpp: SetupClusterBoundaries()).
-        // So, we do the same here for pango_get_log_attrs.
-        break;
-      }
-    }
-  }
-}
-
deleted file mode 100644
--- a/intl/lwbrk/src/nsPangoLineBreaker.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* ***** 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
- * Theppitak Karoonboonyanan <thep@linux.thai.net>.
- * Portions created by the Initial Developer are Copyright (C) 2007
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * - Theppitak Karoonboonyanan <thep@linux.thai.net>
- *
- * 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 ***** */
-#ifndef nsPangoLineBreaker_h__
-#define nsPangoLineBreaker_h__
-
-#include "nsILineBreaker.h"
-
-class nsPangoLineBreaker : public nsILineBreaker
-{
-  NS_DECL_ISUPPORTS
-
-public:
-  PRBool BreakInBetween(const PRUnichar* aText1 , PRUint32 aTextLen1,
-                        const PRUnichar* aText2 , PRUint32 aTextLen2);
-
-  PRInt32 Next(const PRUnichar* aText, PRUint32 aLen, PRUint32 aPos);
-
-  PRInt32 Prev(const PRUnichar* aText, PRUint32 aLen, PRUint32 aPos);
-
-  void GetJISx4051Breaks(const PRUnichar* aText, PRUint32 aLen,
-                         PRPackedBool* aBreakBefore);
-};
-
-#endif  /* nsPangoLineBreaker_h__ */
new file mode 100644
--- /dev/null
+++ b/intl/lwbrk/src/nsRuleBreaker.cpp
@@ -0,0 +1,53 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** 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
+ * Theppitak Karoonboonyanan <thep@linux.thai.net>.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * - Theppitak Karoonboonyanan <thep@linux.thai.net>
+ *
+ * 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 ***** */
+
+#include "nsComplexBreaker.h"
+
+#define TH_UNICODE
+#include "rulebrk.h"
+
+void
+NS_GetComplexLineBreaks(const PRUnichar* aText, PRUint32 aLength,
+                        PRPackedBool* aBreakBefore)
+{
+  NS_ASSERTION(aText, "aText shouldn't be null");
+
+  for (PRUint32 i = 0; i < aLength; i++)
+    aBreakBefore[i] = (0 == TrbWordBreakPos(aText, i, aText + i, aLength - i));
+}
+
--- a/intl/lwbrk/tools/anzx4501.html
+++ b/intl/lwbrk/tools/anzx4501.html
@@ -49,19 +49,19 @@ Analysis of JIS X 4051 to Unicode Genera
 <TD BGCOLOR=yellow>Zs</TD>
 </TR>
 <TR><TH>00_1<TH>
 <TD></TD>
 <TD></TD>
 <TD></TD>
 <TD></TD>
 <TD>14</TD>
-<TD>2</TD>
+<TD>3</TD>
 <TD></TD>
-<TD BGCOLOR=white>16</TD>
+<TD BGCOLOR=white>17</TD>
 <TD></TD>
 <TD></TD>
 <TD></TD>
 <TD></TD>
 <TD></TD>
 <TD></TD>
 <TD></TD>
 <TD></TD>
@@ -74,54 +74,54 @@ Analysis of JIS X 4051 to Unicode Genera
 <TD></TD>
 <TD></TD>
 <TD></TD>
 <TD></TD>
 <TD></TD>
 <TD></TD>
 <TD>1</TD>
 <TD>13</TD>
-<TD>1</TD>
+<TD>2</TD>
 <TD></TD>
 <TD>1</TD>
 <TD></TD>
 <TD></TD>
 <TD></TD>
 <TD></TD>
 </TR>
 <TR><TH>01_[a]<TH>
 <TD></TD>
-<TD>27</TD>
+<TD>31</TD>
 <TD>2</TD>
 <TD></TD>
-<TD>30</TD>
+<TD>32</TD>
 <TD>6</TD>
 <TD></TD>
-<TD BGCOLOR=white>65</TD>
+<TD BGCOLOR=white>71</TD>
 <TD></TD>
 <TD></TD>
 <TD></TD>
 <TD></TD>
 <TD></TD>
-<TD>5</TD>
-<TD>22</TD>
+<TD>7</TD>
+<TD>24</TD>
 <TD></TD>
 <TD></TD>
 <TD></TD>
 <TD></TD>
 <TD>2</TD>
 <TD></TD>
 <TD></TD>
 <TD></TD>
 <TD></TD>
 <TD>2</TD>
 <TD>14</TD>
 <TD></TD>
 <TD></TD>
-<TD>14</TD>
+<TD>16</TD>
 <TD></TD>
 <TD></TD>
 <TD>2</TD>
 <TD>3</TD>
 <TD>1</TD>
 <TD></TD>
 <TD></TD>
 <TD></TD>
@@ -281,34 +281,34 @@ Analysis of JIS X 4051 to Unicode Genera
 <TD></TD>
 <TD></TD>
 <TD>13</TD>
 </TR>
 <TR><TH>06_15<TH>
 <TD></TD>
 <TD></TD>
 <TD></TD>
-<TD>10</TD>
+<TD>30</TD>
 <TD></TD>
 <TD></TD>
 <TD></TD>
-<TD BGCOLOR=white>10</TD>
+<TD BGCOLOR=white>30</TD>
 <TD></TD>
 <TD></TD>
 <TD></TD>
 <TD></TD>
 <TD></TD>
 <TD></TD>
 <TD></TD>
 <TD></TD>
 <TD></TD>
 <TD></TD>
 <TD></TD>
 <TD></TD>
-<TD>10</TD>
+<TD>30</TD>
 <TD></TD>
 <TD></TD>
 <TD></TD>
 <TD></TD>
 <TD></TD>
 <TD></TD>
 <TD></TD>
 <TD></TD>
@@ -357,54 +357,54 @@ Analysis of JIS X 4051 to Unicode Genera
 <TD></TD>
 <TD></TD>
 <TD></TD>
 <TD></TD>
 <TD></TD>
 </TR>
 <TR><TH>08_18<TH>
 <TD>10</TD>
-<TD>660</TD>
+<TD>659</TD>
 <TD>4</TD>
 <TD>130</TD>
-<TD>55</TD>
-<TD>940</TD>
+<TD>56</TD>
+<TD>941</TD>
 <TD>2</TD>
-<TD BGCOLOR=white>1801</TD>
+<TD BGCOLOR=white>1802</TD>
 <TD></TD>
 <TD>10</TD>
 <TD></TD>
 <TD></TD>
-<TD>367</TD>
+<TD>368</TD>
 <TD>1</TD>
-<TD>5</TD>
+<TD>4</TD>
 <TD></TD>
-<TD>287</TD>
+<TD>286</TD>
 <TD></TD>
 <TD></TD>
 <TD>4</TD>
 <TD></TD>
 <TD>3</TD>
 <TD>127</TD>
 <TD>3</TD>
 <TD>5</TD>
 <TD>3</TD>
 <TD>4</TD>
 <TD>6</TD>
-<TD>29</TD>
+<TD>30</TD>
 <TD>5</TD>
 <TD>12</TD>
 <TD>10</TD>
 <TD>273</TD>
-<TD>645</TD>
+<TD>646</TD>
 <TD>1</TD>
 <TD>1</TD>
 <TD></TD>
 </TR>
-<TR><TH>09_nbsp<TH>
+<TR><TH>09_COMPLEX<TH>
 <TD></TD>
 <TD></TD>
 <TD></TD>
 <TD></TD>
 <TD></TD>
 <TD></TD>
 <TD></TD>
 <TD BGCOLOR=white>0</TD>
@@ -484,17 +484,17 @@ Analysis of JIS X 4051 to Unicode Genera
 <TD BGCOLOR=red>01_[a]</TD>
 <TD BGCOLOR=red>02_7</TD>
 <TD BGCOLOR=red>03_8</TD>
 <TD BGCOLOR=red>04_9</TD>
 <TD BGCOLOR=red>05_[b]</TD>
 <TD BGCOLOR=red>06_15</TD>
 <TD BGCOLOR=red>07_16</TD>
 <TD BGCOLOR=red>08_18</TD>
-<TD BGCOLOR=red>09_nbsp</TD>
+<TD BGCOLOR=red>09_COMPLEX</TD>
 <TD BGCOLOR=red>X</TD>
 </TR>
 <TR><TH>00<TH>
 <TD>6</TD>
 <TD>14</TD>
 <TD></TD>
 <TD>2</TD>
 <TD>1</TD>
@@ -552,16 +552,29 @@ Analysis of JIS X 4051 to Unicode Genera
 <TD></TD>
 <TD></TD>
 <TD></TD>
 <TD></TD>
 <TD>226</TD>
 <TD></TD>
 <TD></TD>
 </TR>
+<TR><TH>0E<TH>
+<TD>1</TD>
+<TD>6</TD>
+<TD></TD>
+<TD></TD>
+<TD></TD>
+<TD></TD>
+<TD>20</TD>
+<TD></TD>
+<TD>1</TD>
+<TD></TD>
+<TD></TD>
+</TR>
 <TR><TH>20<TH>
 <TD></TD>
 <TD>5</TD>
 <TD>1</TD>
 <TD></TD>
 <TD>4</TD>
 <TD>13</TD>
 <TD></TD>
--- a/intl/lwbrk/tools/anzx4501.pl
+++ b/intl/lwbrk/tools/anzx4501.pl
@@ -395,16 +395,17 @@ printf "[%s || %s]\n", $r, $def;
       printf HEADER ", // U+%04X - U+%04X\n", $k + $i ,( $k + $i + 7);
    }
    print HEADER "};\n\n";
 }
 printarray("00", "8");
 printarray("20", "8");
 printarray("21", "8");
 printarray("30", "5");
+printarray("0E", "9");
 
 #print %rangecount;
 
 ######################################################################
 #
 # Close files
 #
 ######################################################################
--- a/intl/lwbrk/tools/jisx4501class.txt
+++ b/intl/lwbrk/tools/jisx4501class.txt
@@ -185,8 +185,17 @@ 2729;274B;18
 274D;;18
 274F;2752;18
 2756;;18
 2758;275E;18
 2761;2767;18
 2776;2794;18
 2798;27AF;18
 27B1;27BE;18
+0E3F;;1
+0E2F;;4
+0E46;;4
+0E5A;0E5B;4
+0E50;0E59;15
+0E4F;;18
+0EAF;;4
+0EC6;;4
+0ED0;0ED9;15
--- a/intl/lwbrk/tools/jisx4501simp.txt
+++ b/intl/lwbrk/tools/jisx4501simp.txt
@@ -13,9 +13,9 @@ 12;05_[b]
 13;X
 14;X
 15;06_15
 16;07_16
 17;05_[b]
 18;08_18
 19;X
 20;X
-21;09_nbsp
+21;09_COMPLEX
--- a/js/src/config/WINNT4.0.mk
+++ b/js/src/config/WINNT4.0.mk
@@ -92,17 +92,19 @@ endif
 OS_CFLAGS = -D_X86_=1 -DXP_WIN -DXP_WIN32 -DWIN32 -D_WINDOWS -D_WIN32 $(WIN_CFLAGS)
 JSDLL_CFLAGS = -DEXPORT_JS_API
 OS_LIBS = -lm -lc
 
 PREBUILT_CPUCFG = 1
 USE_MSVC = 1
 
 LIB_LINK_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\
- advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib oldnames.lib -nologo\
+ advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib oldnames.lib \
+ winmm.lib \
+ -nologo\
  -subsystem:windows -dll -debug -pdb:$(OBJDIR)/$(PDBFILE)\
  -machine:I386\
  -opt:ref -opt:noicf
 
 EXE_LINK_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\
  advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib oldnames.lib -nologo\
  -subsystem:console -debug -pdb:$(OBJDIR)/$(PDBFILE)\
  -machine:I386\
--- a/js/src/config/WINNT5.0.mk
+++ b/js/src/config/WINNT5.0.mk
@@ -92,17 +92,19 @@ endif
 OS_CFLAGS = -D_X86_=1 -DXP_WIN -DXP_WIN32 -DWIN32 -D_WINDOWS -D_WIN32 $(WIN_CFLAGS)
 JSDLL_CFLAGS = -DEXPORT_JS_API
 OS_LIBS = -lm -lc
 
 PREBUILT_CPUCFG = 1
 USE_MSVC = 1
 
 LIB_LINK_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\
- advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib oldnames.lib -nologo\
+ advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib oldnames.lib \
+ winmm.lib \
+ -nologo\
  -subsystem:windows -dll -debug -pdb:$(OBJDIR)/$(PDBFILE)\
  -machine:I386\
  -opt:ref -opt:noicf
 
 EXE_LINK_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\
  advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib oldnames.lib -nologo\
  -subsystem:console -debug -pdb:$(OBJDIR)/$(PDBFILE)\
  -machine:I386\
--- a/js/src/config/WINNT5.1.mk
+++ b/js/src/config/WINNT5.1.mk
@@ -92,17 +92,19 @@ endif
 OS_CFLAGS = -D_X86_=1 -DXP_WIN -DXP_WIN32 -DWIN32 -D_WINDOWS -D_WIN32 $(WIN_CFLAGS)
 JSDLL_CFLAGS = -DEXPORT_JS_API
 OS_LIBS = -lm -lc
 
 PREBUILT_CPUCFG = 1
 USE_MSVC = 1
 
 LIB_LINK_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\
- advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib oldnames.lib -nologo\
+ advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib oldnames.lib \
+ winmm.lib \
+ -nologo\
  -subsystem:windows -dll -debug -pdb:$(OBJDIR)/$(PDBFILE)\
  -machine:I386\
  -opt:ref -opt:noicf
 
 EXE_LINK_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\
  advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib oldnames.lib -nologo\
  -subsystem:console -debug -pdb:$(OBJDIR)/$(PDBFILE)\
  -machine:I386\
--- a/js/src/config/WINNT5.2.mk
+++ b/js/src/config/WINNT5.2.mk
@@ -92,17 +92,19 @@ endif
 OS_CFLAGS = -D_X86_=1 -DXP_WIN -DXP_WIN32 -DWIN32 -D_WINDOWS -D_WIN32 $(WIN_CFLAGS)
 JSDLL_CFLAGS = -DEXPORT_JS_API
 OS_LIBS = -lm -lc
 
 PREBUILT_CPUCFG = 1
 USE_MSVC = 1
 
 LIB_LINK_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\
- advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib oldnames.lib -nologo\
+ advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib oldnames.lib \
+ winmm.lib \
+ -nologo\
  -subsystem:windows -dll -debug -pdb:$(OBJDIR)/$(PDBFILE)\
  -machine:I386\
  -opt:ref -opt:noicf
 
 EXE_LINK_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\
  advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib oldnames.lib -nologo\
  -subsystem:console -debug -pdb:$(OBJDIR)/$(PDBFILE)\
  -machine:I386\
--- a/js/src/xpconnect/loader/XPCOMUtils.jsm
+++ b/js/src/xpconnect/loader/XPCOMUtils.jsm
@@ -54,17 +54,17 @@
  *  MyComponent.prototype = {
  *    // properties required for XPCOM registration:
  *    classDescription: "unique text description",
  *    classID:          Components.ID("{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}"),
  *    contractID:       "@example.com/xxx;1",
  *
  *    // [optional] custom factory (an object implementing nsIFactory). If not
  *    // provided, the default factory is used, which returns
- *    // |(new MyComponent()).QueryInterface(iid)| in its createInterface().
+ *    // |(new MyComponent()).QueryInterface(iid)| in its createInstance().
  *    _xpcom_factory: { ... }
  *
  *    // QueryInterface implementation, e.g. using the generateQI helper
  *    QueryInterface: XPCOMUtils.generateQI(
  *      [Components.interfaces.nsIObserver,
  *       Components.interfaces.nsIMyInterface]),
  *
  *    // ...component implementation...
--- a/js/src/xpconnect/src/nsXPConnect.cpp
+++ b/js/src/xpconnect/src/nsXPConnect.cpp
@@ -597,16 +597,27 @@ nsXPConnect::FinishCycleCollection()
 {
     delete mCycleCollectionContext;
     mCycleCollectionContext = nsnull;
     if (mObjRefcounts)
         mObjRefcounts->Finish();
     return NS_OK;
 }
 
+nsCycleCollectionParticipant *
+nsXPConnect::ToParticipant(void *p)
+{
+    // Put this assertion here so it fires when we still have a stack
+    // showing where the bad pointer came from.
+    NS_ASSERTION(mObjRefcounts->Get(p) > 0,
+                 "JS object but unknown to the JS GC?");
+
+    return this;
+}
+
 NS_IMETHODIMP
 nsXPConnect::Root(void *p)
 {
     if(!mCycleCollectionContext || !JS_LockGCThing(*mCycleCollectionContext, p))
         return NS_ERROR_FAILURE;
     return NS_OK;
 }
 
--- a/js/src/xpconnect/src/xpcprivate.h
+++ b/js/src/xpconnect/src/xpcprivate.h
@@ -475,25 +475,27 @@ public:
 
     virtual ~nsXPConnect();
 
     JSBool IsShuttingDown() const {return mShuttingDown;}
 
     nsresult GetInfoForIID(const nsIID * aIID, nsIInterfaceInfo** info);
     nsresult GetInfoForName(const char * name, nsIInterfaceInfo** info);
 
-    // from nsCycleCollectionLanguageRuntime and nsCycleCollectionParticipant
-    nsresult BeginCycleCollection();
+    // nsCycleCollectionParticipant
     NS_IMETHOD Root(void *p);
     NS_IMETHOD Unlink(void *p);
     NS_IMETHOD Unroot(void *p);
     NS_IMETHOD Traverse(void *p,
                         nsCycleCollectionTraversalCallback &cb);
-    nsresult FinishCycleCollection();
-    nsCycleCollectionParticipant *ToParticipant(void *p) {return this;}
+    
+    // nsCycleCollectionLanguageRuntime
+    virtual nsresult BeginCycleCollection();
+    virtual nsresult FinishCycleCollection();
+    virtual nsCycleCollectionParticipant *ToParticipant(void *p);
 
     JSObjectRefcounts* GetJSObjectRefcounts() {return mObjRefcounts;}
 #ifndef XPCONNECT_STANDALONE
     void RecordTraversal(void *p, nsISupports *s);
 #endif
 
 #ifdef XPC_IDISPATCH_SUPPORT
 public:
--- a/js/tests/e4x/shell.js
+++ b/js/tests/e4x/shell.js
@@ -36,16 +36,22 @@
  * 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 ***** */
 
 gTestsuite = 'e4x';
 
+if (typeof version != 'undefined') {
+    // At least in Rhino, if version is set to 150 (which is what is used
+    // in top level shell.js), the implementation assumes E4X is not available.
+    version(160);
+}
+
 /*
  * Report a failure in the 'accepted' manner
  */
 function reportFailure (section, msg)
 {
     msg = inSection(section)+"\n"+msg;
     var lines = msg.split ("\n");
     for (var i=0; i<lines.length; i++)
--- a/js/tests/js1_7/block/regress-348685.js
+++ b/js/tests/js1_7/block/regress-348685.js
@@ -59,22 +59,22 @@ function test()
       function g() {}
     }
     var a = i;
     print(a);
     print(i);
     return i;
   }
 
-  expect = 'ReferenceError: i is not defined';
+  expect = /ReferenceError: (i|"i") is not defined/;
 
   try
   {
     f();
   }
   catch(ex)
   {
     actual = ex + '';
   }
-  reportCompare(expect, actual, summary);
+  reportMatch(expect, actual, summary);
 
   exitFunc ('test');
 }
--- a/js/tests/js1_7/block/regress-349507.js
+++ b/js/tests/js1_7/block/regress-349507.js
@@ -48,22 +48,22 @@ test();
 //-----------------------------------------------------------------------------
 
 function test()
 {
   enterFunc ('test');
   printBugNumber(BUGNUMBER);
   printStatus (summary);
 
-  expect = 'TypeError: redeclaration of const b';
+  expect = /TypeError: redeclaration of const b/;
   try
   {
     eval('(function() { let(x = 1) { const b = 2 }; let b = 3; })');
   }
   catch(ex)
   {
     actual = ex + '';
   }
 
-  reportCompare(expect, actual, summary);
+  reportMatch(expect, actual, summary);
 
   exitFunc ('test');
 }
--- a/js/tests/js1_7/block/regress-350279.js
+++ b/js/tests/js1_7/block/regress-350279.js
@@ -48,22 +48,22 @@ test();
 //-----------------------------------------------------------------------------
 
 function test()
 {
   enterFunc ('test');
   printBugNumber(BUGNUMBER);
   printStatus (summary);
 
-  expect = 'SyntaxError: invalid array comprehension left-hand side';
+  expect = /SyntaxError: /;
   try
   {
     eval('let [2 for (x in [])] = 4;');
   }
   catch(ex)
   {
     actual = ex + '';
   }
 
-  reportCompare(expect, actual, summary);
+  reportMatch(expect, actual, summary);
 
   exitFunc ('test');
 }
--- a/js/tests/js1_7/block/regress-351497.js
+++ b/js/tests/js1_7/block/regress-351497.js
@@ -48,22 +48,22 @@ test();
 //-----------------------------------------------------------------------------
 
 function test()
 {
   enterFunc ('test');
   printBugNumber(BUGNUMBER);
   printStatus (summary);
  
-  expect = 'SyntaxError: invalid for/in left-hand side';
+  expect = /SyntaxError: (invalid for\/in left-hand side|missing variable name)/;
   try
   {
     eval('for(let (w) x in y) { }');
   }
   catch(ex)
   {
     actual = ex + '';
   }
 
-  reportCompare(expect, actual, summary);
+  reportMatch(expect, actual, summary);
 
   exitFunc ('test');
 }
--- a/js/tests/js1_7/block/regress-352212.js
+++ b/js/tests/js1_7/block/regress-352212.js
@@ -48,23 +48,23 @@ test();
 //-----------------------------------------------------------------------------
 
 function test()
 {
   enterFunc ('test');
   printBugNumber(BUGNUMBER);
   printStatus (summary);
  
-  expect = 'TypeError: XML filtering predicate operator called on incompatible Number';
+  expect = /TypeError: /;
 
   try
   {
     'a'.replace(/a/g, function () { return let(y) (3).(<x/>) });
   }
   catch(ex)
   {
     actual = ex + '';
   }
 
-  reportCompare(expect, actual, summary);
+  reportMatch(expect, actual, summary);
 
   exitFunc ('test');
 }
--- a/js/tests/js1_7/block/regress-352609.js
+++ b/js/tests/js1_7/block/regress-352609.js
@@ -47,44 +47,44 @@ var expect = '';
 test();
 //-----------------------------------------------------------------------------
 
 function test()
 {
   enterFunc ('test');
   printBugNumber(BUGNUMBER);
   printStatus (summary);
- 
-  expect = 'TypeError: 0 is not a function';
+
+  expect = /TypeError: 0 is not a function/;
   try
   {
     [let (x = 3, y = 4) x].map(0);
   }
   catch(ex)
   {
     actual = ex + '';
   }
-  reportCompare(expect, actual, '[let (x = 3, y = 4) x].map(0)');
+  reportMatch(expect, actual, '[let (x = 3, y = 4) x].map(0)');
 
-  expect = 'TypeError: p.z = [let (x = 3, y = 4) x] is not a function';
+  expect = /TypeError: (p.z = \[let \(x = 3, y = 4\) x\]|.*Array.*) is not a function/;
   try
   {
     var p = {}; (p.z = [let (x = 3, y = 4) x])();
   }
   catch(ex)
   {
     actual = ex + '';
   }
-  reportCompare(expect, actual, 'p = {}; (p.z = [let (x = 3, y = 4) x])()');
+  reportMatch(expect, actual, 'p = {}; (p.z = [let (x = 3, y = 4) x])()');
 
-  expect = 'TypeError: p.z = (let (x) x) is not a function';
+  expect = /TypeError: (p.z = \(let \(x\) x\)|.*Undefined.*) is not a function/;
   try
   {
     var p = {}; (p.z = let(x) x)()
-		  }
+  }
   catch(ex)
   {
     actual = ex + '';
   }
-  reportCompare(expect, actual, 'p = {}; (p.z = let(x) x)()');
+  reportMatch(expect, actual, 'p = {}; (p.z = let(x) x)()');
 
   exitFunc ('test');
 }
--- a/layout/Makefile.in
+++ b/layout/Makefile.in
@@ -68,15 +68,16 @@ endif
 ifndef MOZ_NO_INSPECTOR_APIS
 DIRS           += inspector
 endif
 
 DIRS           += build
 
 ifdef ENABLE_TESTS
 DIRS           += tools/reftest
+DIRS           += tools/pageloader
 ifndef MOZ_ENABLE_LIBXUL
 TOOL_DIRS	+= html/tests
 endif
 endif
 
 include $(topsrcdir)/config/rules.mk
 
--- a/layout/base/Makefile.in
+++ b/layout/base/Makefile.in
@@ -73,16 +73,17 @@ REQUIRES	= xpcom \
 		  pref \
 		  imglib2 \
 		  unicharutil \
 		  htmlparser \
 		  util \
 		  windowwatcher \
 		  accessibility \
 		  shistory \
+		  caps \
 		  $(NULL)
 
 ifdef MOZ_ENABLE_CAIRO_GFX
 REQUIRES += thebes cairo
 endif
 
 XPIDLSRCS	= \
 		nsIStyleSheetService.idl	\
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -112,17 +112,17 @@
 #include "nsLayoutErrors.h"
 #include "nsLayoutUtils.h"
 #include "nsAutoPtr.h"
 #include "nsBoxFrame.h"
 #include "nsIBoxLayout.h"
 #include "nsImageFrame.h"
 #include "nsIObjectLoadingContent.h"
 #include "nsContentErrors.h"
-
+#include "nsIPrincipal.h"
 #include "nsIDOMWindowInternal.h"
 
 #include "nsBox.h"
 
 #ifdef MOZ_XUL
 #include "nsIRootBox.h"
 #include "nsIDOMXULCommandDispatcher.h"
 #include "nsIDOMXULDocument.h"
@@ -4204,18 +4204,20 @@ nsCSSFrameConstructor::ConstructDocEleme
     nsresult rv;
     PRBool resolveStyle;
     
     nsIXBLService * xblService = GetXBLService();
     if (!xblService)
       return NS_ERROR_FAILURE;
 
     nsRefPtr<nsXBLBinding> binding;
-    rv = xblService->LoadBindings(aDocElement, display->mBinding, PR_FALSE,
-                                  getter_AddRefs(binding), &resolveStyle);
+    rv = xblService->LoadBindings(aDocElement, display->mBinding->mURI,
+                                  display->mBinding->mOriginPrincipal,
+                                  PR_FALSE, getter_AddRefs(binding),
+                                  &resolveStyle);
     if (NS_FAILED(rv))
       return NS_OK; // Binding will load asynchronously.
 
     if (binding) {
       mDocument->BindingManager()->AddToAttachedQueue(binding);
     }
 
     if (resolveStyle) {
@@ -7455,18 +7457,19 @@ nsCSSFrameConstructor::ConstructFrameInt
       nsresult rv;
       // Load the bindings.
       PRBool resolveStyle;
       
       nsIXBLService * xblService = GetXBLService();
       if (!xblService)
         return NS_ERROR_FAILURE;
 
-      rv = xblService->LoadBindings(aContent, display->mBinding, PR_FALSE,
-                                    getter_AddRefs(binding.mBinding),
+      rv = xblService->LoadBindings(aContent, display->mBinding->mURI,
+                                    display->mBinding->mOriginPrincipal,
+                                    PR_FALSE, getter_AddRefs(binding.mBinding),
                                     &resolveStyle);
       if (NS_FAILED(rv))
         return NS_OK;
 
       if (resolveStyle) {
         styleContext = ResolveStyleContext(aParentFrame, aContent);
         display = styleContext->GetStyleDisplay();
       }
@@ -9132,40 +9135,45 @@ nsCSSFrameConstructor::ContentInserted(n
       InsertFirstLineFrames(state, aContainer, containingBlock, &parentFrame,
                             prevSibling, frameItems);
     }
   }
       
   nsIFrame* newFrame = frameItems.childList;
   if (NS_SUCCEEDED(rv) && newFrame) {
     NS_ASSERTION(!captionItems.childList, "leaking caption frames");
+    if (!prevSibling) {
+      // We're inserting the new frame as the first child. See if the
+      // parent has a :before pseudo-element
+      nsIFrame* firstChild = parentFrame->GetFirstChild(nsnull);
+
+      if (firstChild &&
+          nsLayoutUtils::IsGeneratedContentFor(aContainer, firstChild,
+                                               nsCSSPseudoElements::before)) {
+        // Insert the new frames after the last continuation of the :before
+        prevSibling = firstChild->GetLastContinuation();
+        nsIFrame* newParent = prevSibling->GetParent();
+        if (newParent != parentFrame) {
+          nsHTMLContainerFrame::ReparentFrameViewList(state.mPresContext,
+                                                      newFrame, parentFrame,
+                                                      newParent);
+          parentFrame = newParent;
+        }
+        // We perhaps could leave this true and take the AppendFrames path
+        // below, but we'd have to update appendAfterFrame and it seems safer
+        // to force all insert-after-:before cases to take these to take the
+        // InsertFrames path
+        isAppend = PR_FALSE;
+      }
+    }
+
     // Notify the parent frame
     if (isAppend) {
       AppendFrames(state, aContainer, parentFrame, newFrame, appendAfterFrame);
-    }
-    else {
-      if (!prevSibling) {
-        // We're inserting the new frame as the first child. See if the
-        // parent has a :before pseudo-element
-        nsIFrame* firstChild = parentFrame->GetFirstChild(nsnull);
-
-        if (firstChild &&
-            nsLayoutUtils::IsGeneratedContentFor(aContainer, firstChild,
-                                                 nsCSSPseudoElements::before)) {
-          // Insert the new frames after the last continuation of the :before
-          prevSibling = firstChild->GetLastContinuation();
-          nsIFrame* newParent = prevSibling->GetParent();
-          if (newParent != parentFrame) {
-            nsHTMLContainerFrame::ReparentFrameViewList(state.mPresContext,
-                                                        newFrame, parentFrame,
-                                                        newParent);
-            parentFrame = newParent;
-          }
-        }
-      }
+    } else {
       state.mFrameManager->InsertFrames(parentFrame,
                                         nsnull, prevSibling, newFrame);
     }
   }
   else {
     // we might have a caption treat it here
     nsIFrame* newCaptionFrame = captionItems.childList;
     if (NS_SUCCEEDED(rv) && newCaptionFrame) {
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -2797,16 +2797,52 @@ NS_IMETHODIMP
 PresShell::CompleteMove(PRBool aForward, PRBool aExtend)
 {
   return CompleteMoveInner(aForward, aExtend, PR_TRUE);
 }
 
 nsresult
 PresShell::CompleteMoveInner(PRBool aForward, PRBool aExtend, PRBool aScrollIntoView)
 {
+  nsIContent* root = mSelection->GetAncestorLimiter();
+  if (root) {
+    // make the caret be either at the very beginning (0) or the very end
+    nsIContent* node = root;
+    PRInt32 offset = 0;
+    nsFrameSelection::HINT hint = nsFrameSelection::HINTLEFT;
+    if (aForward) {
+      nsIContent* next = node;
+      PRUint32 count;
+      while ((count = next->GetChildCount()) > 0) {
+        node = next;
+        offset = count;
+        next = next->GetChildAt(count - 1);
+      }
+
+      if (offset > 0 && node->GetChildAt(offset - 1)->Tag() == nsGkAtoms::br) {
+        --offset;
+        hint = nsFrameSelection::HINTRIGHT; // for bug 106855
+      }
+    }
+
+    mSelection->HandleClick(node, offset, offset, aExtend, PR_FALSE, hint);
+
+    // HandleClick resets ancestorLimiter, so set it again.
+    mSelection->SetAncestorLimiter(root);
+
+    if (aScrollIntoView) {
+      return
+        ScrollSelectionIntoView(nsISelectionController::SELECTION_NORMAL, 
+                                nsISelectionController::SELECTION_FOCUS_REGION,
+                                PR_TRUE);
+    }
+
+    return NS_OK;
+  }
+
   nsIScrollableView *scrollableView;
   if (!mViewManager) 
     return NS_ERROR_UNEXPECTED;
   nsresult result = mViewManager->GetRootScrollableView(&scrollableView);
   if (NS_FAILED(result)) 
     return result;
   if (!scrollableView) 
     return NS_ERROR_UNEXPECTED;
--- a/layout/generic/nsColumnSetFrame.cpp
+++ b/layout/generic/nsColumnSetFrame.cpp
@@ -64,18 +64,18 @@ public:
   NS_IMETHOD  AppendFrames(nsIAtom*        aListName,
                            nsIFrame*       aFrameList);
   NS_IMETHOD  InsertFrames(nsIAtom*        aListName,
                            nsIFrame*       aPrevFrame,
                            nsIFrame*       aFrameList);
   NS_IMETHOD  RemoveFrame(nsIAtom*        aListName,
                           nsIFrame*       aOldFrame);
 
-  // REVIEW: Now by default the background of a frame receives events,
-  // so this GetFrameForPoint override is no longer necessary.
+  virtual nscoord GetMinWidth(nsIRenderingContext *aRenderingContext);  
+  virtual nscoord GetPrefWidth(nsIRenderingContext *aRenderingContext);
 
   virtual nsIFrame* GetContentInsertionFrame() {
     return GetFirstChild(nsnull)->GetContentInsertionFrame();
   }
   
   NS_IMETHOD BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                               const nsRect&           aDirtyRect,
                               const nsDisplayListSet& aLists);
@@ -191,47 +191,43 @@ static nscoord GetAvailableContentHeight
     return NS_INTRINSICSIZE;
   }
   nscoord borderPaddingHeight =
     aReflowState.mComputedBorderPadding.top +
     aReflowState.mComputedBorderPadding.bottom;
   return PR_MAX(0, aReflowState.availableHeight - borderPaddingHeight);
 }
 
+static nscoord
+GetColumnGap(nsColumnSetFrame* aFrame, const nsStyleColumn* aColStyle) {
+  switch (aColStyle->mColumnGap.GetUnit()) {
+    case eStyleUnit_Coord:
+      return aColStyle->mColumnGap.GetCoordValue();
+    case eStyleUnit_Normal:
+      return aFrame->GetStyleFont()->mFont.size;
+    default:
+      NS_NOTREACHED("Unknown gap type");
+  }
+  return 0;
+}
+
 nsColumnSetFrame::ReflowConfig
 nsColumnSetFrame::ChooseColumnStrategy(const nsHTMLReflowState& aReflowState)
 {
   const nsStyleColumn* colStyle = GetStyleColumn();
   nscoord availContentWidth = GetAvailableContentWidth(aReflowState);
   if (aReflowState.ComputedWidth() != NS_INTRINSICSIZE) {
     availContentWidth = aReflowState.ComputedWidth();
   }
   nscoord colHeight = GetAvailableContentHeight(aReflowState);
   if (aReflowState.mComputedHeight != NS_INTRINSICSIZE) {
     colHeight = aReflowState.mComputedHeight;
   }
 
-  nscoord colGap = 0;
-  switch (colStyle->mColumnGap.GetUnit()) {
-    case eStyleUnit_Coord:
-      colGap = colStyle->mColumnGap.GetCoordValue();
-      break;
-    case eStyleUnit_Percent:
-      if (availContentWidth != NS_INTRINSICSIZE) {
-        colGap = NSToCoordRound(colStyle->mColumnGap.GetPercentValue()*availContentWidth);
-      }
-      break;
-    case eStyleUnit_Normal:
-      colGap = GetStyleFont()->mFont.size;
-      break;
-    default:
-      NS_NOTREACHED("Unknown gap type");
-      break;
-  }
-
+  nscoord colGap = GetColumnGap(this, colStyle);
   PRInt32 numColumns = colStyle->mColumnCount;
 
   nscoord colWidth = NS_INTRINSICSIZE;
   if (colStyle->mColumnWidth.GetUnit() == eStyleUnit_Coord) {
     colWidth = colStyle->mColumnWidth.GetCoordValue();
 
     // Reduce column count if necessary to make columns fit in the
     // available width. Compute max number of columns that fit in
@@ -321,16 +317,68 @@ static void MoveChildTo(nsIFrame* aParen
   aParent->Invalidate(r);
   r -= aChild->GetPosition();
   aChild->SetPosition(aOrigin);
   r += aOrigin;
   aParent->Invalidate(r);
   PlaceFrameView(aChild);
 }
 
+nscoord
+nsColumnSetFrame::GetMinWidth(nsIRenderingContext *aRenderingContext) {
+  nscoord width = 0;
+  if (mFrames.FirstChild()) {
+    width = mFrames.FirstChild()->GetMinWidth(aRenderingContext);
+  }
+  const nsStyleColumn* colStyle = GetStyleColumn();
+  if (colStyle->mColumnWidth.GetUnit() == eStyleUnit_Coord) {
+    // As available width reduces to zero, we reduce our number of columns to one,
+    // and don't enforce the column width, so just return the min of the
+    // child's min-width with any specified column width.
+    width = PR_MIN(width, colStyle->mColumnWidth.GetCoordValue());
+  } else {
+    NS_ASSERTION(colStyle->mColumnCount > 0, "column-count and column-width can't both be auto");
+    // As available width reduces to zero, we still have mColumnCount columns, so
+    // multiply the child's min-width by the number of columns.
+    width *= colStyle->mColumnCount;
+  }
+  // XXX count forced column breaks here? Maybe we should return the child's
+  // min-width times the minimum number of columns.
+  return width;
+}
+
+nscoord
+nsColumnSetFrame::GetPrefWidth(nsIRenderingContext *aRenderingContext) {
+  // Our preferred width is our desired column width, if specified, otherwise the
+  // child's preferred width, times the number of columns, plus the width of any
+  // required column gaps
+  // XXX what about forced column breaks here?
+  const nsStyleColumn* colStyle = GetStyleColumn();
+  nscoord colGap = GetColumnGap(this, colStyle);
+
+  nscoord colWidth;
+  if (colStyle->mColumnWidth.GetUnit() == eStyleUnit_Coord) {
+    colWidth = colStyle->mColumnWidth.GetCoordValue();
+  } else {
+    if (mFrames.FirstChild()) {
+      colWidth = mFrames.FirstChild()->GetPrefWidth(aRenderingContext);
+    } else {
+      colWidth = 0;
+    }
+  }
+
+  PRInt32 numColumns = colStyle->mColumnCount;
+   if (numColumns <= 0) {
+    // if column-count is auto, assume one column
+    numColumns = 1;
+  }
+
+  return colWidth*numColumns + colGap*(numColumns - 1);
+}
+
 PRBool
 nsColumnSetFrame::ReflowChildren(nsHTMLReflowMetrics&     aDesiredSize,
                                  const nsHTMLReflowState& aReflowState,
                                  nsReflowStatus&          aStatus,
                                  const ReflowConfig&      aConfig,
                                  PRBool                   aUnboundedLastColumn,
                                  nsCollapsingMargin*      aBottomMarginCarriedOut) {
   PRBool allFit = PR_TRUE;
--- a/layout/generic/nsFirstLetterFrame.cpp
+++ b/layout/generic/nsFirstLetterFrame.cpp
@@ -73,16 +73,20 @@ public:
   }
 
   virtual nscoord GetMinWidth(nsIRenderingContext *aRenderingContext);
   virtual nscoord GetPrefWidth(nsIRenderingContext *aRenderingContext);
   virtual void AddInlineMinWidth(nsIRenderingContext *aRenderingContext,
                                  InlineMinWidthData *aData);
   virtual void AddInlinePrefWidth(nsIRenderingContext *aRenderingContext,
                                   InlinePrefWidthData *aData);
+  virtual nsSize ComputeSize(nsIRenderingContext *aRenderingContext,
+                             nsSize aCBSize, nscoord aAvailableWidth,
+                             nsSize aMargin, nsSize aBorder, nsSize aPadding,
+                             PRBool aShrinkWrap);
   NS_IMETHOD Reflow(nsPresContext*          aPresContext,
                     nsHTMLReflowMetrics&     aDesiredSize,
                     const nsHTMLReflowState& aReflowState,
                     nsReflowStatus&          aStatus);
 
   virtual PRBool CanContinueTextRun() const;
 
   NS_IMETHOD SetSelected(nsPresContext* aPresContext, nsIDOMRange *aRange,PRBool aSelected, nsSpread aSpread);
@@ -218,16 +222,31 @@ nsFirstLetterFrame::GetMinWidth(nsIRende
 
 // Needed for floating first-letter frames.
 /* virtual */ nscoord
 nsFirstLetterFrame::GetPrefWidth(nsIRenderingContext *aRenderingContext)
 {
   return nsLayoutUtils::PrefWidthFromInline(this, aRenderingContext);
 }
 
+/* virtual */ nsSize
+nsFirstLetterFrame::ComputeSize(nsIRenderingContext *aRenderingContext,
+                                nsSize aCBSize, nscoord aAvailableWidth,
+                                nsSize aMargin, nsSize aBorder, nsSize aPadding,
+                                PRBool aShrinkWrap)
+{
+  if (GetPrevInFlow()) {
+    // We're wrapping the text *after* the first letter, so behave like an
+    // inline frame.
+    return nsSize(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
+  }
+  return nsFirstLetterFrameSuper::ComputeSize(aRenderingContext,
+      aCBSize, aAvailableWidth, aMargin, aBorder, aPadding, aShrinkWrap);
+}
+
 NS_IMETHODIMP
 nsFirstLetterFrame::Reflow(nsPresContext*          aPresContext,
                            nsHTMLReflowMetrics&     aMetrics,
                            const nsHTMLReflowState& aReflowState,
                            nsReflowStatus&          aReflowStatus)
 {
   DO_GLOBAL_REFLOW_COUNT("nsFirstLetterFrame");
   DISPLAY_REFLOW(aPresContext, this, aReflowState, aMetrics, aReflowStatus);
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -1379,31 +1379,30 @@ nsIFrame::BuildDisplayListForStackingCon
       }
     }
     break;
   }
   // 4: block backgrounds
   resultList.AppendToTop(set.BlockBorderBackgrounds());
   // 5: floats
   resultList.AppendToTop(set.Floats());
-  // 6: general content
+  // 7: general content
   resultList.AppendToTop(set.Content());
-  // 7, 8: non-negative z-index children
-  resultList.AppendToTop(set.PositionedDescendants());
-  // 9: outlines, in content tree order. We need to sort by content order
+  // 7.5: outlines, in content tree order. We need to sort by content order
   // because an element with outline that breaks and has children with outline
   // might have placed child outline items between its own outline items.
   // The element's outline items need to all come before any child outline
   // items.
   set.Outlines()->SortByContentOrder(aBuilder, GetContent());
 #ifdef NS_DEBUG
   DisplayDebugBorders(aBuilder, this, set);
 #endif
   resultList.AppendToTop(set.Outlines());
-
+  // 8, 9: non-negative z-index children
+  resultList.AppendToTop(set.PositionedDescendants());
 
   if (applyAbsPosClipping) {
     nsAbsPosClipWrapper wrapper(absPosClip);
     nsDisplayItem* item = wrapper.WrapList(aBuilder, this, &resultList);
     if (!item)
       return NS_ERROR_OUT_OF_MEMORY;
     // resultList was emptied
     resultList.AppendToTop(item);
@@ -1595,18 +1594,18 @@ nsIFrame::BuildDisplayListForChild(nsDis
         nsAbsPosClipWrapper wrapper(clipRect);
         rv = wrapper.WrapListsInPlace(aBuilder, aChild, pseudoStack);
       }
     }
     list.AppendToTop(pseudoStack.BorderBackground());
     list.AppendToTop(pseudoStack.BlockBorderBackgrounds());
     list.AppendToTop(pseudoStack.Floats());
     list.AppendToTop(pseudoStack.Content());
+    list.AppendToTop(pseudoStack.Outlines());
     extraPositionedDescendants.AppendToTop(pseudoStack.PositionedDescendants());
-    aLists.Outlines()->AppendToTop(pseudoStack.Outlines());
 #ifdef NS_DEBUG
     DisplayDebugBorders(aBuilder, aChild, aLists);
 #endif
   }
   NS_ENSURE_SUCCESS(rv, rv);
     
   if (isPositioned || isComposited ||
       (aFlags & DISPLAY_CHILD_FORCE_STACKING_CONTEXT)) {
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -669,19 +669,17 @@ nsHTMLScrollFrame::GetMinWidth(nsIRender
   return result;
 }
 
 /* virtual */ nscoord
 nsHTMLScrollFrame::GetPrefWidth(nsIRenderingContext *aRenderingContext)
 {
   nscoord result;
   DISPLAY_PREF_WIDTH(this, result);
-  // XXX Might this make us count padding/border/margin twice?
-  result = nsLayoutUtils::IntrinsicForContainer(aRenderingContext,
-                             mInner.mScrolledFrame, nsLayoutUtils::PREF_WIDTH);
+  result = mInner.mScrolledFrame->GetPrefWidth(aRenderingContext);
 
   nsGfxScrollFrameInner::ScrollbarStyles ss = GetScrollbarStyles();
   if (ss.mVertical != NS_STYLE_OVERFLOW_HIDDEN && // ideal?
       mInner.mVScrollbarBox) {
     nsBoxLayoutState bls(PresContext(), aRenderingContext);
     nsSize vScrollbarPrefSize(0, 0);
     GetScrollbarMetrics(bls, mInner.mVScrollbarBox,
                         nsnull, &vScrollbarPrefSize, PR_TRUE);
--- a/layout/generic/nsHTMLFrame.cpp
+++ b/layout/generic/nsHTMLFrame.cpp
@@ -587,17 +587,18 @@ CanvasFrame::Reflow(nsPresContext*      
       // But we have a new child, which will affect our background, so
       // invalidate our whole rect.
       // Note: Even though we request to be sized to our child's size, our
       // scroll frame ensures that we are always the size of the viewport.
       // Also note: GetPosition() on a CanvasFrame is always going to return
       // (0, 0). We only want to invalidate GetRect() since GetOverflowRect()
       // could also include overflow to our top and left (out of the viewport)
       // which doesn't need to be painted.
-      Invalidate(GetRect(), PR_FALSE);
+      nsIFrame* viewport = PresContext()->GetPresShell()->GetRootFrame();
+      viewport->Invalidate(nsRect(nsPoint(0, 0), viewport->GetSize()));
     }
 
     // Return our desired size (which doesn't matter)
     aDesiredSize.width = aReflowState.availableWidth;
     aDesiredSize.height = kidDesiredSize.height +
                           kidReflowState.mComputedMargin.TopBottom();
 
     aDesiredSize.mOverflowArea.UnionRect(
--- a/layout/generic/nsIFrame.h
+++ b/layout/generic/nsIFrame.h
@@ -416,28 +416,26 @@ public:
     return GetStyleContext()->GetRuleNode()->GetPresContext();
   }
 
   /**
    * Called to initialize the frame. This is called immediately after creating
    * the frame.
    *
    * If the frame is a continuing frame, then aPrevInFlow indicates the previous
-   * frame (the frame that was split). You should connect the continuing frame to
-   * its prev-in-flow, e.g. by using the AppendToFlow() function
+   * frame (the frame that was split).
    *
    * If you want a view associated with your frame, you should create the view
    * now.
    *
    * @param   aContent the content object associated with the frame
    * @param   aGeometricParent  the geometric parent frame
    * @param   aContentParent  the content parent frame
    * @param   aContext the style context associated with the frame
    * @param   aPrevInFlow the prev-in-flow frame
-   * @see #AppendToFlow()
    */
   NS_IMETHOD  Init(nsIContent*      aContent,
                    nsIFrame*        aParent,
                    nsIFrame*        aPrevInFlow) = 0;
 
   /**
    * Destroys this frame and each of its child frames (recursively calls
    * Destroy() for each child)
--- a/layout/generic/nsInlineFrame.cpp
+++ b/layout/generic/nsInlineFrame.cpp
@@ -247,16 +247,20 @@ nsInlineFrame::ComputeSize(nsIRenderingC
 void
 nsInlineFrame::ReparentFloatsForInlineChild(nsIFrame* aOurLineContainer,
                                             nsIFrame* aFrame,
                                             PRBool aReparentSiblings)
 {
   NS_ASSERTION(aOurLineContainer->GetNextContinuation() ||
                aOurLineContainer->GetPrevContinuation(),
                "Don't call this when we have no continuation, it's a waste");
+  if (!aFrame) {
+    NS_ASSERTION(aReparentSiblings, "Why did we get called?");
+    return;
+  }
 
   nsIFrame* ancestor = aFrame;
   nsIFrame* ancestorBlockChild;
   do {
     ancestorBlockChild = ancestor;
     ancestor = ancestor->GetParent();
     if (!ancestor)
       return;
--- a/layout/generic/nsSpaceManager.cpp
+++ b/layout/generic/nsSpaceManager.cpp
@@ -109,18 +109,18 @@ PSArenaFreeCB(size_t aSize, void* aPtr, 
 // nsSpaceManager
 
 nsSpaceManager::nsSpaceManager(nsIPresShell* aPresShell, nsIFrame* aFrame)
   : mFrame(aFrame),
     mLowestTop(NSCOORD_MIN),
     mFloatDamage(PSArenaAllocCB, PSArenaFreeCB, aPresShell),
     mHaveCachedLeftYMost(PR_TRUE),
     mHaveCachedRightYMost(PR_TRUE),
-    mMaximalLeftYMost(0),
-    mMaximalRightYMost(0),
+    mMaximalLeftYMost(nscoord_MIN),
+    mMaximalRightYMost(nscoord_MIN),
     mCachedBandPosition(nsnull)
 {
   MOZ_COUNT_CTOR(nsSpaceManager);
   mX = mY = 0;
   mFrameInfoMap = nsnull;
 }
 
 void
@@ -1034,17 +1034,17 @@ nsSpaceManager::RemoveRegion(nsIFrame* a
 
 void
 nsSpaceManager::ClearRegions()
 {
   ClearFrameInfo();
   mBandList.Clear();
   mLowestTop = NSCOORD_MIN;
   mHaveCachedLeftYMost = mHaveCachedRightYMost = PR_TRUE;
-  mMaximalLeftYMost = mMaximalRightYMost = 0;
+  mMaximalLeftYMost = mMaximalRightYMost = nscoord_MIN;
 }
 
 void
 nsSpaceManager::PushState(SavedState* aState)
 {
   NS_PRECONDITION(aState, "Need a place to save state");
 
   // This is a cheap push implementation, which
@@ -1278,18 +1278,18 @@ nscoord
 nsSpaceManager::ClearFloats(nscoord aY, PRUint8 aBreakType)
 {
   nscoord bottom = aY + mY;
 
   if ((!mHaveCachedLeftYMost && aBreakType != NS_STYLE_CLEAR_RIGHT) ||
       (!mHaveCachedRightYMost && aBreakType != NS_STYLE_CLEAR_LEFT)) {
     // Recover our maximal YMost values.  Might need both if this is a
     // NS_STYLE_CLEAR_LEFT_AND_RIGHT
-    nscoord maximalLeftYMost = mHaveCachedLeftYMost ? mMaximalLeftYMost : 0;
-    nscoord maximalRightYMost = mHaveCachedRightYMost ? mMaximalRightYMost : 0;
+    nscoord maximalLeftYMost = mHaveCachedLeftYMost ? mMaximalLeftYMost : nscoord_MIN;
+    nscoord maximalRightYMost = mHaveCachedRightYMost ? mMaximalRightYMost : nscoord_MIN;
 
     // Optimize for most floats not being near the bottom
     for (FrameInfo *frame = mFrameInfoMap; frame; frame = frame->mNext) {
       nscoord ymost = frame->mRect.YMost();
       if (ymost > maximalLeftYMost) {
         if (frame->mFrame->GetStyleDisplay()->mFloats == NS_STYLE_FLOAT_LEFT) {
           NS_ASSERTION(!mHaveCachedLeftYMost, "Shouldn't happen");
           maximalLeftYMost = ymost;
--- a/layout/reftests/box-properties/reftest.list
+++ b/layout/reftests/box-properties/reftest.list
@@ -1,10 +1,8 @@
-== column-gap-percent-1.html column-gap-percent-1-ref.html
-!= column-gap-percent-2.html column-gap-percent-2-ref.html
 == outline-radius-percent-1.html outline-radius-percent-1-ref.html
 == min-width-1.html min-width-1-ref.html
 == min-height-1.html min-height-1-ref.html
 == max-width-1.html max-width-1-ref.html
 == max-height-1.html max-height-1-ref.html
 == width-special-values-block.html width-special-values-block-ref.html
 == width-special-values-float.html width-special-values-block-ref.html
 == width-special-values-image-block.html width-special-values-image-block-ref.html
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/372768-1-ref.html
@@ -0,0 +1,10 @@
+<html>
+<body>
+<table width="100" border="4">
+  <tr>
+    <td width="200" id="td" nowrap="nowrap">
+    </td>
+  </tr>
+</table>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/372768-1.html
@@ -0,0 +1,14 @@
+<html>
+<body>
+<table width="100" border="4">
+  <tr>
+    <td width="200" id="td">
+    </td>
+  </tr>
+</table>
+<script>
+document.body.offsetWidth;
+document.getElementById("td").setAttribute("nowrap", "nowrap");
+</script>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/384762-1.html
@@ -0,0 +1,1 @@
+<div style="margin-top: -10em; clear:both">a
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/384876-1-ref.html
@@ -0,0 +1,37 @@
+<html>
+<head>
+    <title>Width:auto and padding</title>
+</head>
+
+<body>
+
+<div style="border-bottom:5px solid #000;
+            overflow: hidden;
+            background-color:#fbb;
+            position: absolute; 
+            left:0px;
+            top:20px"><div style="padding: 0px 0px 0px 45px;">The bottom border should end with my text (overflow:hidden)</div></div>
+
+<div style="border-bottom:5px solid #000;
+            overflow: visible;
+            background-color:#fbb;
+            position: absolute; 
+            left:0px;
+            top:60px"><div style="padding: 0px 0px 0px 45px;">The bottom border should end with my text (overflow:visible)</div></div>
+
+<div style="border-bottom:5px solid #000;
+            overflow: auto;
+            background-color:#fbb;
+            position: absolute; 
+            left:0px;
+            top:100px"><div style="padding: 0px 0px 0px 45px;">The bottom border should end with my text (overflow:auto)</div></div>
+
+<div style="border-bottom:5px solid #000;
+            background-color:#fbb;
+            position: absolute; 
+            left:0px;
+            top:140px"><div style="padding: 0px 0px 0px 45px;">The bottom border should end with my text (no overflow defined)</div></div>
+
+
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/384876-1.html
@@ -0,0 +1,41 @@
+<html>
+<head>
+    <title>Width:auto and padding</title>
+</head>
+
+<body>
+
+<div style="border-bottom:5px solid #000;
+            padding: 0px 0px 0px 45px;
+            overflow: hidden;
+            background-color:#fbb;
+            position: absolute; 
+            left:0px;
+            top:20px"><div>The bottom border should end with my text (overflow:hidden)</div></div>
+
+<div style="border-bottom:5px solid #000;
+            padding: 0px 0px 0px 45px;
+            overflow: visible;
+            background-color:#fbb;
+            position: absolute; 
+            left:0px;
+            top:60px"><div>The bottom border should end with my text (overflow:visible)</div></div>
+
+<div style="border-bottom:5px solid #000;
+            padding: 0px 0px 0px 45px;
+            overflow: auto;
+            background-color:#fbb;
+            position: absolute; 
+            left:0px;
+            top:100px"><div>The bottom border should end with my text (overflow:auto)</div></div>
+
+<div style="border-bottom:5px solid #000;
+            padding: 0px 0px 0px 45px;
+            background-color:#fbb;
+            position: absolute; 
+            left:0px;
+            top:140px"><div>The bottom border should end with my text (no overflow defined)</div></div>
+
+
+</body>
+</html>
--- a/layout/reftests/bugs/reftest.list
+++ b/layout/reftests/bugs/reftest.list
@@ -209,17 +209,17 @@ fails-if(MOZ_WIDGET_TOOLKIT=="cocoa") ==
 == 367612-1d.html 367612-1-ref.html
 == 367612-1e.html 367612-1-ref.html
 == 367612-1f.html 367612-1-ref.html
 != 367612-1g.html 367612-1-ref.html
 fails == 368020-1.html 368020-1-ref.html # bug 368079
 random-if(MOZ_WIDGET_TOOLKIT=="gtk2") == 368020-2.html 368020-2-ref.html # bug 368157 (gtk)
 fails == 368020-3.html 368020-3-ref.html # bug 368085
 fails == 368020-4.html 368020-4-ref.html # bug 368085
-== 368020-5.html 368020-5-ref.html
+random-if(MOZ_WIDGET_TOOLKIT=="gtk2") == 368020-5.html 368020-5-ref.html # bug 388591
 == 368155-1.xhtml 368155-1-ref.xhtml
 == 368155-negative-margins-1.html 368155-negative-margins-1-ref.html
 # we can't test this because there's antialiasing involved, and our comparison
 # is too exact
 # == 368247-1.html 368247-1-ref.html
 == 368247-2.html 368247-2-ref.html
 fails == 368504-1.html 368504-1-ref.html # bug 368504
 fails == 368504-2.html 368504-2-ref.html # bug 368504
@@ -251,16 +251,17 @@ fails == 368504-2.html 368504-2-ref.html
 == 371925-1a.html 371925-1-ref.html
 == 371925-1b.html 371925-1-ref.html
 == 372553-1.html 372553-1-ref.html
 == 373381-1.html 373381-1-ref.html
 fails-if(MOZ_WIDGET_TOOLKIT=="cocoa") == 372037-1.html 372037-1-ref.html # bug 377118
 == 375508-1.html 375508-1-ref.html
 == 373433-1.html 373433-1-ref.html
 == 372062-1.html 372062-1-ref.html
+== 372768-1.html 372768-1-ref.html
 == 374038-1.xul 374038-1-ref.xul
 == 374038-2.xul 374038-2-ref.xul
 == 374193-1.xhtml about:blank
 == 375716-1.html 375716-1-ref.html
 == 375827-1.html 375827-1-ref.html
 == 376484-1.html 376484-1-ref.html
 == 377603-1.html 377603-1-ref.html
 == 377918.html 377918-ref.html
@@ -271,10 +272,12 @@ random-if(MOZ_WIDGET_TOOLKIT=="cocoa") =
 == 380004-1.html 380004-1-ref.html
 == 380227-1.html 380227-1-ref.html
 == 380842-1.html 380842-1-ref.html
 == 381130-1.html 381130-1-ref.html
 == 381507-1.html 381507-1-ref.html
 == 382600-1.html 382600-1-ref.html
 == 383551-1.html 383551-1-ref.html
 == 384576-1.html 384576-1-ref.html
+== 384762-1.html about:blank
+== 384876-1.html 384876-1-ref.html
 == 386920-1.html 386920-1-ref.html
 == 387344-1.html 387344-1-ref.html
new file mode 100644
--- /dev/null
+++ b/layout/reftests/columns/basic-1.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <style>
+  div { -moz-column-count:2; -moz-column-gap:0; }
+  </style>
+</head>
+<body>
+  <div>
+    Hello<br>
+    Kitty
+  </div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/columns/basic-ref.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <style>
+  table { border-spacing:0 }
+  td { vertical-align: baseline; padding:0; }
+  </style>
+</head>
+<body>
+  <table border="0" width="100%">
+    <tr>
+      <td width="50%">Hello</td>
+      <td width="50%">Kitty</td>
+    </tr>
+  </table>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/columns/min-width-1-ref.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <style>
+  div { border:2px solid black; width:100px; height:200px; }
+  </style>
+</head>
+<body>
+  <table width="1"><tr><td><div></div></tr></td></table>
+  <table width="1"><tr><td><div></div></tr></td></table>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/columns/min-width-1a.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <style>
+  div { -moz-column-count:2; -moz-column-gap:0; border:2px solid black; height:200px; }
+  div.gap { -moz-column-gap:80px; }
+  span { display:inline-block; width:50px; }
+  </style>
+</head>
+<body>
+  <table width="1"><tr><td><div>
+    <span></span>
+  </div></tr></td></table>
+  <table width="1"><tr><td><div class="gap">
+    <span></span>
+  </div></tr></td></table>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/columns/min-width-1b.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <style>
+  div { -moz-column-width:200px; -moz-column-count:2; -moz-column-gap:0; border:2px solid black; height:200px; }
+  div.gap { -moz-column-gap:80px; }
+  span { display:inline-block; width:100px; }
+  </style>
+</head>
+<body>
+  <table width="1"><tr><td><div>
+    <span></span>
+  </div></tr></td></table>
+  <table width="1"><tr><td><div class="gap">
+    <span></span>
+  </div></tr></td></table>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/columns/min-width-1c.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <style>
+  div { -moz-column-width:100px; -moz-column-count:2; -moz-column-gap:0; border:2px solid black; height:200px; }
+  div.gap { -moz-column-gap:80px; }
+  span { display:inline-block; width:200px; }
+  </style>
+</head>
+<body>
+  <table width="1"><tr><td><div>
+    <span></span>
+  </div></tr></td></table>
+  <table width="1"><tr><td><div class="gap">
+    <span></span>
+  </div></tr></td></table>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/columns/pref-width-1-ref.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <style>
+  div { float:left; border:2px solid black; height:200px; }
+  div.clear { clear:both; }
+  span { display:inline-block; width:100px; }
+  span.gap { width:80px; }
+  </style>
+</head>
+<body>
+  <div>
+    <span></span><span></span>
+  </div>
+  <div class="clear">
+    <span></span><span class="gap"></span><span></span>
+  </div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/columns/pref-width-1a.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <style>
+  div { -moz-column-count:2; -moz-column-gap:0; float:left; border:2px solid black; height:200px; }
+  div.clear { clear:both; }
+  div.gap { -moz-column-gap:80px; }
+  span { display:inline-block; width:100px; }
+  </style>
+</head>
+<body>
+  <div>
+    <span></span><br><span></span>
+  </div>
+  <div class="gap clear">
+    <span></span><br><span></span>
+  </div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/columns/pref-width-1b.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <style>
+  div { -moz-column-count:2; -moz-column-width:100px; -moz-column-gap:0; float:left; border:2px solid black; height:200px; }
+  div.clear { clear:both; }
+  div.gap { -moz-column-gap:80px; }
+  span { display:inline-block; width:50px; }
+  </style>
+</head>
+<body>
+  <div>
+    <span></span><br><span></span>
+  </div>
+  <div class="gap clear">
+    <span></span><br><span></span>
+  </div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/columns/pref-width-1c.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <style>
+  div { -moz-column-count:2; -moz-column-width:100px; -moz-column-gap:0; float:left; border:2px solid black; height:200px; }
+  div.clear { clear:both; }
+  div.gap { -moz-column-gap:80px; }
+  span { display:inline-block; width:200px; }
+  </style>
+</head>
+<body>
+  <div>
+    <span></span><br><span></span>
+  </div>
+  <div class="gap clear">
+    <span></span><br><span></span>
+  </div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/columns/reftest.list
@@ -0,0 +1,7 @@
+== basic-1.html basic-ref.html
+== pref-width-1a.html pref-width-1-ref.html
+== pref-width-1b.html pref-width-1-ref.html
+== pref-width-1c.html pref-width-1-ref.html
+== min-width-1a.html min-width-1-ref.html
+== min-width-1b.html min-width-1-ref.html
+== min-width-1c.html min-width-1-ref.html
--- a/layout/reftests/object/404-data-with-type.html
+++ b/layout/reftests/object/404-data-with-type.html
@@ -1,12 +1,10 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
 <!-- http://biesi.damowmow.com/object/003.html -->
 <html lang="en">
 <head>
 <title>&lt;object&gt;: 404 data with type</title>
 </head>
 <body>
-<p><!-- XXX
- - This should really be on a server run locally
---><object type="text/html" data="http://www.mozilla.org/this_does_not_exist">PASS</object></p>
+<p><object type="text/html" data="extra/404.html">PASS</object></p>
 </body>
 </html>
--- a/layout/reftests/object/404-data.html
+++ b/layout/reftests/object/404-data.html
@@ -1,12 +1,10 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
 <!-- http://biesi.damowmow.com/object/002.html -->
 <html lang="en">
 <head>
 <title>&lt;object&gt;: 404 data</title>
 </head>
 <body>
-<p><!-- XXX
-  - This should really be on a server run locally
---><object data="http://www.mozilla.org/this_does_not_exist.html">PASS</object></p>
+<p><object data="extra/404.html">PASS</object></p>
 </body>
 </html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/object/extra/404.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+<head>
+<title>404 Not Found</title>
+</head>
+<body>
+<p>This is a 404 page.</p>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/object/extra/404.html^headers^
@@ -0,0 +1,1 @@
+HTTP 404 Not Found
--- a/layout/reftests/object/reftest.list
+++ b/layout/reftests/object/reftest.list
@@ -1,20 +1,27 @@
 == no-attrs.html no-attrs-ref.html
-== 404-data.html 404-data-ref.html
-== 404-data-with-type.html 404-data-with-type-ref.html
+HTTP == 404-data.html 404-data-ref.html
+HTTP == 404-data-with-type.html 404-data-with-type-ref.html
 == page-as-data.html page-as-data-ref.html
 == page-as-data-with-type.html page-as-data-with-type-ref.html
 == connection-refused.html connection-refused-ref.html
 == image.html image-ref.html
 == image-with-type.html image-with-type-ref.html
 == image-no-useful-extension-typesniff.html image-no-useful-extension-typesniff-ref.html
 == image-no-useful-extension-with-type.html image-no-useful-extension-with-type-ref.html
 #
-# XXX missing tests 011-015 from http://biesi.damowmow.com/object/ here; need
+# This test must be run on an HTTP server because it relies on the HTTP
+# Content-Type overriding the type specified by the attribute on the object,
+# but when run from a local file the type attribute will override the
+# content-sniffed assumed type (text/html based entirely on the extension).
+#
+HTTP == type-overridden-by-server.html type-overridden-by-server-ref.html
+#
+# XXX missing tests 012-015 from http://biesi.damowmow.com/object/ here; need
 #     a controllable HTTP server (or preferably one run on the test machine)
 #     to add them
 #
 == malformed-should-fallback.html malformed-should-fallback-ref.html
 == malformed-with-type.html malformed-with-type-ref.html
 #
 # XXX missing tests 018-021 from http://biesi.damowmow.com/object/ here; need
 #     a controllable HTTP server (or preferably one run on the test machine)
new file mode 100644
--- /dev/null
+++ b/layout/reftests/object/type-overridden-by-server-ref.html
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!-- http://biesi.damowmow.com/object/011.html -->
+<html lang="en">
+<head>
+<title>&lt;object&gt;: Server override of type (PNG vs HTML)</title>
+</head>
+<body>
+<p><iframe style="border: 0px" src="extra/pass.html"></iframe></p>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/object/type-overridden-by-server.html
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!-- http://biesi.damowmow.com/object/011.html -->
+<html lang="en">
+<head>
+<title>&lt;object&gt;: Server override of type (PNG vs HTML)</title>
+</head>
+<body>
+<p><object type="image/png" data="extra/pass.html">FAIL</object></p>
+</body>
+</html>
--- a/layout/reftests/reftest.list
+++ b/layout/reftests/reftest.list
@@ -47,8 +47,14 @@ include text-indent/reftest.list
 # text-transform/
 include text-transform/reftest.list
 
 # native-theme/
 include native-theme/reftest.list
 
 # bidi
 include bidi/reftest.list
+
+# z-index/
+include z-index/reftest.list
+ 
+# columns/
+include columns/reftest.list
new file mode 100644
--- /dev/null
+++ b/layout/reftests/z-index/reftest.list
@@ -0,0 +1,1 @@
+fails-if(MOZ_WIDGET_TOOLKIT=="windows") == z-index-1.html z-index-1-ref.html # bug 388744
new file mode 100644
--- /dev/null
+++ b/layout/reftests/z-index/z-index-1-ref.html
@@ -0,0 +1,59 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<style>
+.container {
+  position:absolute;
+  width:400px;
+  height:100px;
+  background-color:yellow;
+  z-index:0;
+}
+.container > div {
+  height:100px;
+  margin-bottom:-100px;
+}
+.negative {
+  width:380px;
+  background-color:blue;
+}
+.block {
+  width:360px;
+  background-color:purple;
+}
+.float {
+  width:340px;
+  background-color:green;
+}
+.inline {
+  width:320px;
+  background-color:pink;
+}
+#outline {
+  height:60px;
+  width:260px;
+  border:20px solid gray;
+}
+.positioned {
+  width:280px;
+  background-color:magenta;
+}
+.positive {
+  width:260px;
+  background-color:orange;
+}
+</style>
+</head>
+<body>
+<div class="container">
+  <div class="negative"></div>
+  <div class="block"></div>
+  <div class="float"></div>
+  <div class="inline"></div>
+  <div id="outline"></div>
+
+  <div class="positioned"></div>
+  <div class="positive"></div>
+</div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/z-index/z-index-1.html
@@ -0,0 +1,69 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<style>
+.container {
+  position:absolute;
+  width:400px;
+  height:100px;
+  font-size:0;
+  background-color:yellow;
+  line-height:0;
+  z-index:0;
+}
+.container > div {
+  height:100px;
+  margin-bottom:-100px;
+}
+.negative {
+  width:380px;
+  background-color:blue;
+  position:relative;
+  z-index:-1;
+}
+.block {
+  width:360px;
+  background-color:purple;
+}
+.float {
+  float:left;
+  width:340px;
+  margin-right:-340px;
+  background-color:green;
+}
+.inline {
+  width:320px;
+  display:inline-block;
+  background-color:pink;
+}
+#outline {
+  width:300px;
+  outline:20px solid gray;
+  outline-offset:-20px;
+}
+.positioned {
+  width:280px;
+  background-color:magenta;
+  position:relative;
+}
+.positive {
+  width:260px;
+  background-color:orange;
+  position:relative;
+  z-index:1;
+}
+</style>
+</head>
+<body>
+<div class="container">
+  <div class="positive"></div>
+  <div class="positioned"></div>
+  <div id="outline"></div>
+  <div class="inline"></div>
+  <div class="float"></div>
+
+  <div class="block"></div>
+  <div class="negative"></div>
+</div>
+</body>
+</html>
--- a/layout/style/nsCSSParser.cpp
+++ b/layout/style/nsCSSParser.cpp
@@ -4668,17 +4668,17 @@ PRBool CSSParserImpl::ParseSingleValuePr
   case eCSSProperty__moz_border_radius_bottomRight:
   case eCSSProperty__moz_border_radius_bottomLeft:
     return ParsePositiveVariant(aErrorCode, aValue, VARIANT_HLP, nsnull);
   case eCSSProperty__moz_column_count:
     return ParsePositiveVariant(aErrorCode, aValue, VARIANT_AHI, nsnull);
   case eCSSProperty__moz_column_width:
     return ParseVariant(aErrorCode, aValue, VARIANT_AHL, nsnull);
   case eCSSProperty__moz_column_gap:
-    return ParseVariant(aErrorCode, aValue, VARIANT_HLP | VARIANT_NORMAL, nsnull);
+    return ParseVariant(aErrorCode, aValue, VARIANT_HL | VARIANT_NORMAL, nsnull);
   case eCSSProperty__moz_outline_radius_topLeft:
   case eCSSProperty__moz_outline_radius_topRight:
   case eCSSProperty__moz_outline_radius_bottomRight:
   case eCSSProperty__moz_outline_radius_bottomLeft:
     return ParsePositiveVariant(aErrorCode, aValue, VARIANT_HLP, nsnull);
   case eCSSProperty_bottom:
   case eCSSProperty_top:
   case eCSSProperty_left:
--- a/layout/style/nsCSSValue.cpp
+++ b/layout/style/nsCSSValue.cpp
@@ -417,19 +417,34 @@ nsCSSValue::URL::operator==(const URL& a
 {
   PRBool eq;
   return NS_strcmp(GetBufferValue(mString),
                    GetBufferValue(aOther.mString)) == 0 &&
           (mURI == aOther.mURI || // handles null == null
            (mURI && aOther.mURI &&
             NS_SUCCEEDED(mURI->Equals(aOther.mURI, &eq)) &&
             eq)) &&
-          NS_SUCCEEDED(mOriginPrincipal->Equals(aOther.mOriginPrincipal,
-                                                &eq)) &&
-          eq;
+          (mOriginPrincipal == aOther.mOriginPrincipal ||
+           (NS_SUCCEEDED(mOriginPrincipal->Equals(aOther.mOriginPrincipal,
+                                                  &eq)) && eq));
+}
+
+PRBool
+nsCSSValue::URL::URIEquals(const URL& aOther) const
+{
+  PRBool eq;
+  // Worth comparing mURI to aOther.mURI and mOriginPrincipal to
+  // aOther.mOriginPrincipal, because in the (probably common) case when this
+  // value was one of the ones that in fact did not change this will be our
+  // fast path to equality
+  return (mURI == aOther.mURI ||
+          (NS_SUCCEEDED(mURI->Equals(aOther.mURI, &eq)) && eq)) &&
+         (mOriginPrincipal == aOther.mOriginPrincipal ||
+          (NS_SUCCEEDED(mOriginPrincipal->Equals(aOther.mOriginPrincipal,
+                                                 &eq)) && eq));
 }
 
 nsCSSValue::Image::Image(nsIURI* aURI, nsStringBuffer* aString,
                          nsIURI* aReferrer, nsIPrincipal* aOriginPrincipal,
                          nsIDocument* aDocument)
   : URL(aURI, aString, aReferrer, aOriginPrincipal)
 {
   MOZ_COUNT_CTOR(nsCSSValue::Image);
--- a/layout/style/nsCSSValue.h
+++ b/layout/style/nsCSSValue.h
@@ -227,16 +227,24 @@ public:
   nsIURI* GetURLValue() const
   {
     NS_ASSERTION(mUnit == eCSSUnit_URL || mUnit == eCSSUnit_Image,
                  "not a URL value");
     return mUnit == eCSSUnit_URL ?
       mValue.mURL->mURI : mValue.mImage->mURI;
   }
 
+  URL* GetURLStructValue() const
+  {
+    // Not allowing this for Image values, because if the caller takes
+    // a ref to them they won't be able to delete them properly.
+    NS_ASSERTION(mUnit == eCSSUnit_URL, "not a URL value");
+    return mValue.mURL;
+  }
+
   const PRUnichar* GetOriginalURLValue() const
   {
     NS_ASSERTION(mUnit == eCSSUnit_URL || mUnit == eCSSUnit_Image,
                  "not a URL value");
     return GetBufferValue(mUnit == eCSSUnit_URL ?
                             mValue.mURL->mString :
                             mValue.mImage->mString);
   }
@@ -383,16 +391,22 @@ public:
     // aOriginPrincipal must not be null.
     URL(nsIURI* aURI, nsStringBuffer* aString, nsIURI* aReferrer,
         nsIPrincipal* aOriginPrincipal) NS_HIDDEN;
 
     ~URL() NS_HIDDEN;
 
     NS_HIDDEN_(PRBool) operator==(const URL& aOther) const;
 
+    // URIEquals only compares URIs and principals (unlike operator==, which
+    // also compares the original strings).  URIEquals also assumes that the
+    // mURI member of both URL objects is non-null.  Do NOT call this method
+    // unless you're sure this is the case.
+    NS_HIDDEN_(PRBool) URIEquals(const URL& aOther) const;
+
     nsCOMPtr<nsIURI> mURI; // null == invalid URL
     nsStringBuffer* mString; // Could use nsRefPtr, but it'd add useless
                              // null-checks; this is never null.
     nsCOMPtr<nsIURI> mReferrer;
     nsCOMPtr<nsIPrincipal> mOriginPrincipal;
 
     void AddRef() { ++mRefCnt; }
     void Release() { if (--mRefCnt == 0) delete this; }
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -426,17 +426,17 @@ nsresult
 nsComputedDOMStyle::GetBinding(nsIDOMCSSValue** aValue)
 {
   nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
 
   const nsStyleDisplay* display = GetStyleDisplay();
 
   if (display->mBinding) {
-    val->SetURI(display->mBinding);
+    val->SetURI(display->mBinding->mURI);
   } else {
     val->SetIdent(nsGkAtoms::none);
   }
 
   return CallQueryInterface(val, aValue);
 }
 
 nsresult
@@ -586,18 +586,17 @@ nsComputedDOMStyle::GetColumnGap(nsIDOMC
 {
   nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
 
   const nsStyleColumn* column = GetStyleColumn();
   if (column->mColumnGap.GetUnit() == eStyleUnit_Normal) {
     val->SetAppUnits(GetStyleFont()->mFont.size);
   } else {
-    SetValueToCoord(val, GetStyleColumn()->mColumnGap,
-                    &nsComputedDOMStyle::GetFrameContentWidth);
+    SetValueToCoord(val, GetStyleColumn()->mColumnGap);
   }
 
   return CallQueryInterface(val, aValue);
 }
 
 nsresult
 nsComputedDOMStyle::GetCounterIncrement(nsIDOMCSSValue** aValue)
 {
@@ -2818,29 +2817,16 @@ nsComputedDOMStyle::StyleCoordToNSCoord(
     default:
       break;
   }
       
   return aDefaultValue;
 }
 
 PRBool
-nsComputedDOMStyle::GetFrameContentWidth(nscoord& aWidth)
-{
-  if (!mFrame) {
-    return PR_FALSE;
-  }
-
-  FlushPendingReflows();
-
-  aWidth = mFrame->GetContentRect().width;
-  return PR_TRUE;
-}
-
-PRBool
 nsComputedDOMStyle::GetCBContentWidth(nscoord& aWidth)
 {
   if (!mFrame) {
     return PR_FALSE;
   }
 
   nsIFrame* container = GetContainingBlockFor(mFrame);
   if (!container) {
--- a/layout/style/nsComputedDOMStyle.h
+++ b/layout/style/nsComputedDOMStyle.h
@@ -302,17 +302,16 @@ private:
    * eStyleUnit_Percent, attempts to resolve the percentage base and returns
    * the resulting nscoord.  If it's some other unit or a percentge base can't
    * be determined, returns aDefaultValue.
    */
   nscoord StyleCoordToNSCoord(const nsStyleCoord& aCoord,
                               PercentageBaseGetter aPercentageBaseGetter,
                               nscoord aDefaultValue);
 
-  PRBool GetFrameContentWidth(nscoord& aWidth);
   PRBool GetCBContentWidth(nscoord& aWidth);
   PRBool GetCBContentHeight(nscoord& aWidth);
   PRBool GetFrameBorderRectWidth(nscoord& aWidth);
 
   struct ComputedStyleMapEntry
   {
     // Create a pointer-to-member-function type.
     typedef nsresult (nsComputedDOMStyle::*ComputeMethod)(nsIDOMCSSValue**);
--- a/layout/style/nsRuleNode.cpp
+++ b/layout/style/nsRuleNode.cpp
@@ -2723,17 +2723,24 @@ nsRuleNode::ComputeDisplayData(nsStyleSt
   }
   else if (eCSSUnit_Inherit == displayData.mAppearance.GetUnit()) {
     inherited = PR_TRUE;
     display->mAppearance = parentDisplay->mAppearance;
   }
 
   // binding: url, none, inherit
   if (eCSSUnit_URL == displayData.mBinding.GetUnit()) {
-    display->mBinding = displayData.mBinding.GetURLValue();
+    nsCSSValue::URL* url = displayData.mBinding.GetURLStructValue();
+    NS_ASSERTION(url, "What's going on here?");
+    
+    if (NS_LIKELY(url->mURI)) {
+      display->mBinding = url;
+    } else {
+      display->mBinding = nsnull;
+    }
   }
   else if (eCSSUnit_None == displayData.mBinding.GetUnit()) {
     display->mBinding = nsnull;
   }
   else if (eCSSUnit_Inherit == displayData.mBinding.GetUnit()) {
     inherited = PR_TRUE;
     display->mBinding = parentDisplay->mBinding;
   }
--- a/layout/style/nsStyleContext.cpp
+++ b/layout/style/nsStyleContext.cpp
@@ -546,16 +546,25 @@ public:
       aImageRequest->GetURI(getter_AddRefs(uri));
     }
     if (uri) {
       uri->GetSpec(*this);
     } else {
       Assign("[none]");
     }
   }
+
+  URICString(nsCSSValue::URL* aURI) {
+    if (aURI) {
+      NS_ASSERTION(aURI->mURI, "Must have URI here!");
+      aURI->mURI->GetSpec(*this);
+    } else {
+      Assign("[none]");
+    }
+  }
   
   URICString& operator=(const URICString& aOther) {
     Assign(aOther);
     return *this;
   }
 };
 
 void nsStyleContext::List(FILE* out, PRInt32 aIndent)
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -71,16 +71,22 @@ static PRBool EqualURIs(nsIURI *aURI1, n
 {
   PRBool eq;
   return aURI1 == aURI2 ||    // handle null==null, and optimize
          (aURI1 && aURI2 &&
           NS_SUCCEEDED(aURI1->Equals(aURI2, &eq)) && // not equal on fail
           eq);
 }
 
+static PRBool EqualURIs(nsCSSValue::URL *aURI1, nsCSSValue::URL *aURI2)
+{
+  return aURI1 == aURI2 ||    // handle null==null, and optimize
+         (aURI1 && aURI2 && aURI1->URIEquals(*aURI2));
+}
+
 static PRBool EqualImages(imgIRequest *aImage1, imgIRequest* aImage2)
 {
   if (aImage1 == aImage2) {
     return PR_TRUE;
   }
 
   if (!aImage1 || !aImage2) {
     return PR_FALSE;
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -755,18 +755,20 @@ struct nsStyleDisplay : public nsStyleSt
     this->~nsStyleDisplay();
     aContext->FreeToShell(sizeof(nsStyleDisplay), this);
   }
 
   nsChangeHint CalcDifference(const nsStyleDisplay& aOther) const;
 #ifdef DEBUG
   static nsChangeHint MaxDifference();
 #endif
-  
-  nsCOMPtr<nsIURI> mBinding;    // [reset]
+
+  // We guarantee that if mBinding is non-null, so are mBinding->mURI and
+  // mBinding->mOriginPrincipal.
+  nsRefPtr<nsCSSValue::URL> mBinding;    // [reset]
 #if 0
   // XXX This is how it is defined in the CSS2 spec, but the errata
   // changed it to be consistent with the positioning draft and how
   // Nav and IE implement it
   nsMargin  mClip;              // [reset] offsets from respective edge
 #else
   nsRect    mClip;              // [reset] offsets from upper-left border edge
 #endif
@@ -1206,17 +1208,17 @@ struct nsStyleColumn : public nsStyleStr
 
   nsChangeHint CalcDifference(const nsStyleColumn& aOther) const;
 #ifdef DEBUG
   static nsChangeHint MaxDifference();
 #endif
 
   PRUint32     mColumnCount; // [reset] see nsStyleConsts.h
   nsStyleCoord mColumnWidth; // [reset]
-  nsStyleCoord mColumnGap;   // [reset]
+  nsStyleCoord mColumnGap;   // [reset] coord
 };
 
 #ifdef MOZ_SVG
 enum nsStyleSVGPaintType {
   eStyleSVGPaintType_None = 0,
   eStyleSVGPaintType_Color,
   eStyleSVGPaintType_Server
 };
--- a/layout/style/test/property_database.js
+++ b/layout/style/test/property_database.js
@@ -311,18 +311,18 @@ var gCSSProperties = {
 			"3px"
 		]
 	},
 	"-moz-column-gap": {
 		domProp: "MozColumnGap",
 		inherited: false,
 		type: CSS_TYPE_LONGHAND,
 		initial_values: [ "normal", "1em" ],
-		other_values: [ "2px", "4em", "3%" ],
-		invalid_values: []
+		other_values: [ "2px", "4em" ],
+		invalid_values: [ "3%" ]
 	},
 	"-moz-column-width": {
 		domProp: "MozColumnWidth",
 		inherited: false,
 		type: CSS_TYPE_LONGHAND,
 		initial_values: [ "auto" ],
 		other_values: [ "15px", "50%" ],
 		invalid_values: [ "20" ]
--- a/layout/style/test/test_bug302186.html
+++ b/layout/style/test/test_bug302186.html
@@ -10,248 +10,286 @@ https://bugzilla.mozilla.org/show_bug.cg
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
 
 <style>
 
 
 span { color: red }
 :default + span { color: green }
 
-
-/* static default 5 */
-span.reverse5 { color: green }
-:default + span.reverse5 { color: red }
-
-
-/* dynamic default 6 */
-span.reverse6 { color: green }
-:default + span.reverse6 { color: red }
-
-/* dynamic default 7 */
-span.reverse7 { color: green }
-:default + span.reverse7 { color: red }
-
-/* dynamic default 8 */
-span.reverse8 { color: green }
-:default + span.reverse8 { color: red }
-
-/* dynamic default 9 */
-span.reverse9 { color: green }
-:default + span.reverse9 { color: red }
-
-/* dynamic default 10 */
-span.reverse10 { color: green }
-:default + span.reverse10 { color: red }
-
-/* dynamic default 11 */
-span.reverse11 { color: green }
-:default + span.reverse11 { color: red }
-
-/* dynamic default 12 */
-span.reverse12 { color: green }
-:default + span.reverse12 { color: red }
-
-/* dynamic default 13 */
-span.reverse13 { color: green }
-:default + span.reverse13 { color: red }
-
-/* dynamic default 14 */
-span.reverse14 { color: green }
-:default + span.reverse14 { color: red }
-
-/* dynamic default 15 */
-span.reverse15 { color: green }
-:default + span.reverse15 { color: red }
-
-/* dynamic default 16 */
-span.reverse16 { color: green }
-:default + span.reverse16 { color: red }
-
-/* dynamic default 17 */
-span.reverse17 { color: green }
-:default + span.reverse17 { color: red }
-
-/* dynamic default 18 */
-span.reverse18 { color: green }
-:default + span.reverse18 { color: red }
-
-/* dynamic default 19 */
-span.reverse19 { color: green }
-:default + span.reverse19 { color: red }
-
-/* dynamic default 20 */
-span.reverse20 { color: green }
-:default + span.reverse20 { color: red }
-
+span.reverse { color: green }
+:default + span.reverse { color: red }
 
 button { display: none }
 input { display: none }
 </style>
 </head>
 <body>
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=302186">Mozilla Bug 302186</a>
 <p id="display"></p>
 <div id="content" style="display: block">
    
+  <!-- static default 1 -->
+  <form>
+   <div>
+    <input type="submit" checked="checked"><span id="s1a">There should be no red.</span>
+   </div>
+   <div>
+    <input type="submit"><span id="s1b" class="reverse">There should be no red.</span>
+   </div>
+  </form>
+  
+  <!-- static default 2 -->
+  <form>
+   <div>
+    <button type="submit" checked="checked" id="foo"></button>
+    <span id="s2a">There should be no red.</span>
+   </div>
+   <div>
+    <button type="submit"></button>
+    <span class="reverse" id="s2b">There should be no red.</span>
+   </div>
+  </form>
+
+  <!-- static default 3 -->
+  <form>
+   <div>
+    <input type="checkbox" checked="checked" id="foo">
+    <span id="s3a">There should be no red.</span>
+   </div>
+   <div>
+    <input checked="checked">
+    <span class="reverse" id="s3b">There should be no red.</span>
+   </div>
+  </form>
+
+  <!-- static default 3 -->
+  <form>
+   <div>
+    <input type="radio" checked="checked" id="foo">
+    <span id="s4a">There should be no red.</span>
+   </div>
+   <div>
+    <input checked="checked">
+    <span class="reverse" id="s4b">There should be no red.</span>
+   </div>
+  </form>
+
   <!-- static default 5 -->
   <form>
    <div>
-    <input type="image"><span id="5a">There should be no red.</span>
+    <input type="image"><span id="s5a">There should be no red.</span>
+   </div>
+   <div>
+  <input type="image"><span id="s5b" class="reverse">There should be no red.</span>
+
+   </div>
+  </form>
+
+  <!-- dynamic default 1 -->
+  <form>
+   <div>
+    <input type="submit" checked="checked" id="foo1">
+    <span class="reverse" id="1a">There should be no red.</span>
+   </div>
+   <div>
+    <input type="submit">
+    <span id="1b">There should be no red.</span>
+
+   </div>
+  </form>
+
+  <!-- dynamic default 2 -->
+  <form>
+   <div>
+    <button type="submit" checked="checked" id="foo2"></button>
+    <span class="reverse" id="2a">There should be no red.</span>
    </div>
    <div>
-  <input type="image"><span id="5b" class="reverse5">There should be no red.</span>
+    <button type="submit"></button>
+    <span id="2b">There should be no red.</span>
+   </div>
+  </form>
+
+  <!-- dynamic default 3 -->
+  <form>
+   <div>
+    <input type="checkbox" checked="checked" id="foo3">
+    <span class="reverse" id="3a">There should be no red.</span>
+   </div>
+   <div>
+    <input checked="checked" id="bar3">
+    <span id="3b">There should be no red.</span>
+   </div>
+  </form>
 
+  <!-- dynamic default 4 -->
+  <form>
+   <div>
+    <input type="radio" checked="checked" id="foo4">
+    <span class="reverse" id="4a" >There should be no red.</span>
+   </div>
+   <div>
+    <input checked="checked" id="bar4">
+    <span id="4b">There should be no red.</span>
+   </div>
+  </form>
+
+  <!-- dynamic default 5 -->
+  <form>
+   <div>
+    <input type="submit">
+    <input type="radio" checked="checked" id="foo5">
+    <span id="5" class="reverse">There should be no red.</span>
    </div>
   </form>
 
   <!-- dynamic default 6 -->
   <form>
   <div id="div6">
   <span id="6a">There should be no red.</span>
 </div>
 <div>
-  <input type="submit"><span id="6b" class="reverse6">There should be no red.</span>
+  <input type="submit"><span id="6b" class="reverse">There should be no red.</span>
 </div>
   </form>
 
   <!-- dynamic default 7 -->
   <form>
 <div>
   <input type="submit"><span id="7a">There should be no red.</span>
 </div>
 <div id="div7">
-  <span class="reverse7" id="7b">There should be no red.</span>
+  <span class="reverse" id="7b">There should be no red.</span>
 
 </div>
 </form>
 
   <!-- dynamic default 8 -->
 <form>
 <div id="div8"><span id="8a">There should be no red.</span>
 </div>
 <div>
-  <input type="image" id="foo"><span class="reverse8" id="8b">There should be no red.</span>
+  <input type="image" id="foo"><span class="reverse" id="8b">There should be no red.</span>
 
 </div>
 </form>
 
   <!-- dynamic default 9 -->
 <form>
 <div>
   <input type="image"><span id="9a">There should be no red.</span>
 </div>
 <div id="div9">
-  <span class="reverse9" id="9b">There should be no red.</span>
+  <span class="reverse" id="9b">There should be no red.</span>
 
 </div>
 </form>
 
   <!-- dynamic default 10 -->
 <form>
 <div id="div10">
-  <input type="submit"><span id="10a" class="reverse10">There should be no red.</span>
+  <input type="submit"><span id="10a" class="reverse">There should be no red.</span>
 </div>
 <div>
   <input type="submit"><span id="10b" >There should be no red.</span>
 
 </div>
 </form>
 
 <!-- dynamic default 11 -->
 <form>
 <div id="div11a">
   <input type="submit"><span id="11a">There should be no red.</span>
 </div>
 <div id="div11">
-  <input type="submit"><span id="11b" class="reverse11">There should be no red.</span>
+  <input type="submit"><span id="11b" class="reverse">There should be no red.</span>
 
 </div>
 </form>
 
 <!-- dynamic default 12 -->
 <form>
 <div id="div12">
-  <input type="image"><span id="12a" class="reverse12">There should be no red.</span>
+  <input type="image"><span id="12a" class="reverse">There should be no red.</span>
 </div>
 <div>
   <input type="image"><span id="12b">There should be no red.</span>
 
 </div>
 </form>
 
 <!-- dynamic default 13 -->
 <form>
 <div id="div13a">
   <input type="image"><span id="13a">There should be no red.</span>
 </div>
 <div id="div13">
-  <input type="image"><span id="13b" class="reverse13">There should be no red.</span>
+  <input type="image"><span id="13b" class="reverse">There should be no red.</span>
 
 </div>
 </form>
 
 <!-- dynamic default 14 -->
 <form>
 <div id="div14a">
   <input type="submit" id="foo14"><span id="14a">There should be no red.</span>
 </div>
 <div id="div14b">
-  <input type="submit" id="foo14b"><span id="14b" class="reverse14">There should be no red.</span>
+  <input type="submit" id="foo14b"><span id="14b" class="reverse">There should be no red.</span>
 
 </div>
 </form>
 
 <!-- dynamic default 15 -->
 <form>
 <div id="div15a">
   <input type="image" id="foo15a"><span id="15a">There should be no red.</span>
 </div>
 <div id="div15b">
-  <input type="image" id="foo15b"><span id="15b" class="reverse15">There should be no red.</span>
+  <input type="image" id="foo15b"><span id="15b" class="reverse">There should be no red.</span>
 
 </div>
 </form>
 
 <!-- dynamic default 16 -->
 <form>
 <div>
   <input type="image" checked="checked" id="foo16"></button>
-  <span class="reverse16" id="16a">There should be no red.</span>
+  <span class="reverse" id="16a">There should be no red.</span>
 </div>
 <div>
   <input type="image"></button><span id="16b">There should be no red.</span>
 
 </div>
 </form>
 
 <!-- dynamic default 17 -->
 <form>
 <div>
   <button type="button" id="foo17"></button>
   <span id="17a">There should be no red.</span>
 </div>
 <div>
-  <button type="submit"></button><span class="reverse17" id="17b">There should be no red.</span>
+  <button type="submit"></button><span class="reverse" id="17b">There should be no red.</span>
 </div>
 </form>
 
 <!-- dynamic default 18 -->
 <form>
 <div>
   <input type="button" id="foo18"></button>
   <span id="18a">There should be no red.</span>
 </div>
 <div>
-  <input type="submit"></button><span id="18b" class="reverse18">There should be no red.</span>
+  <input type="submit"></button><span id="18b" class="reverse">There should be no red.</span>
 
 </div>
 </form>
 
-
-
 <!-- dynamic default 19 -->
 <form>
 <div id="div19">
   <span id="19a">There should be no red.</span>
 </div>
 </form>
 
 <!-- dynamic default 20 -->
@@ -270,18 +308,57 @@ input { display: none }
 
 SimpleTest.waitForExplicitFinish();
 
 function idColor(anId) {
  var color = Color.fromComputedStyle(anId, "color");
  return color.toRGBString();
 }
 
-is(idColor("5a"),"rgb(0,128,0)", "CSS static-default 5a");
-is(idColor("5b"),"rgb(0,128,0)", "CSS static-default 5b");
+is(idColor("s1a"),"rgb(0,128,0)", "CSS static-default 1a");
+is(idColor("s1b"),"rgb(0,128,0)", "CSS static-default 1b");
+is(idColor("s2a"),"rgb(0,128,0)", "CSS static-default 2a");
+is(idColor("s2b"),"rgb(0,128,0)", "CSS static-default 2b");
+is(idColor("s3a"),"rgb(0,128,0)", "CSS static-default 3a");
+is(idColor("s3b"),"rgb(0,128,0)", "CSS static-default 3b");
+is(idColor("s4a"),"rgb(0,128,0)", "CSS static-default 4a");
+is(idColor("s4b"),"rgb(0,128,0)", "CSS static-default 4b");
+is(idColor("s5a"),"rgb(0,128,0)", "CSS static-default 5a");
+is(idColor("s5b"),"rgb(0,128,0)", "CSS static-default 5b");
+
+function dynamicDefault1() {
+  $('foo1').removeAttribute("type");
+  is(idColor("1a"),"rgb(0,128,0)", "CSS dynamic-default 1a");
+  is(idColor("1b"),"rgb(0,128,0)", "CSS dynamic-default 1b");
+}
+
+function dynamicDefault2() {
+  $('foo2').setAttribute("type", "button");
+  is(idColor("2a"),"rgb(0,128,0)", "CSS dynamic-default 2a");
+  is(idColor("2b"),"rgb(0,128,0)", "CSS dynamic-default 2b");
+}
+
+function dynamicDefault3() {
+  $('foo3').removeAttribute("type");
+  $('bar3').setAttribute("type", "checkbox");
+  is(idColor("3a"),"rgb(0,128,0)", "CSS dynamic-default 3a");
+  is(idColor("3b"),"rgb(0,128,0)", "CSS dynamic-default 3b");
+}
+
+function dynamicDefault4() {
+  $('foo4').removeAttribute("type");
+  $('bar4').setAttribute("type", "radio");
+  is(idColor("4a"),"rgb(0,128,0)", "CSS dynamic-default 4a");
+  is(idColor("4b"),"rgb(0,128,0)", "CSS dynamic-default 4b");
+}
+
+function dynamicDefault5() {
+  $('foo5').setAttribute("type", "submit")
+  is(idColor("5"),"rgb(0,128,0)", "CSS dynamic-default 5");
+}
 
 function dynamicDefault6() {
   var but = document.createElement("input");
   but.setAttribute("type", "submit");
   $('div6').insertBefore(but, $('div6').firstChild);
   todo(idColor("6a") == "rgb(0,128,0)", "CSS dynamic-default 6a");
   is(idColor("6b"),"rgb(0,128,0)", "CSS dynamic-default 6b");
 }
@@ -393,16 +470,21 @@ function dynamicDefault19() {
 function dynamicDefault20() {
   var newSubmit = document.createElement("input");
   newSubmit.setAttribute("type", "image");
   var div1 = document.getElementById("div20");
   div1.insertBefore(newSubmit, div1.firstChild);
   todo(idColor("20a") == "rgb(0,128,0)", "CSS dynamic-default 20a");
 }
 
+addLoadEvent(dynamicDefault1);
+addLoadEvent(dynamicDefault2);
+addLoadEvent(dynamicDefault3);
+addLoadEvent(dynamicDefault4);
+addLoadEvent(dynamicDefault5);
 addLoadEvent(dynamicDefault6);
 addLoadEvent(dynamicDefault7);
 addLoadEvent(dynamicDefault8);
 addLoadEvent(dynamicDefault9);
 addLoadEvent(dynamicDefault10);
 addLoadEvent(dynamicDefault11);
 addLoadEvent(dynamicDefault12);
 addLoadEvent(dynamicDefault13);
--- a/layout/style/test/test_bug365932.html
+++ b/layout/style/test/test_bug365932.html
@@ -34,18 +34,16 @@ https://bugzilla.mozilla.org/show_bug.cg
       border-width: 0 80px;
     }
   </style>
 </head>
 <body>
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=365932">Mozilla Bug 365932</a>
 <p id="display"></p>
 <div id="content">
-  <div id="column1" style="-moz-column-gap: 200px;"></div>
-  <div id="column2" style="-moz-column-gap: 50%;"></div>
   <div id="indent1" style="text-indent: 400px"></div>
   <div id="indent2" style="text-indent: 50%"></div>
 
   <div id="widthheight-1" class="auto"></div>
 
   <div id="minwidth1-1" style="min-width: 200px"></div>
   <div id="minwidth1-2" style="min-width: 25%"></div>
   <div id="minwidth2-1" style="min-width: 600px"></div>
@@ -149,18 +147,16 @@ https://bugzilla.mozilla.org/show_bug.cg
        style="min-height: 75%; max-height: 40%"></div>
 
   <div id="radius1" style="-moz-border-radius: 80px"></div>
   <div id="radius2" style="-moz-border-radius: 10%"></div>
   <div id="outlineradius1" style="-moz-outline-radius: 160px"></div>
   <div id="outlineradius2" style="-moz-outline-radius: 20%"></div>
 </div>
 <div id="content2" style="display: none">
-  <div id="column3" style="-moz-column-gap: 200px;"></div>
-  <div id="column4" style="-moz-column-gap: 50%;"></div>
   <div id="indent3" style="text-indent: 400px"></div>
   <div id="indent4" style="text-indent: 50%"></div>
 
   <div id="minwidth1-3" style="min-width: 200px"></div>
   <div id="minwidth1-4" style="min-width: 25%"></div>
   <div id="minwidth2-3" style="min-width: 600px"></div>
   <div id="minwidth2-4" style="min-width: 75%"></div>
 
@@ -204,17 +200,16 @@ https://bugzilla.mozilla.org/show_bug.cg
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
 /** Test for Bug 365932 **/
 
 document.body.offsetWidth;
 
-doATest("-moz-column-gap", "column", 200, 50);
 doATest("text-indent", "indent", 400, 50);
 doATest("-moz-border-radius-topleft", "radius", 80, 10);
 doATest("-moz-outline-radius-topleft", "outlineradius", 160, 20);
 
 doATest("width", "widthheight-", 440, 0);
 doATest("height", "widthheight-", 0, 0);
 
 doATest("min-width", "minwidth1-", 200, 25);
new file mode 100644
--- /dev/null
+++ b/layout/tools/pageloader/Makefile.in
@@ -0,0 +1,51 @@
+# vim: set shiftwidth=8 tabstop=8 autoindent noexpandtab copyindent:
+# ***** 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's pageloader test
+#
+# The Initial Developer of the Original Code is the Mozilla Foundation.
+# Portions created by the Initial Developer are Copyright (C) 2007
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#   Vladimir Vukicevic <vladimir@pobox.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 *****
+
+DEPTH		= ../../..
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+MODULE		= layout
+
+EXTRA_COMPONENTS= \
+		tp-cmdline.js \
+		$(NULL)
+
+include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/layout/tools/pageloader/README
@@ -0,0 +1,53 @@
+Pageload Test Component
+=======================
+
+Usage:
+
+  ./firefox -tp file:///path/to/manifest.txt [-tpargs...]
+
+See ./firefox -help for other arguments.
+
+The manifest file should contain a list of URLs or URL fragments, one
+per line.  Empty lines or lines starting with # are ignored.  If URL
+fragments are specified, then -tpprefix must be used to give a prefix
+to prepend to each line in the manifest to turn it into a complete
+URL.
+
+The result is a dump to stdout via dump() --
+browser.dom.window.dump.enabled must be set to true in the profile.  A
+number of output formats can be specified via the -tpformat command
+line option, currently 'js', 'text', and 'tinderbox' are supported.
+
+Sample 'js' format output:
+
+([({page:"1280x1024-PNG/index.html", value:133, stddev:20.049937655763422}),({page:"bugzilla.mozilla.org/index.html", value:233, stddev:36.66606060105176}),({page:"espn.go.com/index.html", value:117.6, stddev:1.2}),({page:"home.netscape.com/index.html", value:97.8, stddev:47.41898354035017}),])
+
+Sample 'text' format output:
+
+============================================================
+    Page                                     mean  stdd   min   max raw
+  0 1280x1024-PNG/index.html                  133    20   121   297 297,173,122,121,124,125
+  1 bugzilla.mozilla.org/index.html           233    37   192   395 395,273,223,192,198,279
+  2 espn.go.com/index.html                    118     1   116   254 254,117,116,119,119,117
+  3 home.netscape.com/index.html               98    47     3   124 3,121,120,124,124,121
+============================================================
+
+Sample 'tinderbox' format output:
+
+__start_tp_report
+_x_x_mozilla_page_load,778.5,NaN,NaN
+_x_x_mozilla_page_load_details,avgmedian|778.5|average|766.75|minimum|NaN|maximum|NaN|stddev|NaN|0;file:///c:/proj/mozilla-cvs/perf/tp2/base/www.cnn.com/index.html;778.5;766.75;722;1027;1027;788;777;722;780|...
+__end_tp_report
+
+Note that the minimum, maximum, stddev are not calculated; they're
+always reported as NaN.  (They were the minimum and maximum values of
+any sampled value, and the standard deviation across all sampled
+values -- not very useful.)
+
+TODO
+====
+
+* Command line option to choose whether to run with or without browser chrome.  Currently runs without.
+
+* Tinderbox-dropping style output
+  * better yet would be to teach tinderbox about JSON
new file mode 100644
--- /dev/null
+++ b/layout/tools/pageloader/jar.mn
@@ -0,0 +1,6 @@
+pageloader.jar:
+% content pageloader %content/
+* content/quit.js (quit.js)
+* content/pageloader.js (pageloader.js)
+  content/pageloader.xul (pageloader.xul)
+* content/report.js (report.js)
new file mode 100644
--- /dev/null
+++ b/layout/tools/pageloader/pageloader.js
@@ -0,0 +1,300 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** 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 tp.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Rob Helmer <rhelmer@mozilla.com>
+ *   Vladimir Vukicevic <vladimir@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 ***** */
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+
+var NUM_CYCLES = 5;
+
+var pageFilterRegexp = null;
+var reportFormat = "js";
+var useBrowser = true;
+var winWidth = 1024;
+var winHeight = 768;
+var urlPrefix = null;
+
+var doRenderTest = false;
+
+var pages;
+var pageIndex;
+var results;
+var start_time;
+var cycle;
+var report;
+var renderReport;
+var running = false;
+
+var content;
+
+var browserWindow = null;
+
+function plInit() {
+  if (running) {
+    return;
+  }
+  running = true;
+
+  cycle = 0;
+  results = {};
+
+  try {
+    var args = window.arguments[0].wrappedJSObject;
+
+    var manifestURI = args.manifest;
+    var startIndex = 0;
+    var endIndex = -1;
+    if (args.startIndex) startIndex = parseInt(args.startIndex);
+    if (args.endIndex) endIndex = parseInt(args.endIndex);
+    if (args.numCycles) NUM_CYCLES = parseInt(args.numCycles);
+    if (args.format) reportFormat = args.format;
+    if (args.width) winWidth = parseInt(args.width);
+    if (args.height) winHeight = parseInt(args.height);
+    if (args.filter) pageFilterRegexp = new RegExp(args.filter);
+    if (args.prefix) urlPrefix = args.prefix;
+    doRenderTest = args.doRender;
+
+    var ios = Cc["@mozilla.org/network/io-service;1"]
+      .getService(Ci.nsIIOService);
+    if (args.offline)
+      ios.offline = true;
+    var fileURI = ios.newURI(manifestURI, null, null);
+    pages = plLoadURLsFromURI(fileURI);
+
+    if (!pages) {
+      dumpLine('tp: could not load URLs, quitting');
+      plStop(true);
+    }
+
+    if (pages.length == 0) {
+      dumpLine('tp: no pages to test, quitting');
+      plStop(true);
+    }
+
+    if (startIndex < 0)
+      startIndex = 0;
+    if (endIndex == -1 || endIndex >= pages.length)
+      endIndex = pages.length-1;
+    if (startIndex > endIndex) {
+      dumpLine("tp: error: startIndex >= endIndex");
+      plStop(true);
+    }
+
+    pages = pages.slice(startIndex,endIndex+1);
+    report = new Report(pages);
+
+    if (doRenderTest)
+      renderReport = new Report(pages);
+
+    pageIndex = 0;
+
+    if (args.useBrowserChrome) {
+      var wwatch = Cc["@mozilla.org/embedcomp/window-watcher;1"]
+	.getService(Ci.nsIWindowWatcher);
+      var blank = Cc["@mozilla.org/supports-string;1"]
+	.createInstance(Ci.nsISupportsString);
+      blank.data = "about:blank";
+      browserWindow = wwatch.openWindow
+        (null, "chrome://browser/content/", "_blank",
+         "chrome,dialog=no,width=" + winWidth + ",height=" + winHeight, blank);
+
+      // get our window out of the way
+      window.resizeTo(10,10);
+
+      var browserLoadFunc = function (ev) {
+        browserWindow.removeEventListener('load', browserLoadFunc, true);
+
+        // do this half a second after load, because we need to be
+        // able to resize the window and not have it get clobbered
+        // by the persisted values
+        setTimeout(function () {
+                     browserWindow.resizeTo(winWidth, winHeight);
+                     browserWindow.moveTo(0, 0);
+                     browserWindow.focus();
+
+                     content = browserWindow.getBrowser();
+                     content.addEventListener('load', plLoadHandler, true);
+                     setTimeout(plLoadPage, 100);
+                   }, 500);
+      };
+
+      browserWindow.addEventListener('load', browserLoadFunc, true);
+    } else {
+      window.resizeTo(winWidth, winHeight);
+
+      content = document.getElementById('contentPageloader');
+      content.addEventListener('load', plLoadHandler, true);
+
+      setTimeout(plLoadPage, 0);
+    }
+  } catch(e) {
+    dumpLine(e);
+    plStop(true);
+  }
+}
+
+function plLoadPage() {
+  start_time = Date.now();
+  content.loadURI(pages[pageIndex]);
+}
+
+function plLoadHandler(evt) {
+  // make sure we pick up the right load event
+  if (evt.type != 'load' ||
+      (!evt.originalTarget instanceof Ci.nsIDOMHTMLDocument ||
+       evt.originalTarget.defaultView.frameElement))
+      return;
+
+  var end_time = Date.now();
+  var time = (end_time - start_time);
+
+  var pageName = pages[pageIndex];
+
+  results[pageName] = time;
+  report.recordTime(pageIndex, time);
+
+  if (doRenderTest)
+    runRenderTest();
+
+  if (pageIndex < pages.length-1) {
</