Merged with mozilla-central
authorOleg Romashin <romaxa@gmail.com>
Wed, 07 Apr 2010 06:59:04 -0400
changeset 46786 482000dcbafe7000feab98dbd8e3d56a7a5209c4
parent 46785 7eda6386d28c3802e566d20c2a3cbcbc311a4f18 (current diff)
parent 40531 6db519c93627697eec2a5398397a6f3188ae1114 (diff)
child 46787 2e96ee8bf80d3b266f74ba685fe1f0306ef0bc76
push idunknown
push userunknown
push dateunknown
milestone1.9.3a4pre
Merged with mozilla-central
accessible/src/html/nsHTMLAreaAccessible.cpp
accessible/src/html/nsHTMLAreaAccessible.h
browser/app/profile/firefox.js
caps/src/nsScriptSecurityManager.cpp
config/insure.mk
content/base/public/nsContentUtils.h
content/base/src/nsContentUtils.cpp
content/base/src/nsFrameMessageManager.cpp
content/base/src/nsGkAtomList.h
content/canvas/src/WebGLContext.cpp
content/canvas/src/nsCanvasRenderingContext2D.cpp
content/events/src/nsDOMEvent.cpp
content/events/src/nsDOMNotifyPaintEvent.cpp
content/events/src/nsDOMScrollAreaEvent.cpp
content/events/src/nsDOMUIEvent.cpp
content/html/content/src/nsGenericHTMLElement.cpp
content/html/content/src/nsHTMLCanvasElement.cpp
content/xul/content/src/nsXULElement.cpp
content/xul/content/src/nsXULElement.h
dom/base/nsDOMClassInfo.cpp
dom/base/nsDOMClassInfoID.h
dom/base/nsGlobalWindow.cpp
dom/base/nsJSEnvironment.cpp
dom/base/nsJSEnvironment.h
dom/interfaces/canvas/nsIDOMCanvasRenderingContext2D.idl
dom/plugins/PluginInstanceChild.cpp
dom/plugins/PluginInstanceParent.cpp
dom/plugins/PluginInstanceParent.h
dom/plugins/PluginMessageUtils.h
dom/plugins/PluginModuleChild.cpp
dom/plugins/PluginModuleChild.h
dom/plugins/PluginModuleParent.cpp
gfx/cairo/cairo/src/cairo-meta-surface.c
gfx/cairo/cairo/src/cairo-skiplist-private.h
gfx/cairo/cairo/src/cairo-skiplist.c
js/ctypes/CTypes.cpp
js/ctypes/CTypes.h
js/ctypes/Library.cpp
js/ctypes/Library.h
js/ctypes/Makefile.in
js/ctypes/Module.cpp
js/ctypes/Module.h
js/ctypes/ctypes.jsm
js/ctypes/ctypes.msg
js/ctypes/libffi.patch
js/ctypes/libffi/ChangeLog
js/ctypes/libffi/ChangeLog.libffi
js/ctypes/libffi/ChangeLog.libgcj
js/ctypes/libffi/ChangeLog.v1
js/ctypes/libffi/LICENSE
js/ctypes/libffi/Makefile.am
js/ctypes/libffi/Makefile.in
js/ctypes/libffi/README
js/ctypes/libffi/acinclude.m4
js/ctypes/libffi/aclocal.m4
js/ctypes/libffi/compile
js/ctypes/libffi/config.guess
js/ctypes/libffi/config.sub
js/ctypes/libffi/configure
js/ctypes/libffi/configure.ac
js/ctypes/libffi/configure.host
js/ctypes/libffi/depcomp
js/ctypes/libffi/doc/libffi.info
js/ctypes/libffi/doc/libffi.texi
js/ctypes/libffi/doc/stamp-vti
js/ctypes/libffi/doc/version.texi
js/ctypes/libffi/fficonfig.h.in
js/ctypes/libffi/include/Makefile.am
js/ctypes/libffi/include/Makefile.in
js/ctypes/libffi/include/ffi.h.in
js/ctypes/libffi/include/ffi_common.h
js/ctypes/libffi/install-sh
js/ctypes/libffi/libffi.pc.in
js/ctypes/libffi/libtool-version
js/ctypes/libffi/ltmain.sh
js/ctypes/libffi/m4/libtool.m4
js/ctypes/libffi/m4/ltoptions.m4
js/ctypes/libffi/m4/ltsugar.m4
js/ctypes/libffi/m4/ltversion.m4
js/ctypes/libffi/m4/lt~obsolete.m4
js/ctypes/libffi/man/Makefile.am
js/ctypes/libffi/man/Makefile.in
js/ctypes/libffi/man/ffi.3
js/ctypes/libffi/man/ffi_call.3
js/ctypes/libffi/man/ffi_prep_cif.3
js/ctypes/libffi/mdate-sh
js/ctypes/libffi/missing
js/ctypes/libffi/msvcc.sh
js/ctypes/libffi/src/alpha/ffi.c
js/ctypes/libffi/src/alpha/ffitarget.h
js/ctypes/libffi/src/alpha/osf.S
js/ctypes/libffi/src/arm/ffi.c
js/ctypes/libffi/src/arm/ffitarget.h
js/ctypes/libffi/src/arm/sysv.S
js/ctypes/libffi/src/avr32/ffi.c
js/ctypes/libffi/src/avr32/ffitarget.h
js/ctypes/libffi/src/avr32/sysv.S
js/ctypes/libffi/src/closures.c
js/ctypes/libffi/src/cris/ffi.c
js/ctypes/libffi/src/cris/ffitarget.h
js/ctypes/libffi/src/cris/sysv.S
js/ctypes/libffi/src/debug.c
js/ctypes/libffi/src/dlmalloc.c
js/ctypes/libffi/src/frv/eabi.S
js/ctypes/libffi/src/frv/ffi.c
js/ctypes/libffi/src/frv/ffitarget.h
js/ctypes/libffi/src/ia64/ffi.c
js/ctypes/libffi/src/ia64/ffitarget.h
js/ctypes/libffi/src/ia64/ia64_flags.h
js/ctypes/libffi/src/ia64/unix.S
js/ctypes/libffi/src/java_raw_api.c
js/ctypes/libffi/src/m32r/ffi.c
js/ctypes/libffi/src/m32r/ffitarget.h
js/ctypes/libffi/src/m32r/sysv.S
js/ctypes/libffi/src/m68k/ffi.c
js/ctypes/libffi/src/m68k/ffitarget.h
js/ctypes/libffi/src/m68k/sysv.S
js/ctypes/libffi/src/mips/ffi.c
js/ctypes/libffi/src/mips/ffitarget.h
js/ctypes/libffi/src/mips/n32.S
js/ctypes/libffi/src/mips/o32.S
js/ctypes/libffi/src/moxie/eabi.S
js/ctypes/libffi/src/moxie/ffi.c
js/ctypes/libffi/src/moxie/ffitarget.h
js/ctypes/libffi/src/pa/ffi.c
js/ctypes/libffi/src/pa/ffitarget.h
js/ctypes/libffi/src/pa/hpux32.S
js/ctypes/libffi/src/pa/linux.S
js/ctypes/libffi/src/powerpc/aix.S
js/ctypes/libffi/src/powerpc/aix_closure.S
js/ctypes/libffi/src/powerpc/asm.h
js/ctypes/libffi/src/powerpc/darwin.S
js/ctypes/libffi/src/powerpc/darwin_closure.S
js/ctypes/libffi/src/powerpc/ffi.c
js/ctypes/libffi/src/powerpc/ffi_darwin.c
js/ctypes/libffi/src/powerpc/ffitarget.h
js/ctypes/libffi/src/powerpc/linux64.S
js/ctypes/libffi/src/powerpc/linux64_closure.S
js/ctypes/libffi/src/powerpc/ppc_closure.S
js/ctypes/libffi/src/powerpc/sysv.S
js/ctypes/libffi/src/prep_cif.c
js/ctypes/libffi/src/raw_api.c
js/ctypes/libffi/src/s390/ffi.c
js/ctypes/libffi/src/s390/ffitarget.h
js/ctypes/libffi/src/s390/sysv.S
js/ctypes/libffi/src/sh/ffi.c
js/ctypes/libffi/src/sh/ffitarget.h
js/ctypes/libffi/src/sh/sysv.S
js/ctypes/libffi/src/sh64/ffi.c
js/ctypes/libffi/src/sh64/ffitarget.h
js/ctypes/libffi/src/sh64/sysv.S
js/ctypes/libffi/src/sparc/ffi.c
js/ctypes/libffi/src/sparc/ffitarget.h
js/ctypes/libffi/src/sparc/v8.S
js/ctypes/libffi/src/sparc/v9.S
js/ctypes/libffi/src/types.c
js/ctypes/libffi/src/x86/darwin.S
js/ctypes/libffi/src/x86/darwin64.S
js/ctypes/libffi/src/x86/ffi.c
js/ctypes/libffi/src/x86/ffi64.c
js/ctypes/libffi/src/x86/ffitarget.h
js/ctypes/libffi/src/x86/freebsd.S
js/ctypes/libffi/src/x86/sysv.S
js/ctypes/libffi/src/x86/unix64.S
js/ctypes/libffi/src/x86/win32.S
js/ctypes/libffi/src/x86/win64.S
js/ctypes/libffi/testsuite/Makefile.am
js/ctypes/libffi/testsuite/Makefile.in
js/ctypes/libffi/testsuite/config/default.exp
js/ctypes/libffi/testsuite/lib/libffi-dg.exp
js/ctypes/libffi/testsuite/lib/target-libpath.exp
js/ctypes/libffi/testsuite/lib/wrapper.exp
js/ctypes/libffi/testsuite/libffi.call/call.exp
js/ctypes/libffi/testsuite/libffi.call/closure_fn0.c
js/ctypes/libffi/testsuite/libffi.call/closure_fn1.c
js/ctypes/libffi/testsuite/libffi.call/closure_fn2.c
js/ctypes/libffi/testsuite/libffi.call/closure_fn3.c
js/ctypes/libffi/testsuite/libffi.call/closure_fn4.c
js/ctypes/libffi/testsuite/libffi.call/closure_fn5.c
js/ctypes/libffi/testsuite/libffi.call/closure_fn6.c
js/ctypes/libffi/testsuite/libffi.call/closure_loc_fn0.c
js/ctypes/libffi/testsuite/libffi.call/closure_stdcall.c
js/ctypes/libffi/testsuite/libffi.call/cls_12byte.c
js/ctypes/libffi/testsuite/libffi.call/cls_16byte.c
js/ctypes/libffi/testsuite/libffi.call/cls_18byte.c
js/ctypes/libffi/testsuite/libffi.call/cls_19byte.c
js/ctypes/libffi/testsuite/libffi.call/cls_1_1byte.c
js/ctypes/libffi/testsuite/libffi.call/cls_20byte.c
js/ctypes/libffi/testsuite/libffi.call/cls_20byte1.c
js/ctypes/libffi/testsuite/libffi.call/cls_24byte.c
js/ctypes/libffi/testsuite/libffi.call/cls_2byte.c
js/ctypes/libffi/testsuite/libffi.call/cls_3_1byte.c
js/ctypes/libffi/testsuite/libffi.call/cls_3byte1.c
js/ctypes/libffi/testsuite/libffi.call/cls_3byte2.c
js/ctypes/libffi/testsuite/libffi.call/cls_4_1byte.c
js/ctypes/libffi/testsuite/libffi.call/cls_4byte.c
js/ctypes/libffi/testsuite/libffi.call/cls_5_1_byte.c
js/ctypes/libffi/testsuite/libffi.call/cls_5byte.c
js/ctypes/libffi/testsuite/libffi.call/cls_64byte.c
js/ctypes/libffi/testsuite/libffi.call/cls_6_1_byte.c
js/ctypes/libffi/testsuite/libffi.call/cls_6byte.c
js/ctypes/libffi/testsuite/libffi.call/cls_7_1_byte.c
js/ctypes/libffi/testsuite/libffi.call/cls_7byte.c
js/ctypes/libffi/testsuite/libffi.call/cls_8byte.c
js/ctypes/libffi/testsuite/libffi.call/cls_9byte1.c
js/ctypes/libffi/testsuite/libffi.call/cls_9byte2.c
js/ctypes/libffi/testsuite/libffi.call/cls_align_double.c
js/ctypes/libffi/testsuite/libffi.call/cls_align_float.c
js/ctypes/libffi/testsuite/libffi.call/cls_align_longdouble.c
js/ctypes/libffi/testsuite/libffi.call/cls_align_longdouble_split.c
js/ctypes/libffi/testsuite/libffi.call/cls_align_longdouble_split2.c
js/ctypes/libffi/testsuite/libffi.call/cls_align_pointer.c
js/ctypes/libffi/testsuite/libffi.call/cls_align_sint16.c
js/ctypes/libffi/testsuite/libffi.call/cls_align_sint32.c
js/ctypes/libffi/testsuite/libffi.call/cls_align_sint64.c
js/ctypes/libffi/testsuite/libffi.call/cls_align_uint16.c
js/ctypes/libffi/testsuite/libffi.call/cls_align_uint32.c
js/ctypes/libffi/testsuite/libffi.call/cls_align_uint64.c
js/ctypes/libffi/testsuite/libffi.call/cls_dbls_struct.c
js/ctypes/libffi/testsuite/libffi.call/cls_double.c
js/ctypes/libffi/testsuite/libffi.call/cls_double_va.c
js/ctypes/libffi/testsuite/libffi.call/cls_float.c
js/ctypes/libffi/testsuite/libffi.call/cls_longdouble.c
js/ctypes/libffi/testsuite/libffi.call/cls_longdouble_va.c
js/ctypes/libffi/testsuite/libffi.call/cls_multi_schar.c
js/ctypes/libffi/testsuite/libffi.call/cls_multi_sshort.c
js/ctypes/libffi/testsuite/libffi.call/cls_multi_sshortchar.c
js/ctypes/libffi/testsuite/libffi.call/cls_multi_uchar.c
js/ctypes/libffi/testsuite/libffi.call/cls_multi_ushort.c
js/ctypes/libffi/testsuite/libffi.call/cls_multi_ushortchar.c
js/ctypes/libffi/testsuite/libffi.call/cls_pointer.c
js/ctypes/libffi/testsuite/libffi.call/cls_pointer_stack.c
js/ctypes/libffi/testsuite/libffi.call/cls_schar.c
js/ctypes/libffi/testsuite/libffi.call/cls_sint.c
js/ctypes/libffi/testsuite/libffi.call/cls_sshort.c
js/ctypes/libffi/testsuite/libffi.call/cls_uchar.c
js/ctypes/libffi/testsuite/libffi.call/cls_uint.c
js/ctypes/libffi/testsuite/libffi.call/cls_ulonglong.c
js/ctypes/libffi/testsuite/libffi.call/cls_ushort.c
js/ctypes/libffi/testsuite/libffi.call/err_bad_abi.c
js/ctypes/libffi/testsuite/libffi.call/err_bad_typedef.c
js/ctypes/libffi/testsuite/libffi.call/ffitest.h
js/ctypes/libffi/testsuite/libffi.call/float.c
js/ctypes/libffi/testsuite/libffi.call/float1.c
js/ctypes/libffi/testsuite/libffi.call/float2.c
js/ctypes/libffi/testsuite/libffi.call/float3.c
js/ctypes/libffi/testsuite/libffi.call/float4.c
js/ctypes/libffi/testsuite/libffi.call/huge_struct.c
js/ctypes/libffi/testsuite/libffi.call/many.c
js/ctypes/libffi/testsuite/libffi.call/many_win32.c
js/ctypes/libffi/testsuite/libffi.call/negint.c
js/ctypes/libffi/testsuite/libffi.call/nested_struct.c
js/ctypes/libffi/testsuite/libffi.call/nested_struct1.c
js/ctypes/libffi/testsuite/libffi.call/nested_struct10.c
js/ctypes/libffi/testsuite/libffi.call/nested_struct2.c
js/ctypes/libffi/testsuite/libffi.call/nested_struct3.c
js/ctypes/libffi/testsuite/libffi.call/nested_struct4.c
js/ctypes/libffi/testsuite/libffi.call/nested_struct5.c
js/ctypes/libffi/testsuite/libffi.call/nested_struct6.c
js/ctypes/libffi/testsuite/libffi.call/nested_struct7.c
js/ctypes/libffi/testsuite/libffi.call/nested_struct8.c
js/ctypes/libffi/testsuite/libffi.call/nested_struct9.c
js/ctypes/libffi/testsuite/libffi.call/problem1.c
js/ctypes/libffi/testsuite/libffi.call/promotion.c
js/ctypes/libffi/testsuite/libffi.call/pyobjc-tc.c
js/ctypes/libffi/testsuite/libffi.call/return_dbl.c
js/ctypes/libffi/testsuite/libffi.call/return_dbl1.c
js/ctypes/libffi/testsuite/libffi.call/return_dbl2.c
js/ctypes/libffi/testsuite/libffi.call/return_fl.c
js/ctypes/libffi/testsuite/libffi.call/return_fl1.c
js/ctypes/libffi/testsuite/libffi.call/return_fl2.c
js/ctypes/libffi/testsuite/libffi.call/return_fl3.c
js/ctypes/libffi/testsuite/libffi.call/return_ldl.c
js/ctypes/libffi/testsuite/libffi.call/return_ll.c
js/ctypes/libffi/testsuite/libffi.call/return_ll1.c
js/ctypes/libffi/testsuite/libffi.call/return_sc.c
js/ctypes/libffi/testsuite/libffi.call/return_sl.c
js/ctypes/libffi/testsuite/libffi.call/return_uc.c
js/ctypes/libffi/testsuite/libffi.call/return_ul.c
js/ctypes/libffi/testsuite/libffi.call/stret_large.c
js/ctypes/libffi/testsuite/libffi.call/stret_large2.c
js/ctypes/libffi/testsuite/libffi.call/stret_medium.c
js/ctypes/libffi/testsuite/libffi.call/stret_medium2.c
js/ctypes/libffi/testsuite/libffi.call/strlen.c
js/ctypes/libffi/testsuite/libffi.call/strlen_win32.c
js/ctypes/libffi/testsuite/libffi.call/struct1.c
js/ctypes/libffi/testsuite/libffi.call/struct2.c
js/ctypes/libffi/testsuite/libffi.call/struct3.c
js/ctypes/libffi/testsuite/libffi.call/struct4.c
js/ctypes/libffi/testsuite/libffi.call/struct5.c
js/ctypes/libffi/testsuite/libffi.call/struct6.c
js/ctypes/libffi/testsuite/libffi.call/struct7.c
js/ctypes/libffi/testsuite/libffi.call/struct8.c
js/ctypes/libffi/testsuite/libffi.call/struct9.c
js/ctypes/libffi/testsuite/libffi.call/testclosure.c
js/ctypes/libffi/testsuite/libffi.special/ffitestcxx.h
js/ctypes/libffi/testsuite/libffi.special/special.exp
js/ctypes/libffi/testsuite/libffi.special/unwindtest.cc
js/ctypes/libffi/testsuite/libffi.special/unwindtest_ffi_call.cc
js/ctypes/libffi/texinfo.tex
js/ctypes/tests/Makefile.in
js/ctypes/tests/jsctypes-test.cpp
js/ctypes/tests/jsctypes-test.h
js/ctypes/tests/unit/test_jsctypes.js.in
js/ctypes/typedefs.h
js/src/config/insure.mk
js/src/ipc/ObjectWrapperParent.cpp
js/src/jsapi.cpp
js/src/jsapi.h
js/src/jsinterpinlines.h
js/src/xpconnect/shell/xpcshell.cpp
js/src/xpconnect/src/xpcthreadcontext.cpp
layout/base/nsPresContext.cpp
layout/generic/crashtests/414740.html
modules/plugin/base/src/nsPluginHost.cpp
modules/plugin/test/mochitest/Makefile.in
modules/plugin/test/testplugin/nptest.cpp
testing/xpcshell/head.js
testing/xpcshell/runxpcshelltests.py
toolkit/components/places/tests/autocomplete/head_000.js
toolkit/components/places/tests/mochitest/bug_461710/Makefile.in
toolkit/components/places/tests/mochitest/bug_461710/link_page-2.html
toolkit/components/places/tests/mochitest/bug_461710/link_page-3.html
toolkit/components/places/tests/mochitest/bug_461710/link_page.html
toolkit/components/places/tests/mochitest/bug_461710/visited_page.html
toolkit/components/places/tests/mochitest/test_bug_461710.html
toolkit/content/widgets/browser.xml
toolkit/crashreporter/nsExceptionHandler.cpp
toolkit/library/libxul-config.mk
toolkit/toolkit-makefiles.sh
toolkit/toolkit-tiers.mk
toolkit/xre/nsAppRunner.cpp
toolkit/xre/nsEmbedFunctions.cpp
widget/src/qt/nsWindow.cpp
widget/src/qt/nsWindow.h
widget/src/windows/nsWindow.cpp
widget/src/windows/nsWindow.h
widget/src/windows/nsWindowGfx.cpp
--- a/LICENSE
+++ b/LICENSE
@@ -1,567 +1,9 @@
-                          MOZILLA PUBLIC LICENSE
-                                Version 1.1
-
-                              ---------------
-
-1. Definitions.
-
-     1.0.1. "Commercial Use" means distribution or otherwise making the
-     Covered Code available to a third party.
-
-     1.1. "Contributor" means each entity that creates or contributes to
-     the creation of Modifications.
-
-     1.2. "Contributor Version" means the combination of the Original
-     Code, prior Modifications used by a Contributor, and the Modifications
-     made by that particular Contributor.
-
-     1.3. "Covered Code" means the Original Code or Modifications or the
-     combination of the Original Code and Modifications, in each case
-     including portions thereof.
-
-     1.4. "Electronic Distribution Mechanism" means a mechanism generally
-     accepted in the software development community for the electronic
-     transfer of data.
-
-     1.5. "Executable" means Covered Code in any form other than Source
-     Code.
-
-     1.6. "Initial Developer" means the individual or entity identified
-     as the Initial Developer in the Source Code notice required by Exhibit
-     A.
-
-     1.7. "Larger Work" means a work which combines Covered Code or
-     portions thereof with code not governed by the terms of this License.
-
-     1.8. "License" means this document.
-
-     1.8.1. "Licensable" means having the right to grant, to the maximum
-     extent possible, whether at the time of the initial grant or
-     subsequently acquired, any and all of the rights conveyed herein.
-
-     1.9. "Modifications" means any addition to or deletion from the
-     substance or structure of either the Original Code or any previous
-     Modifications. When Covered Code is released as a series of files, a
-     Modification is:
-          A. Any addition to or deletion from the contents of a file
-          containing Original Code or previous Modifications.
-
-          B. Any new file that contains any part of the Original Code or
-          previous Modifications.
-
-     1.10. "Original Code" means Source Code of computer software code
-     which is described in the Source Code notice required by Exhibit A as
-     Original Code, and which, at the time of its release under this
-     License is not already Covered Code governed by this License.
-
-     1.10.1. "Patent Claims" means any patent claim(s), now owned or
-     hereafter acquired, including without limitation, method, process,
-     and apparatus claims, in any patent Licensable by grantor.
-
-     1.11. "Source Code" means the preferred form of the Covered Code for
-     making modifications to it, including all modules it contains, plus
-     any associated interface definition files, scripts used to control
-     compilation and installation of an Executable, or source code
-     differential comparisons against either the Original Code or another
-     well known, available Covered Code of the Contributor's choice. The
-     Source Code can be in a compressed or archival form, provided the
-     appropriate decompression or de-archiving software is widely available
-     for no charge.
-
-     1.12. "You" (or "Your") means an individual or a legal entity
-     exercising rights under, and complying with all of the terms of, this
-     License or a future version of this License issued under Section 6.1.
-     For legal entities, "You" includes any entity which controls, is
-     controlled by, or is under common control with You. For purposes of
-     this definition, "control" means (a) the power, direct or indirect,
-     to cause the direction or management of such entity, whether by
-     contract or otherwise, or (b) ownership of more than fifty percent
-     (50%) of the outstanding shares or beneficial ownership of such
-     entity.
-
-2. Source Code License.
-
-     2.1. The Initial Developer Grant.
-     The Initial Developer hereby grants You a world-wide, royalty-free,
-     non-exclusive license, subject to third party intellectual property
-     claims:
-          (a) under intellectual property rights (other than patent or
-          trademark) Licensable by Initial Developer to use, reproduce,
-          modify, display, perform, sublicense and distribute the Original
-          Code (or portions thereof) with or without Modifications, and/or
-          as part of a Larger Work; and
-
-          (b) under Patents Claims infringed by the making, using or
-          selling of Original Code, to make, have made, use, practice,
-          sell, and offer for sale, and/or otherwise dispose of the
-          Original Code (or portions thereof).
-
-          (c) the licenses granted in this Section 2.1(a) and (b) are
-          effective on the date Initial Developer first distributes
-          Original Code under the terms of this License.
-
-          (d) Notwithstanding Section 2.1(b) above, no patent license is
-          granted: 1) for code that You delete from the Original Code; 2)
-          separate from the Original Code; or 3) for infringements caused
-          by: i) the modification of the Original Code or ii) the
-          combination of the Original Code with other software or devices.
-
-     2.2. Contributor Grant.
-     Subject to third party intellectual property claims, each Contributor
-     hereby grants You a world-wide, royalty-free, non-exclusive license
-
-          (a) under intellectual property rights (other than patent or
-          trademark) Licensable by Contributor, to use, reproduce, modify,
-          display, perform, sublicense and distribute the Modifications
-          created by such Contributor (or portions thereof) either on an
-          unmodified basis, with other Modifications, as Covered Code
-          and/or as part of a Larger Work; and
-
-          (b) under Patent Claims infringed by the making, using, or
-          selling of Modifications made by that Contributor either alone
-          and/or in combination with its Contributor Version (or portions
-          of such combination), to make, use, sell, offer for sale, have
-          made, and/or otherwise dispose of: 1) Modifications made by that
-          Contributor (or portions thereof); and 2) the combination of
-          Modifications made by that Contributor with its Contributor
-          Version (or portions of such combination).
-
-          (c) the licenses granted in Sections 2.2(a) and 2.2(b) are
-          effective on the date Contributor first makes Commercial Use of
-          the Covered Code.
-
-          (d) Notwithstanding Section 2.2(b) above, no patent license is
-          granted: 1) for any code that Contributor has deleted from the
-          Contributor Version; 2) separate from the Contributor Version;
-          3) for infringements caused by: i) third party modifications of
-          Contributor Version or ii) the combination of Modifications made
-          by that Contributor with other software (except as part of the
-          Contributor Version) or other devices; or 4) under Patent Claims
-          infringed by Covered Code in the absence of Modifications made by
-          that Contributor.
-
-3. Distribution Obligations.
-
-     3.1. Application of License.
-     The Modifications which You create or to which You contribute are
-     governed by the terms of this License, including without limitation
-     Section 2.2. The Source Code version of Covered Code may be
-     distributed only under the terms of this License or a future version
-     of this License released under Section 6.1, and You must include a
-     copy of this License with every copy of the Source Code You
-     distribute. You may not offer or impose any terms on any Source Code
-     version that alters or restricts the applicable version of this
-     License or the recipients' rights hereunder. However, You may include
-     an additional document offering the additional rights described in
-     Section 3.5.
-
-     3.2. Availability of Source Code.
-     Any Modification which You create or to which You contribute must be
-     made available in Source Code form under the terms of this License
-     either on the same media as an Executable version or via an accepted
-     Electronic Distribution Mechanism to anyone to whom you made an
-     Executable version available; and if made available via Electronic
-     Distribution Mechanism, must remain available for at least twelve (12)
-     months after the date it initially became available, or at least six
-     (6) months after a subsequent version of that particular Modification
-     has been made available to such recipients. You are responsible for
-     ensuring that the Source Code version remains available even if the
-     Electronic Distribution Mechanism is maintained by a third party.
-
-     3.3. Description of Modifications.
-     You must cause all Covered Code to which You contribute to contain a
-     file documenting the changes You made to create that Covered Code and
-     the date of any change. You must include a prominent statement that
-     the Modification is derived, directly or indirectly, from Original
-     Code provided by the Initial Developer and including the name of the
-     Initial Developer in (a) the Source Code, and (b) in any notice in an
-     Executable version or related documentation in which You describe the
-     origin or ownership of the Covered Code.
-
-     3.4. Intellectual Property Matters
-          (a) Third Party Claims.
-          If Contributor has knowledge that a license under a third party's
-          intellectual property rights is required to exercise the rights
-          granted by such Contributor under Sections 2.1 or 2.2,
-          Contributor must include a text file with the Source Code
-          distribution titled "LEGAL" which describes the claim and the
-          party making the claim in sufficient detail that a recipient will
-          know whom to contact. If Contributor obtains such knowledge after
-          the Modification is made available as described in Section 3.2,
-          Contributor shall promptly modify the LEGAL file in all copies
-          Contributor makes available thereafter and shall take other steps
-          (such as notifying appropriate mailing lists or newsgroups)
-          reasonably calculated to inform those who received the Covered
-          Code that new knowledge has been obtained.
-
-          (b) Contributor APIs.
-          If Contributor's Modifications include an application programming
-          interface and Contributor has knowledge of patent licenses which
-          are reasonably necessary to implement that API, Contributor must
-          also include this information in the LEGAL file.
-
-          (c) Representations.
-          Contributor represents that, except as disclosed pursuant to
-          Section 3.4(a) above, Contributor believes that Contributor's
-          Modifications are Contributor's original creation(s) and/or
-          Contributor has sufficient rights to grant the rights conveyed by
-          this License.
-
-     3.5. Required Notices.
-     You must duplicate the notice in Exhibit A in each file of the Source
-     Code. If it is not possible to put such notice in a particular Source
-     Code file due to its structure, then You must include such notice in a
-     location (such as a relevant directory) where a user would be likely
-     to look for such a notice. If You created one or more Modification(s)
-     You may add your name as a Contributor to the notice described in
-     Exhibit A. You must also duplicate this License in any documentation
-     for the Source Code where You describe recipients' rights or ownership
-     rights relating to Covered Code. You may choose to offer, and to
-     charge a fee for, warranty, support, indemnity or liability
-     obligations to one or more recipients of Covered Code. However, You
-     may do so only on Your own behalf, and not on behalf of the Initial
-     Developer or any Contributor. You must make it absolutely clear than
-     any such warranty, support, indemnity or liability obligation is
-     offered by You alone, and You hereby agree to indemnify the Initial
-     Developer and every Contributor for any liability incurred by the
-     Initial Developer or such Contributor as a result of warranty,
-     support, indemnity or liability terms You offer.
-
-     3.6. Distribution of Executable Versions.
-     You may distribute Covered Code in Executable form only if the
-     requirements of Section 3.1-3.5 have been met for that Covered Code,
-     and if You include a notice stating that the Source Code version of
-     the Covered Code is available under the terms of this License,
-     including a description of how and where You have fulfilled the
-     obligations of Section 3.2. The notice must be conspicuously included
-     in any notice in an Executable version, related documentation or
-     collateral in which You describe recipients' rights relating to the
-     Covered Code. You may distribute the Executable version of Covered
-     Code or ownership rights under a license of Your choice, which may
-     contain terms different from this License, provided that You are in
-     compliance with the terms of this License and that the license for the
-     Executable version does not attempt to limit or alter the recipient's
-     rights in the Source Code version from the rights set forth in this
-     License. If You distribute the Executable version under a different
-     license You must make it absolutely clear that any terms which differ
-     from this License are offered by You alone, not by the Initial
-     Developer or any Contributor. You hereby agree to indemnify the
-     Initial Developer and every Contributor for any liability incurred by
-     the Initial Developer or such Contributor as a result of any such
-     terms You offer.
-
-     3.7. Larger Works.
-     You may create a Larger Work by combining Covered Code with other code
-     not governed by the terms of this License and distribute the Larger
-     Work as a single product. In such a case, You must make sure the
-     requirements of this License are fulfilled for the Covered Code.
-
-4. Inability to Comply Due to Statute or Regulation.
-
-     If it is impossible for You to comply with any of the terms of this
-     License with respect to some or all of the Covered Code due to
-     statute, judicial order, or regulation then You must: (a) comply with
-     the terms of this License to the maximum extent possible; and (b)
-     describe the limitations and the code they affect. Such description
-     must be included in the LEGAL file described in Section 3.4 and must
-     be included with all distributions of the Source Code. Except to the
-     extent prohibited by statute or regulation, such description must be
-     sufficiently detailed for a recipient of ordinary skill to be able to
-     understand it.
-
-5. Application of this License.
-
-     This License applies to code to which the Initial Developer has
-     attached the notice in Exhibit A and to related Covered Code.
-
-6. Versions of the License.
-
-     6.1. New Versions.
-     Netscape Communications Corporation ("Netscape") may publish revised
-     and/or new versions of the License from time to time. Each version
-     will be given a distinguishing version number.
+Please see the file toolkit/content/license.html for the copyright licensing
+conditions attached to this codebase, including copies of the licenses
+concerned.
 
-     6.2. Effect of New Versions.
-     Once Covered Code has been published under a particular version of the
-     License, You may always continue to use it under the terms of that
-     version. You may also choose to use such Covered Code under the terms
-     of any subsequent version of the License published by Netscape. No one
-     other than Netscape has the right to modify the terms applicable to
-     Covered Code created under this License.
-
-     6.3. Derivative Works.
-     If You create or use a modified version of this License (which you may
-     only do in order to apply it to code which is not already Covered Code
-     governed by this License), You must (a) rename Your license so that
-     the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape",
-     "MPL", "NPL" or any confusingly similar phrase do not appear in your
-     license (except to note that your license differs from this License)
-     and (b) otherwise make it clear that Your version of the license
-     contains terms which differ from the Mozilla Public License and
-     Netscape Public License. (Filling in the name of the Initial
-     Developer, Original Code or Contributor in the notice described in
-     Exhibit A shall not of themselves be deemed to be modifications of
-     this License.)
-
-7. DISCLAIMER OF WARRANTY.
-
-     COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS,
-     WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
-     WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF
-     DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING.
-     THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE
-     IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT,
-     YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE
-     COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER
-     OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF
-     ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER.
-
-8. TERMINATION.
-
-     8.1. This License and the rights granted hereunder will terminate
-     automatically if You fail to comply with terms herein and fail to cure
-     such breach within 30 days of becoming aware of the breach. All
-     sublicenses to the Covered Code which are properly granted shall
-     survive any termination of this License. Provisions which, by their
-     nature, must remain in effect beyond the termination of this License
-     shall survive.
-
-     8.2. If You initiate litigation by asserting a patent infringement
-     claim (excluding declatory judgment actions) against Initial Developer
-     or a Contributor (the Initial Developer or Contributor against whom
-     You file such action is referred to as "Participant") alleging that:
-
-     (a) such Participant's Contributor Version directly or indirectly
-     infringes any patent, then any and all rights granted by such
-     Participant to You under Sections 2.1 and/or 2.2 of this License
-     shall, upon 60 days notice from Participant terminate prospectively,
-     unless if within 60 days after receipt of notice You either: (i)
-     agree in writing to pay Participant a mutually agreeable reasonable
-     royalty for Your past and future use of Modifications made by such
-     Participant, or (ii) withdraw Your litigation claim with respect to
-     the Contributor Version against such Participant. If within 60 days
-     of notice, a reasonable royalty and payment arrangement are not
-     mutually agreed upon in writing by the parties or the litigation claim
-     is not withdrawn, the rights granted by Participant to You under
-     Sections 2.1 and/or 2.2 automatically terminate at the expiration of
-     the 60 day notice period specified above.
-
-     (b) any software, hardware, or device, other than such Participant's
-     Contributor Version, directly or indirectly infringes any patent, then
-     any rights granted to You by such Participant under Sections 2.1(b)
-     and 2.2(b) are revoked effective as of the date You first made, used,
-     sold, distributed, or had made, Modifications made by that
-     Participant.
-
-     8.3. If You assert a patent infringement claim against Participant
-     alleging that such Participant's Contributor Version directly or
-     indirectly infringes any patent where such claim is resolved (such as
-     by license or settlement) prior to the initiation of patent
-     infringement litigation, then the reasonable value of the licenses
-     granted by such Participant under Sections 2.1 or 2.2 shall be taken
-     into account in determining the amount or value of any payment or
-     license.
-
-     8.4. In the event of termination under Sections 8.1 or 8.2 above,
-     all end user license agreements (excluding distributors and resellers)
-     which have been validly granted by You or any distributor hereunder
-     prior to termination shall survive termination.
-
-9. LIMITATION OF LIABILITY.
-
-     UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT
-     (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL
-     DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE,
-     OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR
-     ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY
-     CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL,
-     WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER
-     COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN
-     INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF
-     LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY
-     RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW
-     PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE
-     EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO
-     THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU.
-
-10. U.S. GOVERNMENT END USERS.
-
-     The Covered Code is a "commercial item," as that term is defined in
-     48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer
-     software" and "commercial computer software documentation," as such
-     terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48
-     C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995),
-     all U.S. Government End Users acquire Covered Code with only those
-     rights set forth herein.
-
-11. MISCELLANEOUS.
-
-     This License represents the complete agreement concerning subject
-     matter hereof. If any provision of this License is held to be
-     unenforceable, such provision shall be reformed only to the extent
-     necessary to make it enforceable. This License shall be governed by
-     California law provisions (except to the extent applicable law, if
-     any, provides otherwise), excluding its conflict-of-law provisions.
-     With respect to disputes in which at least one party is a citizen of,
-     or an entity chartered or registered to do business in the United
-     States of America, any litigation relating to this License shall be
-     subject to the jurisdiction of the Federal Courts of the Northern
-     District of California, with venue lying in Santa Clara County,
-     California, with the losing party responsible for costs, including
-     without limitation, court costs and reasonable attorneys' fees and
-     expenses. The application of the United Nations Convention on
-     Contracts for the International Sale of Goods is expressly excluded.
-     Any law or regulation which provides that the language of a contract
-     shall be construed against the drafter shall not apply to this
-     License.
-
-12. RESPONSIBILITY FOR CLAIMS.
+You are not granted rights or licenses to the trademarks of the
+Mozilla Foundation or any party, including without limitation the
+Firefox name or logo.
 
-     As between Initial Developer and the Contributors, each party is
-     responsible for claims and damages arising, directly or indirectly,
-     out of its utilization of rights under this License and You agree to
-     work with Initial Developer and Contributors to distribute such
-     responsibility on an equitable basis. Nothing herein is intended or
-     shall be deemed to constitute any admission of liability.
-
-13. MULTIPLE-LICENSED CODE.
-
-     Initial Developer may designate portions of the Covered Code as
-     "Multiple-Licensed". "Multiple-Licensed" means that the Initial
-     Developer permits you to utilize portions of the Covered Code under
-     Your choice of the NPL or the alternative licenses, if any, specified
-     by the Initial Developer in the file described in Exhibit A.
-
-EXHIBIT A -Mozilla Public License.
-
-     ``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 ______________________________________.
-
-     The Initial Developer of the Original Code is ________________________.
-     Portions created by ______________________ are Copyright (C) ______
-     _______________________. All Rights Reserved.
-
-     Contributor(s): ______________________________________.
-
-     Alternatively, the contents of this file may be used under the terms
-     of the _____ license (the "[___] License"), in which case the
-     provisions of [______] License are applicable instead of those
-     above. If you wish to allow use of your version of this file only
-     under the terms of the [____] License and not to allow others to use
-     your version of this file under the MPL, indicate your decision by
-     deleting the provisions above and replace them with the notice and
-     other provisions required by the [___] License. If you do not delete
-     the provisions above, a recipient may use your version of this file
-     under either the MPL or the [___] License."
-
-     [NOTE: The text of this Exhibit A may differ slightly from the text of
-     the notices in the Source Code files of the Original Code. You should
-     use the text of this Exhibit A rather than the text found in the
-     Original Code Source Code for Your Modifications.]
-
-     ----------------------------------------------------------------------
-
-     AMENDMENTS
-
-     The Netscape Public License Version 1.1 ("NPL") consists of the
-     Mozilla Public License Version 1.1 with the following Amendments,
-     including Exhibit A-Netscape Public License. Files identified with
-     "Exhibit A-Netscape Public License" are governed by the Netscape
-     Public License Version 1.1.
-
-     Additional Terms applicable to the Netscape Public License.
-          I. Effect.
-          These additional terms described in this Netscape Public
-          License -- Amendments shall apply to the Mozilla Communicator
-          client code and to all Covered Code under this License.
-
-          II. "Netscape's Branded Code" means Covered Code that Netscape
-          distributes and/or permits others to distribute under one or more
-          trademark(s) which are controlled by Netscape but which are not
-          licensed for use under this License.
-
-          III. Netscape and logo.
-          This License does not grant any rights to use the trademarks
-          "Netscape", the "Netscape N and horizon" logo or the "Netscape
-          lighthouse" logo, "Netcenter", "Gecko", "Java" or "JavaScript",
-          "Smart Browsing" even if such marks are included in the Original
-          Code or Modifications.
-
-          IV. Inability to Comply Due to Contractual Obligation.
-          Prior to licensing the Original Code under this License, Netscape
-          has licensed third party code for use in Netscape's Branded Code.
-          To the extent that Netscape is limited contractually from making
-          such third party code available under this License, Netscape may
-          choose to reintegrate such code into Covered Code without being
-          required to distribute such code in Source Code form, even if
-          such code would otherwise be considered "Modifications" under
-          this License.
-
-          V. Use of Modifications and Covered Code by Initial Developer.
-               V.1. In General.
-               The obligations of Section 3 apply to Netscape, except to
-               the extent specified in this Amendment, Section V.2 and V.3.
-
-               V.2. Other Products.
-               Netscape may include Covered Code in products other than the
-               Netscape's Branded Code which are released by Netscape
-               during the two (2) years following the release date of the
-               Original Code, without such additional products becoming
-               subject to the terms of this License, and may license such
-               additional products on different terms from those contained
-               in this License.
-
-               V.3. Alternative Licensing.
-               Netscape may license the Source Code of Netscape's Branded
-               Code, including Modifications incorporated therein, without
-               such Netscape Branded Code becoming subject to the terms of
-               this License, and may license such Netscape Branded Code on
-               different terms from those contained in this License.
-
-          VI. Litigation.
-          Notwithstanding the limitations of Section 11 above, the
-          provisions regarding litigation in Section 11(a), (b) and (c) of
-          the License shall apply to all disputes relating to this License.
-
-     EXHIBIT A-Netscape Public License.
-
-          "The contents of this file are subject to the Netscape 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/NPL/
-
-          Software distributed under the License is distributed on an "AS
-          IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
-          implied. See the License for the specific language governing
-          rights and limitations under the License.
-
-          The Original Code is Mozilla Communicator client code, released
-          March 31, 1998.
-
-          The Initial Developer of the Original Code is Netscape
-          Communications Corporation. Portions created by Netscape are
-          Copyright (C) 1998-1999 Netscape Communications Corporation. All
-          Rights Reserved.
-
-          Contributor(s): ______________________________________.
-
-          Alternatively, the contents of this file may be used under the
-          terms of the _____ license (the "[___] License"), in which case
-          the provisions of [______] License are applicable  instead of
-          those above. If you wish to allow use of your version of this
-          file only under the terms of the [____] License and not to allow
-          others to use your version of this file under the NPL, indicate
-          your decision by deleting the provisions above and replace  them
-          with the notice and other provisions required by the [___]
-          License. If you do not delete the provisions above, a recipient
-          may use your version of this file under either the NPL or the
-          [___] License."
+For more information, see: http://www.mozilla.org/foundation/licensing.html
--- a/accessible/src/base/nsAccessibilityAtomList.h
+++ b/accessible/src/base/nsAccessibilityAtomList.h
@@ -192,16 +192,17 @@ ACCESSIBILITY_ATOM(scope, "scope") // HT
 ACCESSIBILITY_ATOM(simple, "simple") // XLink
 ACCESSIBILITY_ATOM(src, "src")
 ACCESSIBILITY_ATOM(selected, "selected")
 ACCESSIBILITY_ATOM(summary, "summary")
 ACCESSIBILITY_ATOM(tabindex, "tabindex")
 ACCESSIBILITY_ATOM(title, "title")
 ACCESSIBILITY_ATOM(tooltiptext, "tooltiptext")
 ACCESSIBILITY_ATOM(type, "type")
+ACCESSIBILITY_ATOM(usemap, "usemap")
 ACCESSIBILITY_ATOM(value, "value")
 
   // Alphabetical list of object attributes
 ACCESSIBILITY_ATOM(checkable, "checkable")
 ACCESSIBILITY_ATOM(display, "display")
 ACCESSIBILITY_ATOM(eventFromInput, "event-from-input")
 ACCESSIBILITY_ATOM(textAlign, "text-align")
 ACCESSIBILITY_ATOM(textIndent, "text-indent")
--- a/accessible/src/base/nsAccessibilityService.cpp
+++ b/accessible/src/base/nsAccessibilityService.cpp
@@ -42,32 +42,34 @@
 #include "nsCoreUtils.h"
 #include "nsAccUtils.h"
 #include "nsApplicationAccessibleWrap.h"
 #include "nsARIAGridAccessibleWrap.h"
 #include "nsARIAMap.h"
 #include "nsIContentViewer.h"
 #include "nsCURILoader.h"
 #include "nsDocAccessible.h"
-#include "nsHTMLImageAccessibleWrap.h"
+#include "nsHTMLImageMapAccessible.h"
 #include "nsHTMLLinkAccessible.h"
 #include "nsHTMLSelectAccessible.h"
 #include "nsHTMLTableAccessibleWrap.h"
 #include "nsHTMLTextAccessible.h"
 #include "nsHyperTextAccessibleWrap.h"
 #include "nsIAccessibilityService.h"
 #include "nsIAccessibleProvider.h"
+
 #include "nsIDOMDocument.h"
 #include "nsIDOMHTMLAreaElement.h"
 #include "nsIDOMHTMLLegendElement.h"
 #include "nsIDOMHTMLObjectElement.h"
 #include "nsIDOMHTMLOptGroupElement.h"
 #include "nsIDOMHTMLOptionElement.h"
 #include "nsIDOMWindow.h"
 #include "nsIDOMXULElement.h"
+#include "nsIHTMLDocument.h"
 #include "nsIDocShell.h"
 #include "nsIFrame.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsIImageFrame.h"
 #include "nsILink.h"
 #include "nsINameSpaceManager.h"
 #include "nsIObserverService.h"
 #include "nsIPluginInstance.h"
@@ -631,34 +633,56 @@ nsAccessibilityService::CreateHTMLCombob
   if (! *_retval)
     return NS_ERROR_OUT_OF_MEMORY;
 
   NS_ADDREF(*_retval);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsAccessibilityService::CreateHTMLImageAccessible(nsIFrame *aFrame, nsIAccessible **_retval)
+nsAccessibilityService::CreateHTMLImageAccessible(nsIFrame *aFrame,
+                                                  nsIAccessible **aAccessible)
 {
+  NS_ENSURE_ARG_POINTER(aAccessible);
+  *aAccessible = nsnull;
+
   nsCOMPtr<nsIDOMNode> node;
   nsCOMPtr<nsIWeakReference> weakShell;
   nsresult rv = GetInfo(aFrame, getter_AddRefs(weakShell), getter_AddRefs(node));
   if (NS_FAILED(rv))
     return rv;
 
-  *_retval = nsnull;
-  nsCOMPtr<nsIDOMElement> domElement(do_QueryInterface(node));
-  if (domElement) {
-      *_retval = new nsHTMLImageAccessibleWrap(node, weakShell);
+  nsCOMPtr<nsIContent> content = do_QueryInterface(node);
+  NS_ENSURE_STATE(content);
+
+  nsCOMPtr<nsIHTMLDocument> htmlDoc =
+    do_QueryInterface(content->GetCurrentDoc());
+
+  nsCOMPtr<nsIDOMHTMLMapElement> mapElm;
+  if (htmlDoc) {
+    nsAutoString mapElmName;
+    content->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::usemap,
+                     mapElmName);
+
+    if (!mapElmName.IsEmpty()) {
+      if (mapElmName.CharAt(0) == '#')
+        mapElmName.Cut(0,1);
+      mapElm = htmlDoc->GetImageMap(mapElmName);
+    }
   }
 
-  if (! *_retval) 
+  if (mapElm)
+    *aAccessible = new nsHTMLImageMapAccessible(node, weakShell, mapElm);
+  else
+    *aAccessible = new nsHTMLImageAccessibleWrap(node, weakShell);
+
+  if (!*aAccessible)
     return NS_ERROR_OUT_OF_MEMORY;
 
-  NS_ADDREF(*_retval);
+  NS_ADDREF(*aAccessible);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsAccessibilityService::CreateHTMLGenericAccessible(nsIFrame *aFrame, nsIAccessible **aAccessible)
 {
   return CreateHyperTextAccessible(aFrame, aAccessible);
 }
--- a/accessible/src/base/nsCaretAccessible.cpp
+++ b/accessible/src/base/nsCaretAccessible.cpp
@@ -317,18 +317,17 @@ nsCaretAccessible::GetCaretRect(nsIWidge
   nsCOMPtr<nsIDOMNode> lastNodeWithCaret;
   lastAccessNode->GetDOMNode(getter_AddRefs(lastNodeWithCaret));
   NS_ENSURE_TRUE(lastNodeWithCaret, caretRect);
 
   nsCOMPtr<nsIPresShell> presShell =
     nsCoreUtils::GetPresShellFor(lastNodeWithCaret);
   NS_ENSURE_TRUE(presShell, caretRect);
 
-  nsRefPtr<nsCaret> caret;
-  presShell->GetCaret(getter_AddRefs(caret));
+  nsRefPtr<nsCaret> caret = presShell->GetCaret();
   NS_ENSURE_TRUE(caret, caretRect);
 
   nsCOMPtr<nsISelection> caretSelection(do_QueryReferent(mLastUsedSelection));
   NS_ENSURE_TRUE(caretSelection, caretRect);
   
   PRBool isVisible;
   caret->GetCaretVisible(&isVisible);
   if (!isVisible) {
--- a/accessible/src/base/nsDocAccessible.cpp
+++ b/accessible/src/base/nsDocAccessible.cpp
@@ -1174,16 +1174,19 @@ nsDocAccessible::AttributeChangedImpl(ns
 // nsDocAccessible protected member
 void
 nsDocAccessible::ARIAAttributeChanged(nsIContent* aContent, nsIAtom* aAttribute)
 {
   nsCOMPtr<nsIDOMNode> targetNode(do_QueryInterface(aContent));
   if (!targetNode)
     return;
 
+  // Note: For universal/global ARIA states and properties we don't care if
+  // there is an ARIA role present or not.
+
   if (aAttribute == nsAccessibilityAtoms::aria_required) {
     nsRefPtr<nsAccEvent> event =
       new nsAccStateChangeEvent(targetNode,
                                 nsIAccessibleStates::STATE_REQUIRED,
                                 PR_FALSE);
     FireDelayedAccessibleEvent(event);
     return;
   }
@@ -1204,16 +1207,34 @@ nsDocAccessible::ARIAAttributeChanged(ns
     if (SameCOMIdentity(nsCoreUtils::GetRoleContent(currentFocus), targetNode)) {
       nsRefPtr<nsRootAccessible> rootAcc = GetRootAccessible();
       if (rootAcc)
         rootAcc->FireAccessibleFocusEvent(nsnull, currentFocus, nsnull, PR_TRUE);
     }
     return;
   }
 
+  // For aria drag and drop changes we fire a generic attribute change event;
+  // at least until native API comes up with a more meaningful event.
+  if (aAttribute == nsAccessibilityAtoms::aria_grabbed ||
+      aAttribute == nsAccessibilityAtoms::aria_dropeffect) {
+    FireDelayedAccessibleEvent(nsIAccessibleEvent::EVENT_OBJECT_ATTRIBUTE_CHANGED,
+                               targetNode);
+  }
+
+  // We treat aria-expanded as a global ARIA state for historical reasons
+  if (aAttribute == nsAccessibilityAtoms::aria_expanded) {
+    nsRefPtr<nsAccEvent> event =
+      new nsAccStateChangeEvent(targetNode,
+                                nsIAccessibleStates::STATE_EXPANDED,
+                                PR_FALSE);
+    FireDelayedAccessibleEvent(event);
+    return;
+  }
+
   if (!aContent->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::role)) {
     // We don't care about these other ARIA attribute changes unless there is
     // an ARIA role set for the element
     // XXX: we should check the role map to see if the changed property is
     // relevant for that particular role.
     return;
   }
 
@@ -1244,25 +1265,16 @@ nsDocAccessible::ARIAAttributeChanged(ns
                                       PR_FALSE, isMixed);
           FireDelayedAccessibleEvent(event);
         }
       }
     }
     return;
   }
 
-  if (aAttribute == nsAccessibilityAtoms::aria_expanded) {
-    nsRefPtr<nsAccEvent> event =
-      new nsAccStateChangeEvent(targetNode,
-                                nsIAccessibleStates::STATE_EXPANDED,
-                                PR_FALSE);
-    FireDelayedAccessibleEvent(event);
-    return;
-  }
-
   if (aAttribute == nsAccessibilityAtoms::aria_readonly) {
     nsRefPtr<nsAccEvent> event =
       new nsAccStateChangeEvent(targetNode,
                                 nsIAccessibleStates::STATE_READONLY,
                                 PR_FALSE);
     FireDelayedAccessibleEvent(event);
     return;
   }
@@ -1285,24 +1297,16 @@ nsDocAccessible::ARIAAttributeChanged(ns
       aContent->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::role)) {
     // This affects whether the accessible supports nsIAccessibleSelectable.
     // COM says we cannot change what interfaces are supported on-the-fly,
     // so invalidate this object. A new one will be created on demand.
     InvalidateCacheSubtree(aContent,
                            nsIAccessibilityService::NODE_SIGNIFICANT_CHANGE);
     return;
   }
-
-  // For aria drag and drop changes we fire a generic attribute change event;
-  // at least until native API comes up with a more meaningful event.
-  if (aAttribute == nsAccessibilityAtoms::aria_grabbed ||
-      aAttribute == nsAccessibilityAtoms::aria_dropeffect) {
-    FireDelayedAccessibleEvent(nsIAccessibleEvent::EVENT_OBJECT_ATTRIBUTE_CHANGED,
-                               targetNode);
-  }
 }
 
 void nsDocAccessible::ContentAppended(nsIDocument *aDocument,
                                       nsIContent* aContainer,
                                       PRInt32 aNewIndexInContainer)
 {
   if ((!mIsContentLoaded || !mDocument) && mAccessNodeCache.Count() <= 1) {
     // See comments in nsDocAccessible::InvalidateCacheSubtree
--- a/accessible/src/html/Makefile.in
+++ b/accessible/src/html/Makefile.in
@@ -45,19 +45,19 @@ include $(DEPTH)/config/autoconf.mk
 
 MODULE = accessibility
 LIBRARY_NAME = accessibility_html_s
 LIBXUL_LIBRARY = 1
 
 
 
 CPPSRCS = \
-  nsHTMLAreaAccessible.cpp \
   nsHTMLFormControlAccessible.cpp \
   nsHTMLImageAccessible.cpp \
+  nsHTMLImageMapAccessible.cpp \
   nsHTMLLinkAccessible.cpp \
   nsHTMLSelectAccessible.cpp \
   nsHTMLTableAccessible.cpp \
   nsHTMLTextAccessible.cpp \
   nsHyperTextAccessible.cpp \
   $(NULL)
 
 EXPORTS = \
--- a/accessible/src/html/nsHTMLImageAccessible.cpp
+++ b/accessible/src/html/nsHTMLImageAccessible.cpp
@@ -36,68 +36,41 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "imgIContainer.h"
 #include "imgIRequest.h"
 
 #include "nsHTMLImageAccessible.h"
 #include "nsAccessibilityAtoms.h"
-#include "nsHTMLAreaAccessible.h"
 
-#include "nsIDOMHTMLCollection.h"
 #include "nsIDocument.h"
-#include "nsIHTMLDocument.h"
 #include "nsIImageLoadingContent.h"
 #include "nsILink.h"
 #include "nsIPresShell.h"
 #include "nsIServiceManager.h"
 #include "nsIDOMHTMLImageElement.h"
 #include "nsIDOMDocument.h"
 #include "nsPIDOMWindow.h"
 
-// --- image -----
-
-const PRUint32 kDefaultImageCacheSize = 256;
-
 ////////////////////////////////////////////////////////////////////////////////
 // nsHTMLImageAccessible
-
-nsHTMLImageAccessible::nsHTMLImageAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell):
-nsLinkableAccessible(aDOMNode, aShell), mAccessNodeCache(nsnull)
-{ 
-  nsCOMPtr<nsIDOMElement> element(do_QueryInterface(aDOMNode));
-  nsCOMPtr<nsIPresShell> shell(do_QueryReferent(mWeakShell));
-  if (!shell)
-    return;
-
-  nsIDocument *doc = shell->GetDocument();
-  nsAutoString mapElementName;
+////////////////////////////////////////////////////////////////////////////////
 
-  if (doc && element) {
-    nsCOMPtr<nsIHTMLDocument> htmlDoc(do_QueryInterface(doc));
-    element->GetAttribute(NS_LITERAL_STRING("usemap"),mapElementName);
-    if (htmlDoc && !mapElementName.IsEmpty()) {
-      if (mapElementName.CharAt(0) == '#')
-        mapElementName.Cut(0,1);
-      mMapElement = htmlDoc->GetImageMap(mapElementName);
-    }
-  }
-
-  if (mMapElement) {
-    mAccessNodeCache = new nsAccessNodeHashtable();
-    mAccessNodeCache->Init(kDefaultImageCacheSize);
-  }
+nsHTMLImageAccessible::
+  nsHTMLImageAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell) :
+  nsLinkableAccessible(aDOMNode, aShell)
+{
 }
 
 NS_IMPL_ISUPPORTS_INHERITED1(nsHTMLImageAccessible, nsAccessible,
                              nsIAccessibleImage)
 
 ////////////////////////////////////////////////////////////////////////////////
-// nsIAccessible
+// nsAccessible public
 
 nsresult
 nsHTMLImageAccessible::GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState)
 {
   // The state is a bitfield, get our inherited state, then logically OR it with
   // STATE_ANIMATED if this is an animated image.
 
   nsresult rv = nsLinkableAccessible::GetStateInternal(aState, aExtraState);
@@ -145,44 +118,22 @@ nsHTMLImageAccessible::GetNameInternal(n
   }
 
   return NS_OK;
 }
 
 nsresult
 nsHTMLImageAccessible::GetRoleInternal(PRUint32 *aRole)
 {
-  *aRole = mMapElement ? nsIAccessibleRole::ROLE_IMAGE_MAP :
-                         nsIAccessibleRole::ROLE_GRAPHIC;
+  *aRole = nsIAccessibleRole::ROLE_GRAPHIC;
   return NS_OK;
 }
 
-void 
-nsHTMLImageAccessible::CacheChildren()
-{
-  nsCOMPtr<nsIDOMHTMLCollection> mapAreas = GetAreaCollection();
-  if (!mapAreas)
-    return;
-
-  PRUint32 areaCount = 0;
-  mapAreas->GetLength(&areaCount);
-
-  nsCOMPtr<nsIAccessible> areaAccessible;
-  nsRefPtr<nsAccessible> areaAcc;
-
-  for (PRUint32 areaIdx = 0; areaIdx < areaCount; areaIdx++) {
-    areaAccessible = GetAreaAccessible(mapAreas, areaIdx);
-    if (!areaAccessible)
-      return;
-
-    areaAcc = nsAccUtils::QueryObject<nsAccessible>(areaAccessible);
-    mChildren.AppendElement(areaAcc);
-    areaAcc->SetParent(this);
-  }
-}
+////////////////////////////////////////////////////////////////////////////////
+// nsIAccessible
 
 NS_IMETHODIMP
 nsHTMLImageAccessible::GetNumActions(PRUint8 *aNumActions)
 {
   NS_ENSURE_ARG_POINTER(aNumActions);
   *aNumActions = 0;
 
   if (IsDefunct())
@@ -235,76 +186,16 @@ nsHTMLImageAccessible::DoAction(PRUint8 
     nsCOMPtr<nsIDOMWindow> tmp;
     return win->Open(longDesc, NS_LITERAL_STRING(""), NS_LITERAL_STRING(""),
                      getter_AddRefs(tmp));
   }
   return nsLinkableAccessible::DoAction(aIndex);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-// nsIAccessibleHyperLink
-NS_IMETHODIMP
-nsHTMLImageAccessible::GetAnchorCount(PRInt32 *aAnchorCount)
-{
-  NS_ENSURE_ARG_POINTER(aAnchorCount);
-
-  if (!mMapElement)
-    return nsLinkableAccessible::GetAnchorCount(aAnchorCount);
-
-  return GetChildCount(aAnchorCount);
-}
-
-NS_IMETHODIMP
-nsHTMLImageAccessible::GetURI(PRInt32 aIndex, nsIURI **aURI)
-{
-  NS_ENSURE_ARG_POINTER(aURI);
-  *aURI = nsnull;
-
-  if (!mMapElement)
-    return nsLinkableAccessible::GetURI(aIndex, aURI);
-
-  nsCOMPtr<nsIDOMHTMLCollection> mapAreas = GetAreaCollection();
-  if (!mapAreas)
-    return NS_OK;
-  
-  nsCOMPtr<nsIDOMNode> domNode;
-  mapAreas->Item(aIndex, getter_AddRefs(domNode));
-  if (!domNode)
-    return NS_ERROR_INVALID_ARG;
-
-  nsCOMPtr<nsIContent> link(do_QueryInterface(domNode));
-  if (link)
-    *aURI = link->GetHrefURI().get();
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsHTMLImageAccessible::GetAnchor(PRInt32 aIndex, nsIAccessible **aAccessible)
-{
-  NS_ENSURE_ARG_POINTER(aAccessible);
-  *aAccessible = nsnull;
-
-  if (!mMapElement)
-    return nsLinkableAccessible::GetAnchor(aIndex, aAccessible);
-
-  nsCOMPtr<nsIDOMHTMLCollection> mapAreas = GetAreaCollection();
-  if (mapAreas) {
-    nsCOMPtr<nsIAccessible> accessible;
-    accessible = GetAreaAccessible(mapAreas, aIndex);
-    if (!accessible)
-      return NS_ERROR_INVALID_ARG;
-
-    NS_ADDREF(*aAccessible = accessible);
-  }
-
-  return NS_OK;
-}
-
-////////////////////////////////////////////////////////////////////////////////
 // nsIAccessibleImage
 
 NS_IMETHODIMP
 nsHTMLImageAccessible::GetImagePosition(PRUint32 aCoordType,
                                         PRInt32 *aX, PRInt32 *aY)
 {
   PRInt32 width, height;
   nsresult rv = GetBounds(aX, aY, &width, &height);
@@ -316,36 +207,17 @@ nsHTMLImageAccessible::GetImagePosition(
 
 NS_IMETHODIMP
 nsHTMLImageAccessible::GetImageSize(PRInt32 *aWidth, PRInt32 *aHeight)
 {
   PRInt32 x, y;
   return GetBounds(&x, &y, aWidth, aHeight);
 }
 
-////////////////////////////////////////////////////////////////////////////////
-// nsHTMLImageAccessible. nsAccessNode
-
-nsresult
-nsHTMLImageAccessible::Shutdown()
-{
-  nsLinkableAccessible::Shutdown();
-
-  if (mAccessNodeCache) {
-    ClearCache(*mAccessNodeCache);
-    delete mAccessNodeCache;
-    mAccessNodeCache = nsnull;
-  }
-
-  return NS_OK;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// nsHTMLImageAccessible
-
+// nsAccessible
 nsresult
 nsHTMLImageAccessible::GetAttributesInternal(nsIPersistentProperties *aAttributes)
 {
   if (IsDefunct())
     return NS_ERROR_FAILURE;
   
   nsresult rv = nsLinkableAccessible::GetAttributesInternal(aAttributes);
   NS_ENSURE_SUCCESS(rv, rv);
@@ -355,61 +227,16 @@ nsHTMLImageAccessible::GetAttributesInte
   nsAutoString src;
   content->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::src, src);
   if (!src.IsEmpty())
     nsAccUtils::SetAccAttr(aAttributes, nsAccessibilityAtoms::src, src);
 
   return NS_OK;
 }
 
-already_AddRefed<nsIDOMHTMLCollection>
-nsHTMLImageAccessible::GetAreaCollection()
-{
-  if (!mMapElement)
-    return nsnull;
-
-  nsIDOMHTMLCollection *mapAreas = nsnull;
-  nsresult rv = mMapElement->GetAreas(&mapAreas);
-  if (NS_FAILED(rv))
-    return nsnull;
-
-  return mapAreas;
-}
-
-already_AddRefed<nsIAccessible>
-nsHTMLImageAccessible::GetAreaAccessible(nsIDOMHTMLCollection *aAreaCollection,
-                                         PRInt32 aAreaNum)
-{
-  if (!aAreaCollection)
-    return nsnull;
-
-  nsCOMPtr<nsIDOMNode> domNode;
-  aAreaCollection->Item(aAreaNum,getter_AddRefs(domNode));
-  if (!domNode)
-    return nsnull;
-
-  void* key = reinterpret_cast<void*>(aAreaNum);
-  nsRefPtr<nsAccessNode> accessNode = mAccessNodeCache->GetWeak(key);
-
-  if (!accessNode) {
-    accessNode = new nsHTMLAreaAccessible(domNode, this, mWeakShell);
-    if (!accessNode)
-      return nsnull;
-
-    nsresult rv = accessNode->Init();
-    if (NS_FAILED(rv))
-      return nsnull;
-
-    mAccessNodeCache->Put(key, accessNode);
-  }
-
-  nsCOMPtr<nsIAccessible> accessible = do_QueryInterface(accessNode);
-  return accessible.forget();
-}
-
 ////////////////////////////////////////////////////////////////////////////////
 // Private methods
 
 PRBool
 nsHTMLImageAccessible::HasLongDesc()
 {
   if (IsDefunct())
     return PR_FALSE;
--- a/accessible/src/html/nsHTMLImageAccessible.h
+++ b/accessible/src/html/nsHTMLImageAccessible.h
@@ -35,72 +35,46 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef _nsHTMLImageAccessible_H_
 #define _nsHTMLImageAccessible_H_
 
 #include "nsBaseWidgetAccessible.h"
-#include "nsIDOMHTMLMapElement.h"
 #include "nsIAccessibleImage.h"
 
 /* Accessible for supporting images
  * supports:
  * - gets name, role
  * - support basic state
  */
 class nsHTMLImageAccessible : public nsLinkableAccessible,
                               public nsIAccessibleImage
 {
-
-  NS_DECL_ISUPPORTS_INHERITED
-
 public:
   nsHTMLImageAccessible(nsIDOMNode* aDomNode, nsIWeakReference* aShell);
 
+  // nsISupports
+  NS_DECL_ISUPPORTS_INHERITED
+
   // nsIAccessible
   NS_IMETHOD GetNumActions(PRUint8 *aNumActions);
   NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
   NS_IMETHOD DoAction(PRUint8 index);
 
-  // nsIAccessibleHyperLink
-  NS_IMETHOD GetAnchorCount(PRInt32 *aAnchorCount);
-  NS_IMETHOD GetURI(PRInt32 aIndex, nsIURI **aURI);
-  NS_IMETHOD GetAnchor(PRInt32 aIndex, nsIAccessible **aAccessible);
-
   // nsIAccessibleImage
   NS_DECL_NSIACCESSIBLEIMAGE
 
-  // nsAccessNode
-  virtual nsresult Shutdown();
-
   // nsAccessible
   virtual nsresult GetNameInternal(nsAString& aName);
   virtual nsresult GetRoleInternal(PRUint32 *aRole);
   virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
   virtual nsresult GetAttributesInternal(nsIPersistentProperties *aAttributes);
 
-protected:
-  // nsAccessible
-  virtual void CacheChildren();
-
-  // nsHTMLImageAccessible
-  already_AddRefed<nsIDOMHTMLCollection> GetAreaCollection();
-  already_AddRefed<nsIAccessible>
-    GetAreaAccessible(nsIDOMHTMLCollection* aAreaNodes, PRInt32 aAreaNum);
-
-  // Reference on linked map element if any.
-  nsCOMPtr<nsIDOMHTMLMapElement> mMapElement;
-
-  // Cache of area accessibles. We do not use common cache because images can
-  // share area elements but we need to have separate area accessibles for
-  // each image accessible.
-  nsAccessNodeHashtable *mAccessNodeCache;
-
 private:
   /**
    * Determine if this image accessible has a longdesc attribute.
    *
    * @returns  true if the longdesc attribute is present.
    */
   PRBool HasLongDesc();
   
rename from accessible/src/html/nsHTMLAreaAccessible.cpp
rename to accessible/src/html/nsHTMLImageMapAccessible.cpp
--- a/accessible/src/html/nsHTMLAreaAccessible.cpp
+++ b/accessible/src/html/nsHTMLImageMapAccessible.cpp
@@ -15,54 +15,235 @@
  * The Original Code is mozilla.org code.
  *
  * The Initial Developer of the Original Code is
  * Netscape Communications Corporation.
  * Portions created by the Initial Developer are Copyright (C) 1998
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s):
- *   Author: Aaron Leventhal (aaronl@netscape.com)
+ *   Aaron Leventhal <aaronl@netscape.com> (original author)
+ *   Alexander Surkov <surkov.alexander@gmail.com>
  *
  * Alternatively, the contents of this file may be used under the terms of
  * either of the GNU General Public License Version 2 or later (the "GPL"),
  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  * in which case the provisions of the GPL or the LGPL are applicable instead
  * of those above. If you wish to allow use of your version of this file only
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
-#include "nsHTMLAreaAccessible.h"
+#include "nsHTMLImageMapAccessible.h"
+
+#include "nsIDOMHTMLCollection.h"
 #include "nsIServiceManager.h"
 #include "nsIDOMElement.h"
 #include "nsIDOMHTMLAreaElement.h"
 #include "nsIFrame.h"
 #include "nsIImageFrame.h"
 #include "nsIImageMap.h"
 
+////////////////////////////////////////////////////////////////////////////////
+// nsHTMLImageMapAccessible
+////////////////////////////////////////////////////////////////////////////////
+
+const PRUint32 kDefaultImageMapCacheSize = 256;
+
+nsHTMLImageMapAccessible::
+  nsHTMLImageMapAccessible(nsIDOMNode *aDOMNode, nsIWeakReference *aShell,
+                           nsIDOMHTMLMapElement *aMapElm) :
+  nsHTMLImageAccessibleWrap(aDOMNode, aShell), mMapElement(aMapElm)
+{
+  mAreaAccCache.Init(kDefaultImageMapCacheSize);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// nsHTMLImageMapAccessible: nsISupports and cycle collector
+
+NS_IMPL_CYCLE_COLLECTION_CLASS(nsHTMLImageMapAccessible)
+
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsHTMLImageMapAccessible,
+                                                  nsAccessible)
+CycleCollectorTraverseCache(tmp->mAreaAccCache, &cb);
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
+
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsHTMLImageMapAccessible,
+                                                nsAccessible)
+ClearCache(tmp->mAreaAccCache);
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsHTMLImageMapAccessible)
+NS_INTERFACE_MAP_END_INHERITING(nsHTMLImageAccessible)
+
+NS_IMPL_ADDREF_INHERITED(nsHTMLImageMapAccessible, nsHTMLImageAccessible)
+NS_IMPL_RELEASE_INHERITED(nsHTMLImageMapAccessible, nsHTMLImageAccessible)
+
+////////////////////////////////////////////////////////////////////////////////
+// nsHTMLImageMapAccessible: nsIAccessibleHyperLink
+
+NS_IMETHODIMP
+nsHTMLImageMapAccessible::GetAnchorCount(PRInt32 *aAnchorCount)
+{
+  NS_ENSURE_ARG_POINTER(aAnchorCount);
+
+  return GetChildCount(aAnchorCount);
+}
+
+NS_IMETHODIMP
+nsHTMLImageMapAccessible::GetURI(PRInt32 aIndex, nsIURI **aURI)
+{
+  NS_ENSURE_ARG_POINTER(aURI);
+  *aURI = nsnull;
+
+  nsCOMPtr<nsIDOMHTMLCollection> mapAreas = GetAreaCollection();
+  if (!mapAreas)
+    return NS_OK;
+
+  nsCOMPtr<nsIDOMNode> domNode;
+  mapAreas->Item(aIndex, getter_AddRefs(domNode));
+  if (!domNode)
+    return NS_ERROR_INVALID_ARG;
+
+  nsCOMPtr<nsIContent> link(do_QueryInterface(domNode));
+  if (link)
+    *aURI = link->GetHrefURI().get();
+
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsHTMLImageMapAccessible::GetAnchor(PRInt32 aIndex, nsIAccessible **aAccessible)
+{
+  NS_ENSURE_ARG_POINTER(aAccessible);
+  *aAccessible = nsnull;
+
+  nsCOMPtr<nsIDOMHTMLCollection> mapAreas = GetAreaCollection();
+  if (mapAreas) {
+    nsRefPtr<nsIAccessible> accessible = GetAreaAccessible(mapAreas, aIndex);
+    if (!accessible)
+      return NS_ERROR_INVALID_ARG;
+
+    NS_ADDREF(*aAccessible = accessible);
+  }
+
+  return NS_OK;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// nsHTMLImageAccessible: nsAccessNode
+
+nsresult
+nsHTMLImageMapAccessible::Shutdown()
+{
+  nsLinkableAccessible::Shutdown();
+
+  ClearCache(mAreaAccCache);
+  return NS_OK;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// nsHTMLImageMapAccessible: nsAccessible public
+
+nsresult
+nsHTMLImageMapAccessible::GetRoleInternal(PRUint32 *aRole)
+{
+  *aRole = nsIAccessibleRole::ROLE_IMAGE_MAP;
+  return NS_OK;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// nsHTMLImageMapAccessible: nsAccessible protected
+
+void 
+nsHTMLImageMapAccessible::CacheChildren()
+{
+  nsCOMPtr<nsIDOMHTMLCollection> mapAreas = GetAreaCollection();
+  if (!mapAreas)
+    return;
+
+  PRUint32 areaCount = 0;
+  mapAreas->GetLength(&areaCount);
+
+  nsRefPtr<nsAccessible> areaAcc;
+  for (PRUint32 areaIdx = 0; areaIdx < areaCount; areaIdx++) {
+    areaAcc = GetAreaAccessible(mapAreas, areaIdx);
+    if (!areaAcc)
+      return;
+
+    mChildren.AppendElement(areaAcc);
+    areaAcc->SetParent(this);
+  }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// nsHTMLImageAccessible
+
+already_AddRefed<nsIDOMHTMLCollection>
+nsHTMLImageMapAccessible::GetAreaCollection()
+{
+  if (!mMapElement)
+    return nsnull;
+
+  nsIDOMHTMLCollection *mapAreas = nsnull;
+  mMapElement->GetAreas(&mapAreas);
+  return mapAreas;
+}
+
+already_AddRefed<nsAccessible>
+nsHTMLImageMapAccessible::GetAreaAccessible(nsIDOMHTMLCollection *aAreaCollection,
+                                            PRInt32 aAreaNum)
+{
+  if (!aAreaCollection)
+    return nsnull;
+
+  nsCOMPtr<nsIDOMNode> domNode;
+  aAreaCollection->Item(aAreaNum,getter_AddRefs(domNode));
+  if (!domNode)
+    return nsnull;
+
+  void *key = reinterpret_cast<void*>(aAreaNum);
+  nsRefPtr<nsAccessible> accessible = mAreaAccCache.GetWeak(key);
+
+  if (!accessible) {
+    accessible = new nsHTMLAreaAccessible(domNode, this, mWeakShell);
+    if (!accessible)
+      return nsnull;
+
+    nsresult rv = accessible->Init();
+    if (NS_FAILED(rv)) {
+      accessible->Shutdown();
+      return nsnull;
+    }
+
+    mAreaAccCache.Put(key, accessible);
+  }
+
+  return accessible.forget();
+}
+
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsHTMLAreaAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
 nsHTMLAreaAccessible::
   nsHTMLAreaAccessible(nsIDOMNode *aDomNode, nsIAccessible *aParent,
                        nsIWeakReference* aShell):
   nsHTMLLinkAccessible(aDomNode, aShell)
 {
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-// nsIAccessible
+// nsHTMLAreaAccessible: nsIAccessible
 
 nsresult
 nsHTMLAreaAccessible::GetNameInternal(nsAString & aName)
 {
   nsresult rv = nsAccessible::GetNameInternal(aName);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (!aName.IsEmpty())
@@ -131,28 +312,28 @@ nsHTMLAreaAccessible::GetBounds(PRInt32 
   orgRectPixels = frame->GetScreenRectExternal();
   *x += orgRectPixels.x;
   *y += orgRectPixels.y;
 
   return NS_OK;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-// nsAccessible public implementation
+// nsHTMLAreaAccessible: nsAccessible public
 
 nsresult
 nsHTMLAreaAccessible::GetChildAtPoint(PRInt32 aX, PRInt32 aY,
                                       PRBool aDeepestChild,
                                       nsIAccessible **aChild)
 {
   // Don't walk into area accessibles.
   NS_ADDREF(*aChild = this);
   return NS_OK;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-// nsAccessible protected implementation
+// nsHTMLAreaAccessible: nsAccessible protected
 
 void
 nsHTMLAreaAccessible::CacheChildren()
 {
   // No children for aria accessible.
 }
rename from accessible/src/html/nsHTMLAreaAccessible.h
rename to accessible/src/html/nsHTMLImageMapAccessible.h
--- a/accessible/src/html/nsHTMLAreaAccessible.h
+++ b/accessible/src/html/nsHTMLImageMapAccessible.h
@@ -15,17 +15,18 @@
  * The Original Code is mozilla.org code.
  *
  * The Initial Developer of the Original Code is
  * Netscape Communications Corporation.
  * Portions created by the Initial Developer are Copyright (C) 1998
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s):
- *   Author: Aaron Leventhal (aaronl@netscape.com)
+ *   Aaron Leventhal <aaronl@netscape.com> (original author)
+ *   Alexander Surkov <surkov.alexander@gmail.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
@@ -35,16 +36,72 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef _nsHTMLAreaAccessible_H_
 #define _nsHTMLAreaAccessible_H_
 
 #include "nsHTMLLinkAccessible.h"
+#include "nsHTMLImageAccessibleWrap.h"
+
+#include "nsIDOMHTMLMapElement.h"
+
+/**
+ * Used for HTML image maps.
+ */
+class nsHTMLImageMapAccessible : public nsHTMLImageAccessibleWrap
+{
+public:
+  nsHTMLImageMapAccessible(nsIDOMNode *aNode, nsIWeakReference *aShell,
+                           nsIDOMHTMLMapElement *aMapElm);
+
+  // nsISupports and cycle collector
+  NS_DECL_ISUPPORTS_INHERITED
+
+  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsHTMLImageMapAccessible,
+                                           nsAccessible)
+
+  // nsIAccessibleHyperLink
+  NS_IMETHOD GetAnchorCount(PRInt32 *aAnchorCount);
+  NS_IMETHOD GetURI(PRInt32 aIndex, nsIURI **aURI);
+  NS_IMETHOD GetAnchor(PRInt32 aIndex, nsIAccessible **aAccessible);
+
+  // nsAccessible
+  virtual nsresult GetRoleInternal(PRUint32 *aRole);
+
+protected:
+  // nsAccessNode
+  virtual nsresult Shutdown();
+
+  // nsAccessible
+  virtual void CacheChildren();
+
+  // nsHTMLImageAccessible
+  /**
+   * Return collection of HTML area elements associated with the image map.
+   */
+  already_AddRefed<nsIDOMHTMLCollection> GetAreaCollection();
+
+  /**
+   * Return an accessible for HTML area element at the given index.
+   */
+  already_AddRefed<nsAccessible>
+    GetAreaAccessible(nsIDOMHTMLCollection* aAreaNodes, PRInt32 aAreaNum);
+
+private:
+  // Reference on linked map element if any.
+  nsCOMPtr<nsIDOMHTMLMapElement> mMapElement;
+
+  // Cache of area accessibles. We do not use common cache because images can
+  // share area elements but we need to have separate area accessibles for
+  // each image accessible.
+  nsAccessibleHashtable mAreaAccCache;
+};
+
 
 /**
  * Accessible for image map areas - must be child of image.
  */
 class nsHTMLAreaAccessible : public nsHTMLLinkAccessible
 {
 
 public:
--- a/accessible/tests/mochitest/events/Makefile.in
+++ b/accessible/tests/mochitest/events/Makefile.in
@@ -43,16 +43,17 @@ VPATH		= @srcdir@
 relativesrcdir  = accessible/events
 
 include $(DEPTH)/config/autoconf.mk
 include $(topsrcdir)/config/rules.mk
 
 _TEST_FILES =\
 		focus.html \
 		scroll.html \
+		test_aria_statechange.html \
 		test_attrs.html \
 		test_caretmove.html \
 	$(warning	test_coalescence.html temporarily disabled) \
 		test_doc.html \
 		test_dragndrop.html \
 		test_flush.html \
 		test_focus.html \
 		test_focus.xul \
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/events/test_aria_statechange.html
@@ -0,0 +1,85 @@
+<html>
+
+<head>
+  <title>ARIA state change event testing</title>
+
+  <link rel="stylesheet" type="text/css"
+        href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+
+  <script type="application/javascript"
+          src="chrome://mochikit/content/MochiKit/packed.js"></script>
+  <script type="application/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+
+  <script type="application/javascript"
+          src="chrome://mochikit/content/a11y/accessible/common.js"></script>
+  <script type="application/javascript"
+          src="chrome://mochikit/content/a11y/accessible/states.js"></script>
+  <script type="application/javascript"
+          src="chrome://mochikit/content/a11y/accessible/events.js"></script>
+
+  <script type="application/javascript">
+
+
+    /**
+     * Do tests.
+     */
+    var gQueue = null;
+
+    function expandNode(aNodeOrID, bExpand)
+    {
+      this.DOMNode = getNode(aNodeOrID);
+
+      this.invoke = function expand_invoke() {
+        // Note: this should fire an EVENT_STATE_CHANGE
+        this.DOMNode.setAttribute("aria-expanded", bExpand);
+      };
+
+      this.check = function expand_check() {
+        testStates(aNodeOrID,
+                   bExpand ? STATE_EXPANDED : STATE_COLLAPSED,
+                   EXT_STATE_EXPANDABLE);
+      };
+
+      this.getID = function changeValue_getID() {
+        return prettyName(aNodeOrID) + " aria-expanded changed";
+      };
+    }
+
+    function doTests()
+    {
+      gQueue = new eventQueue(nsIAccessibleEvent.EVENT_STATE_CHANGE);
+
+      gQueue.push(new expandNode("section", true));
+      gQueue.push(new expandNode("section", false));
+      gQueue.push(new expandNode("div", true));
+      gQueue.push(new expandNode("div", false));
+
+      gQueue.invoke(); // Will call SimpleTest.finish();
+    }
+
+    SimpleTest.waitForExplicitFinish();
+    addA11yLoadEvent(doTests);
+  </script>
+</head>
+
+<body>
+
+  <a target="_blank"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=551684"
+     title="No statechange event for aria-expanded on native HTML elements, is fired on ARIA widgets">
+    Mozilla Bug 551684
+  </a>
+
+  <p id="display"></p>
+  <div id="content" style="display: none"></div>
+  <pre id="test">
+  </pre>
+  <div id="eventdump"></div>
+
+  <!-- aria-expanded -->
+  <div id="section" role="section" aria-expanded="false">expandable section</div>
+  <div id="div" aria-expanded="false">expandable native div</div>
+
+</body>
+</html>
--- a/accessible/tests/mochitest/tree/test_tabbrowser.xul
+++ b/accessible/tests/mochitest/tree/test_tabbrowser.xul
@@ -59,19 +59,16 @@
     }
 
     function testAccTree()
     {
       var tabsAccTree = {
         role: ROLE_PAGETABLIST,
         children: [
           {
-            role: ROLE_MENUPOPUP
-          },
-          {
             role: ROLE_PAGETAB,
             children: [
               {
                 role: ROLE_PUSHBUTTON
               }
             ]
           },
           {
--- a/allmakefiles.sh
+++ b/allmakefiles.sh
@@ -80,17 +80,17 @@ if [ "$WINCE" ]; then
     build/wince/shunt/Makefile
     build/wince/shunt/include/windows.h
     build/wince/shunt/include/ymath.h
     build/wince/shunt/include/stdlib.h
     build/wince/shunt/include/sys/Makefile
   "
 fi
 
-if [ "$MOZ_MEMORY" -a "$LIBXUL_SDK" -eq ""]; then
+if [ "$MOZ_MEMORY" -a "$LIBXUL_SDK" = "" ]; then
   add_makefiles "
     memory/jemalloc/Makefile
   "
 fi
 
 #
 # Application-specific makefiles
 #
--- a/browser/app/Makefile.in
+++ b/browser/app/Makefile.in
@@ -351,23 +351,16 @@ endif
 
 else
 ifdef LIBXUL_SDK
 libs::
 	cp $(LIBXUL_DIST)/bin/$(XULRUNNER_STUB_NAME)$(BIN_SUFFIX) $(DIST)/bin/firefox$(BIN_SUFFIX)
 endif
 endif
 
-libs::
-ifeq ($(OS_ARCH),WINNT)
-	$(PERL) -pe 's/(?<!\r)\n/\r\n/g;' < $(topsrcdir)/LICENSE > $(DIST)/bin/LICENSE
-else
-	$(INSTALL) $(IFLAGS1) $(topsrcdir)/LICENSE $(DIST)/bin
-endif
-
 ifdef LIBXUL_SDK
 ifndef SKIP_COPY_XULRUNNER
 libs::
 ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
 	rsync -a --copy-unsafe-links $(LIBXUL_DIST)/XUL.framework $(DIST)/$(APP_NAME).app/Contents/Frameworks
 else
 	$(NSINSTALL) -D $(DIST)/bin/xulrunner
 	(cd $(LIBXUL_SDK)/bin && tar $(TAR_CREATE_FLAGS) - .) | (cd $(DIST)/bin/xulrunner && tar -xf -)
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -235,24 +235,26 @@ pref("browser.urlbar.maxRichResults", 12
 pref("browser.urlbar.delay", 50);
 
 // The special characters below can be typed into the urlbar to either restrict
 // the search to visited history, bookmarked, tagged pages; or force a match on
 // just the title text or url.
 pref("browser.urlbar.restrict.history", "^");
 pref("browser.urlbar.restrict.bookmark", "*");
 pref("browser.urlbar.restrict.tag", "+");
+pref("browser.urlbar.restrict.openpage", "%");
 pref("browser.urlbar.restrict.typed", "~");
 pref("browser.urlbar.match.title", "#");
 pref("browser.urlbar.match.url", "@");
 
 // The default behavior for the urlbar can be configured to use any combination
 // of the restrict or match filters with each additional filter restricting
 // more (intersection). Add the following values to set the behavior as the
-// default: 1: history, 2: bookmark, 4: tag, 8: title, 16: url, 32: typed
+// default: 1: history, 2: bookmark, 4: tag, 8: title, 16: url, 32: typed,
+//          64: javascript, 128: tabs
 // E.g., 0 = show all results (no filtering), 1 = only visited pages in history,
 // 2 = only bookmarks, 3 = visited bookmarks, 1+16 = history matching in the url
 pref("browser.urlbar.default.behavior", 0);
 
 // Number of milliseconds to wait for the http headers (and thus
 // the Content-Disposition filename) before giving up and falling back to 
 // picking a filename without that info in hand so that the user sees some
 // feedback from their action.
@@ -837,19 +839,16 @@ pref("browser.offline-apps.notify", true
 pref("browser.zoom.full", true);
 
 // Whether or not to save and restore zoom levels on a per-site basis.
 pref("browser.zoom.siteSpecific", true);
 
 // Whether or not to update background tabs to the current zoom level.
 pref("browser.zoom.updateBackgroundTabs", true);
 
-// replace newlines with spaces when pasting into <input type="text"> fields
-pref("editor.singleLine.pasteNewlines", 2);
-
 // The breakpad report server to link to in about:crashes
 pref("breakpad.reportURL", "http://crash-stats.mozilla.com/report/index/");
 
 // base URL for web-based support pages
 pref("app.support.baseURL", "http://support.mozilla.com/1/%APP%/%VERSION%/%OS%/%LOCALE%/");
 
 // Name of alternate about: page for certificate errors (when undefined, defaults to about:neterror)
 pref("security.alternate_certificate_error_page", "certerror");
@@ -903,16 +902,19 @@ pref("browser.sessionstore.interval", 60
 #ifdef XP_MACOSX
 pref("toolbar.customization.usesheet", true);
 #else
 pref("toolbar.customization.usesheet", false);
 #endif
 
 #ifdef XP_MACOSX
 pref("dom.ipc.plugins.enabled", false);
+// These plug-ins will run OOP by default
+pref("dom.ipc.plugins.enabled.flash player.plugin", true);
+pref("dom.ipc.plugins.enabled.javaplugin2_npapi.plugin", true);
 #else
 pref("dom.ipc.plugins.enabled", true);
 #endif
 
 #ifdef XP_WIN
 #ifndef WINCE
 pref("browser.taskbar.previews.enable", true);
 pref("browser.taskbar.previews.max", 20);
--- a/browser/base/content/browser-fullZoom.js
+++ b/browser/base/content/browser-fullZoom.js
@@ -272,17 +272,17 @@ var FullZoom = {
    *        (optional) browser object displaying the document
    */
   onLocationChange: function FullZoom_onLocationChange(aURI, aIsTabSwitch, aBrowser) {
     if (!aURI || (aIsTabSwitch && !this.siteSpecific))
       return;
 
     // Avoid the cps roundtrip and apply the default/global pref.
     if (aURI.spec == "about:blank") {
-      this._applyPrefToSetting();
+      this._applyPrefToSetting(undefined, aBrowser);
       return;
     }
 
     var self = this;
     this._cps.getPref(aURI, this.name, function(aResult) {
       // Check that we're still where we expect to be in case this took a while.
       let isSaneURI = (aBrowser && aBrowser.currentURI) ?
         aURI.equals(aBrowser.currentURI) : false;
--- a/browser/base/content/browser-menubar.inc
+++ b/browser/base/content/browser-menubar.inc
@@ -208,16 +208,21 @@
                   accesskey="&viewMenu.accesskey;">
               <menupopup id="menu_viewPopup">
                 <menu id="viewToolbarsMenu"
                       label="&viewToolbarsMenu.label;"
                       accesskey="&viewToolbarsMenu.accesskey;"
                       onpopupshowing="onViewToolbarsPopupShowing(event);">
                   <menupopup>
                     <menuseparator/>
+                    <menuitem command="cmd_ToggleTabsOnTop"
+                              type="checkbox"
+                              label="&viewTabsOnTop.label;"
+                              accesskey="&viewTabsOnTop.accesskey;"/>
+                    <menuseparator/>
                     <menuitem id="menu_customizeToolbars"
                               label="&viewCustomizeToolbar.label;"
                               accesskey="&viewCustomizeToolbar.accesskey;"
                               command="cmd_CustomizeToolbars"/>
                   </menupopup>
                 </menu>
                 <menuitem id="toggle_taskbar"
                           label="&taskbarCmd.label;"
--- a/browser/base/content/browser-sets.inc
+++ b/browser/base/content/browser-sets.inc
@@ -64,16 +64,17 @@
              oncommand="MailIntegration.sendLinkForWindow(window.content);"/>
 
     <command id="cmd_pageSetup" oncommand="PrintUtils.showPageSetup();"/>
     <command id="cmd_print" oncommand="PrintUtils.print();"/>
     <command id="cmd_printPreview" oncommand="PrintUtils.printPreview(PrintPreviewListener);"/>
     <command id="cmd_close" oncommand="BrowserCloseTabOrWindow()"/>
     <command id="cmd_closeWindow" oncommand="BrowserTryToCloseWindow()"/>
     <command id="cmd_toggleTaskbar" oncommand="goToggleToolbar('status-bar','toggle_taskbar');"/>
+    <command id="cmd_ToggleTabsOnTop" oncommand="TabsOnTop.toggle()"/>
     <command id="cmd_CustomizeToolbars" oncommand="BrowserCustomizeToolbar()"/>
     <command id="cmd_quitApplication" oncommand="goQuitApplication()"/>
 
 
     <commandset id="editMenuCommands"/>
 
     <command id="View:PageSource" oncommand="BrowserViewSourceOfDocument(content.document);" observes="isImage"/>
     <command id="View:PageInfo" oncommand="BrowserPageInfo();"/>
--- a/browser/base/content/browser-tabPreviews.js
+++ b/browser/base/content/browser-tabPreviews.js
@@ -39,36 +39,46 @@
  */
 
 /**
  * Tab previews utility, produces thumbnails
  */
 var tabPreviews = {
   aspectRatio: 0.5625, // 16:9
   init: function tabPreviews_init() {
+    if (this._selectedTab)
+      return;
+    this._selectedTab = gBrowser.selectedTab;
+
     this.width = Math.ceil(screen.availWidth / 5.75);
     this.height = Math.round(this.width * this.aspectRatio);
 
+    window.addEventListener("unload", this, false);
     gBrowser.tabContainer.addEventListener("TabSelect", this, false);
     gBrowser.tabContainer.addEventListener("SSTabRestored", this, false);
   },
   uninit: function tabPreviews_uninit() {
+    window.removeEventListener("unload", this, false);
     gBrowser.tabContainer.removeEventListener("TabSelect", this, false);
     gBrowser.tabContainer.removeEventListener("SSTabRestored", this, false);
     this._selectedTab = null;
   },
   get: function tabPreviews_get(aTab) {
+    this.init();
+
     if (aTab.__thumbnail_lastURI &&
         aTab.__thumbnail_lastURI != aTab.linkedBrowser.currentURI.spec) {
       aTab.__thumbnail = null;
       aTab.__thumbnail_lastURI = null;
     }
     return aTab.__thumbnail || this.capture(aTab, !aTab.hasAttribute("busy"));
   },
   capture: function tabPreviews_capture(aTab, aStore) {
+    this.init();
+
     var thumbnail = document.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
     thumbnail.mozOpaque = true;
     thumbnail.height = this.height;
     thumbnail.width = this.width;
 
     var ctx = thumbnail.getContext("2d");
     var win = aTab.linkedBrowser.contentWindow;
     var snippetWidth = win.innerWidth * .6;
@@ -100,16 +110,19 @@ var tabPreviews = {
               self.capture(aTab, true);
           }, 2000, this, this._selectedTab);
         }
         this._selectedTab = event.target;
         break;
       case "SSTabRestored":
         this.capture(event.target, true);
         break;
+      case "unload":
+        this.uninit();
+        break;
     }
   }
 };
 
 var tabPreviewPanelHelper = {
   opening: function (host) {
     host.panel.hidden = false;
 
@@ -220,16 +233,18 @@ var ctrlTab = {
       }
     }
 
     return this._tabList = list;
   },
 
   init: function ctrlTab_init() {
     if (!this._recentlyUsedTabs) {
+      tabPreviews.init();
+
       this._recentlyUsedTabs = [gBrowser.selectedTab];
       this._init(true);
     }
   },
 
   uninit: function ctrlTab_uninit() {
     this._recentlyUsedTabs = null;
     this._init(false);
@@ -572,16 +587,18 @@ var allTabs = {
   get previews () this.container.getElementsByClassName("allTabs-preview"),
   get isOpen () this.panel.state == "open" || this.panel.state == "showing",
 
   init: function allTabs_init() {
     if (this._initiated)
       return;
     this._initiated = true;
 
+    tabPreviews.init();
+
     Array.forEach(gBrowser.tabs, function (tab) {
       this._addPreview(tab);
     }, this);
 
     gBrowser.tabContainer.addEventListener("TabOpen", this, false);
     gBrowser.tabContainer.addEventListener("TabAttrModified", this, false);
     gBrowser.tabContainer.addEventListener("TabMove", this, false);
     gBrowser.tabContainer.addEventListener("TabClose", this, false);
--- a/browser/base/content/browser.css
+++ b/browser/base/content/browser.css
@@ -16,16 +16,28 @@ tabbrowser {
 .tabbrowser-tab {
   -moz-binding: url("chrome://browser/content/tabbrowser.xml#tabbrowser-tab");
 }
 
 toolbar[printpreview="true"] {
   -moz-binding: url("chrome://global/content/printPreviewBindings.xml#printpreviewtoolbar");
 }
 
+#navigator-toolbox > toolbar:not(#TabsToolbar) {
+  -moz-box-ordinal-group: 50;
+}
+
+#TabsToolbar {
+  -moz-box-ordinal-group: 100;
+}
+
+#navigator-toolbox[tabsontop="true"] > #TabsToolbar {
+  -moz-box-ordinal-group: 10;
+}
+
 toolbarpaletteitem[place="palette"] > toolbaritem > hbox[type="places"] {
   display: none;
 }
 
 toolbar[mode="icons"] > #reload-button:not([displaystop]) + #stop-button,
 toolbar[mode="icons"] > #reload-button[displaystop] {
   visibility: collapse;
 }
@@ -46,16 +58,36 @@ toolbar[mode="icons"] > #reload-button[d
   background-position: bottom left;
 }
 
 /* ::::: location bar ::::: */
 #urlbar {
   -moz-binding: url(chrome://browser/content/urlbarBindings.xml#urlbar);
 }
 
+/* Some child nodes want to be ordered based on the locale's direction, while
+   everything else should be ltr. */
+#urlbar:-moz-locale-dir(rtl) > .autocomplete-textbox-container > .textbox-input-box {
+  direction: rtl;
+}
+
+#urlbar html|*.autocomplete-textbox {
+  direction: ltr;
+}
+
+/* For results that are actions, their description text is shown instead of
+   the URL - this needs to follow the locale's direction, unlike URLs. */
+richlistitem[type="action"]:-moz-locale-dir(rtl) > .ac-url-box {
+  direction: rtl;
+}
+
+#urlbar:not([actiontype]) > #urlbar-display {
+  display: none;
+}
+
 #wrapper-urlbar-container > #urlbar-container > #urlbar {
   -moz-user-input: disabled;
   cursor: -moz-grab;
 }
 
 #PopupAutoComplete {
   -moz-binding: url("chrome://browser/content/urlbarBindings.xml#browser-autocomplete-result-popup");
 }
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -1302,17 +1302,16 @@ function delayedStartup(isLoadingBlank, 
   gBookmarkAllTabsHandler.init();
 
   // Attach a listener to watch for "command" events bubbling up from error
   // pages.  This lets us fix bugs like 401575 which require error page UI to
   // do privileged things, without letting error pages have any privilege
   // themselves.
   gBrowser.addEventListener("command", BrowserOnCommand, false);
 
-  tabPreviews.init();
   ctrlTab.readPref();
   gPrefService.addObserver(ctrlTab.prefName, ctrlTab, false);
   gPrefService.addObserver(allTabs.prefName, allTabs, false);
 
   // Initialize the microsummary service by retrieving it, prompting its factory
   // to create its singleton, whose constructor initializes the service.
   // Started 4 seconds after delayedStartup (before the livemarks service below).
   setTimeout(function() {
@@ -1359,26 +1358,27 @@ function delayedStartup(isLoadingBlank, 
   gPrivateBrowsingUI.init();
 
   gBrowser.mPanelContainer.addEventListener("InstallBrowserTheme", LightWeightThemeWebInstaller, false, true);
   gBrowser.mPanelContainer.addEventListener("PreviewBrowserTheme", LightWeightThemeWebInstaller, false, true);
   gBrowser.mPanelContainer.addEventListener("ResetBrowserThemePreview", LightWeightThemeWebInstaller, false, true);
 
   if (Win7Features)
     Win7Features.onOpenWindow();
+
+  TabsOnTop.syncCommand();
 }
 
 function BrowserShutdown()
 {
   if (Win7Features)
     Win7Features.onCloseWindow();
 
   gPrefService.removeObserver(ctrlTab.prefName, ctrlTab);
   gPrefService.removeObserver(allTabs.prefName, allTabs);
-  tabPreviews.uninit();
   ctrlTab.uninit();
   allTabs.uninit();
 
   CombinedStopReload.uninit();
 
   gGestureSupport.init(false);
 
   FullScreen.cleanup();
@@ -3800,17 +3800,16 @@ var XULBrowserWindow = {
   // Stored Status, Link and Loading values
   status: "",
   defaultStatus: "",
   jsStatus: "",
   jsDefaultStatus: "",
   overLink: "",
   startTime: 0,
   statusText: "",
-  lastURI: null,
   isBusy: false,
 
   _progressCollapseTimer: 0,
 
   QueryInterface: function (aIID) {
     if (aIID.equals(Ci.nsIWebProgressListener) ||
         aIID.equals(Ci.nsIWebProgressListener2) ||
         aIID.equals(Ci.nsISupportsWeakReference) ||
@@ -3864,17 +3863,16 @@ var XULBrowserWindow = {
     // XXXjag to avoid leaks :-/, see bug 60729
     delete this.throbberElement;
     delete this.statusMeter;
     delete this.stopCommand;
     delete this.reloadCommand;
     delete this.statusTextField;
     delete this.securityButton;
     delete this.statusText;
-    delete this.lastURI;
   },
 
   setJSStatus: function (status) {
     this.jsStatus = status;
     this.updateStatusField();
   },
 
   setJSDefaultStatus: function (status) {
@@ -4079,17 +4077,16 @@ var XULBrowserWindow = {
         newSpec = newSpec.substr(0, newSpec.indexOf("#"));
       if (newSpec != oldSpec) {
         // Remove all the notifications, except for those which want to
         // persist across the first location change.
         let nBox = gBrowser.getNotificationBox(selectedBrowser);
         nBox.removeTransientNotifications();
       }
     }
-    selectedBrowser.lastURI = aLocationURI;
 
     // Disable menu entries for images, enable otherwise
     if (content.document && mimeTypeIsTextBased(content.document.contentType))
       this.isImage.removeAttribute('disabled');
     else
       this.isImage.setAttribute('disabled', 'true');
 
     this.setOverLink("", null);
@@ -4587,16 +4584,39 @@ function onViewToolbarCommand(aEvent)
   var hidingAttribute = toolbar.getAttribute("type") == "menubar" ?
                         "autohide" : "collapsed";
 
   toolbar.setAttribute(hidingAttribute,
                        aEvent.originalTarget.getAttribute("checked") != "true");
   document.persist(toolbar.id, hidingAttribute);
 }
 
+var TabsOnTop = {
+  toggle: function () {
+    this.enabled = !this.enabled;
+  },
+  syncCommand: function () {
+    document.getElementById("cmd_ToggleTabsOnTop")
+            .setAttribute("checked", this.enabled);
+  },
+  get enabled () {
+    return gNavToolbox.getAttribute("tabsontop") == "true";
+  },
+  set enabled (val) {
+    gNavToolbox.setAttribute("tabsontop", !!val);
+    this.syncCommand();
+
+    //XXX: Trigger reframe. This is a workaround for bug 555987 and needs to be
+    //     removed once that bug is fixed.
+    gNavToolbox.style.MozBoxOrdinalGroup = val ? 2 : 3;
+
+    return val;
+  }
+}
+
 function displaySecurityInfo()
 {
   BrowserPageInfo(null, "securityTab");
 }
 
 /**
  * Opens or closes the sidebar identified by commandID.
  *
@@ -7339,16 +7359,20 @@ let gPrivateBrowsingUI = {
       let searchBox = BrowserSearch.searchBar.textbox;
       searchBox.reset();
       if (this._searchBarValue) {
         searchBox.value = this._searchBarValue;
         this._searchBarValue = null;
       }
     }
 
+    if (gURLBar) {
+      gURLBar.editor.transactionManager.clear();
+    }
+
     document.getElementById("menu_import").removeAttribute("disabled");
 
     // Re-enable the Clear Recent History... menu item on exit of PB mode
     // temporary fix until bug 463607 is fixed
     document.getElementById("Tools:Sanitize").removeAttribute("disabled");
 
     if (gFindBar) {
       let findbox = gFindBar.getElement("findbar-textbox");
@@ -7584,8 +7608,67 @@ var LightWeightThemeWebInstaller = {
     return pm.testPermission(uri, "install") == pm.ALLOW_ACTION;
   },
 
   _getThemeFromNode: function (node) {
     return this._manager.parseTheme(node.getAttribute("data-browsertheme"),
                                     node.baseURI);
   }
 }
+
+function switchToTabHavingURI(aURI) {
+  function switchIfURIInWindow(aWindow) {
+    if (!("gBrowser" in aWindow))
+      return false;
+    let browsers = aWindow.gBrowser.browsers;
+    for (let i = 0; i < browsers.length; i++) {
+      let browser = browsers[i];
+      if (browser.currentURI.equals(aURI)) {
+        gURLBar.handleRevert();
+        aWindow.focus();
+        aWindow.gBrowser.tabContainer.selectedIndex = i;
+        return true;
+      }
+    }
+    return false;
+  }
+
+  // This can be passed either nsIURI or a string.
+  if (!(aURI instanceof Ci.nsIURI))
+    aURI = makeURI(aURI);
+
+  // Prioritise this window.
+  if (switchIfURIInWindow(window))
+    return true;
+
+  let winEnum = Services.wm.getEnumerator("navigator:browser");
+  while (winEnum.hasMoreElements()) {
+    let browserWin = winEnum.getNext();
+    // Skip closed (but not yet destroyed) windows,
+    // and the current window (which was checked earlier).
+    if (browserWin.closed || browserWin == window)
+      continue;
+    if (switchIfURIInWindow(browserWin))
+      return true;
+  }
+  // No opened tab has that url.
+  return false;
+}
+
+var TabContextMenu = {
+  contextTab: null,
+  updateContextMenu: function updateContextMenu(aPopupMenu) {
+    this.contextTab = document.popupNode.localName == "tab" ?
+                      document.popupNode : gBrowser.selectedTab;
+    var disabled = gBrowser.tabs.length == 1;
+    var menuItems = aPopupMenu.getElementsByAttribute("tbattr", "tabbrowser-multiple");
+    for (var i = 0; i < menuItems.length; i++)
+      menuItems[i].disabled = disabled;
+
+    // Session store
+    // XXXzeniko should't we just disable this item as we disable
+    // the tabbrowser-multiple items above - for consistency?
+    document.getElementById("context_undoCloseTab").hidden =
+      Cc["@mozilla.org/browser/sessionstore;1"].
+      getService(Ci.nsISessionStore).
+      getClosedTabCount(window) == 0;
+  }
+}
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -105,16 +105,54 @@
      rely on the new Drag and Drop API these dependencies should be removed. -->
 <script type="application/javascript" src="chrome://global/content/nsDragAndDrop.js"/>
 
 # All sets except for popupsets (commands, keys, stringbundles and broadcasters) *must* go into the 
 # browser-sets.inc file for sharing with hiddenWindow.xul.
 #include browser-sets.inc
 
   <popupset id="mainPopupSet">
+    <menupopup id="tabContextMenu"
+               onpopupshowing="if (event.target == this) TabContextMenu.updateContextMenu(this);"
+               onpopuphidden="if (event.target == this) TabContextMenu.contextTab = null;">
+      <menuitem id="context_newTab" label="&newTab.label;" accesskey="&newTab.accesskey;"
+                command="cmd_newNavigatorTab"/>
+      <menuseparator/>
+      <menuitem id="context_reloadTab" label="&reloadTab.label;" accesskey="&reloadTab.accesskey;"
+                oncommand="gBrowser.reloadTab(TabContextMenu.contextTab);"/>
+      <menuitem id="context_reloadAllTabs" label="&reloadAllTabs.label;" accesskey="&reloadAllTabs.accesskey;"
+                tbattr="tabbrowser-multiple"
+                oncommand="gBrowser.reloadAllTabs();"/>
+      <menuitem id="context_closeOtherTabs" label="&closeOtherTabs.label;" accesskey="&closeOtherTabs.accesskey;"
+                tbattr="tabbrowser-multiple"
+                oncommand="gBrowser.removeAllTabsBut(TabContextMenu.contextTab);"/>
+      <menuseparator/>
+      <menuitem id="context_openTabInWindow" label="&openTabInNewWindow.label;"
+                accesskey="&openTabInNewWindow.accesskey;"
+                tbattr="tabbrowser-multiple"
+                oncommand="gBrowser.replaceTabWithWindow(TabContextMenu.contextTab);"/>
+      <menuseparator/>
+      <menuitem id="context_bookmarkTab"
+                label="&bookmarkThisTab.label;"
+                accesskey="&bookmarkThisTab.accesskey;"
+                oncommand="BookmarkThisTab(TabContextMenu.contextTab);"/>
+      <menuitem id="context_bookmarkAllTabs"
+                label="&bookmarkAllTabs.label;"
+                accesskey="&bookmarkAllTabs.accesskey;"
+                command="Browser:BookmarkAllTabs"/>
+      <menuitem id="context_undoCloseTab"
+                label="&undoCloseTab.label;"
+                accesskey="&undoCloseTab.accesskey;"
+                command="History:UndoCloseTab"/>
+      <menuseparator/>
+      <menuitem id="context_closeTab" label="&closeTab.label;" accesskey="&closeTab.accesskey;"
+                tbattr="tabbrowser-multiple"
+                oncommand="gBrowser.removeTab(TabContextMenu.contextTab);"/>
+    </menupopup>
+
     <menupopup id="backForwardMenu"
                onpopupshowing="return FillHistoryMenu(event.target);"
                oncommand="gotoHistoryIndex(event);"
                onclick="checkForMiddleClick(this, event);"/>
     <tooltip id="aHTMLTooltip" onpopupshowing="return FillInHTMLTooltip(document.tooltipNode);"/>
 
     <!-- for search and content formfill/pw manager -->
     <panel type="autocomplete" id="PopupAutoComplete" noautofocus="true" hidden="true"/>
@@ -178,16 +216,21 @@
                 oncommand="StarUI.panel.hidePopup();"/>
 #endif
       </hbox>
     </panel>
 
     <popup id="toolbar-context-menu"
            onpopupshowing="onViewToolbarsPopupShowing(event);">
       <menuseparator/>
+      <menuitem command="cmd_ToggleTabsOnTop"
+                type="checkbox"
+                label="&viewTabsOnTop.label;"
+                accesskey="&viewTabsOnTop.accesskey;"/>
+      <menuseparator/>
       <menuitem command="cmd_CustomizeToolbars"
                 label="&viewCustomizeToolbar.label;"
                 accesskey="&viewCustomizeToolbar.accesskey;"/>
     </popup>
 
     <popup id="blockedPopupOptions" 
            onpopupshowing="gPopupBlockerObserver.fillPopupList(event);">
       <menuitem observes="blockedPopupAllowSite"/>
@@ -311,17 +354,18 @@
 
     <tooltip id="tabbrowser-tab-tooltip" onpopupshowing="gBrowser.createTooltip(event);"/>
   </popupset>
 
   <toolbox id="navigator-toolbox" class="toolbox-top" mode="icons"
 #ifdef WINCE
            defaulticonsize="small" iconsize="small"
 #endif
-           defaultmode="icons">
+           defaultmode="icons"
+           persist="tabsontop">
     <!-- Menu -->
     <toolbar type="menubar" id="toolbar-menubar" class="chromeclass-menubar" customizable="true"
              defaultset="menubar-items"
              mode="icons" iconsize="small" defaulticonsize="small"
              lockiconsize="true"
 #ifdef XP_WIN
              toolbarname="&menubarCmd.label;"
              accesskey="&menubarCmd.accesskey;"
@@ -399,16 +443,17 @@
                    title="&locationItem.title;" class="chromeclass-location" removable="true">
         <textbox id="urlbar" flex="1"
                  bookmarkhistoryplaceholder="&urlbar.bookmarkhistory.emptyText;"
                  bookmarkplaceholder="&urlbar.bookmark.emptyText;"
                  historyplaceholder="&urlbar.history.emptyText;"
                  noneplaceholder="&urlbar.none.emptyText;"
                  type="autocomplete"
                  autocompletesearch="history"
+                 autocompletesearchparam="enable-actions"
                  autocompletepopup="PopupAutoCompleteRichResult"
                  completeselectedindex="true"
                  tabscrolling="true"
                  showcommentcolumn="true"
                  showimagecolumn="true"
                  enablehistory="true"
                  maxrows="6"
                  newlines="stripsurroundingwhitespace"
@@ -437,16 +482,17 @@
                        onerror="this.removeAttribute('src');"/>
               </stack>
               <hbox id="identity-icon-labels">
                 <label id="identity-icon-label" class="plain" flex="1"/>
                 <label id="identity-icon-country-label" class="plain"/>
               </hbox>
             </hbox>
           </box>
+          <label id="urlbar-display" value="&urlbar.switchToTab.label;"/>
           <hbox id="urlbar-icons">
             <button type="menu"
                     style="-moz-user-focus: none"
                     class="plain urlbar-icon"
                     id="feed-button"
                     collapsed="true"
                     tooltiptext="&feedButton.tooltip;"
                     onclick="return FeedHandler.onFeedButtonClick(event);">
@@ -512,19 +558,20 @@
                oncommand="BookmarksEventHandler.onCommand(event);"
                onpopupshowing="BookmarksEventHandler.onPopupShowing(event);"
                tooltip="bhTooltip" popupsinherittooltip="true"/>
       </toolbaritem>
     </toolbar>
 
     <toolbar id="TabsToolbar"
              fullscreentoolbar="true"
-             ordinal="100"
              collapsed="true">
-      <tabs id="tabbrowser-tabs" class="tabbrowser-tabs"
+      <tabs id="tabbrowser-tabs"
+            class="tabbrowser-tabs"
+            context="tabContextMenu"
             tabbrowser="content"
             flex="1"
             setfocus="false"
             tooltip="tabbrowser-tab-tooltip">
         <tab class="tabbrowser-tab" selected="true"/>
       </tabs>
     </toolbar>
 
--- a/browser/base/content/fullscreen-video.xhtml
+++ b/browser/base/content/fullscreen-video.xhtml
@@ -32,17 +32,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 *****
 -->
-<html xmlns="http://www.w3.org/1999/xhtml">
+<html xmlns="http://www.w3.org/1999/xhtml" accelerated="11">
 <head>
   <style type="text/css"><![CDATA[
 
 html,
 body,
 video {
   height: 100%;
 }
--- a/browser/base/content/nsContextMenu.js
+++ b/browser/base/content/nsContextMenu.js
@@ -95,20 +95,16 @@ function nsContextMenu(aXulMenu, aBrowse
   } catch (e) { }
 
   // Initialize new menu.
   this.initMenu(aXulMenu, aBrowser);
 }
 
 // Prototype for nsContextMenu "class."
 nsContextMenu.prototype = {
-  // onDestroy is a no-op at this point.
-  onDestroy: function () {
-  },
-
   // Initialize context menu.
   initMenu: function CM_initMenu(aPopup, aBrowser) {
     this.menu = aPopup;
     this.browser = aBrowser;
 
     this.isFrameImage = document.getElementById("isFrameImage");
 
     // Get contextual info.
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -91,16 +91,20 @@
       <field name="mURIFixup" readonly="true">
         Components.classes["@mozilla.org/docshell/urifixup;1"]
                   .getService(Components.interfaces.nsIURIFixup);
       </field>
       <field name="mFaviconService" readonly="true">
         Components.classes["@mozilla.org/browser/favicon-service;1"]
                   .getService(Components.interfaces.nsIFaviconService);
       </field>
+      <field name="mBrowserHistory" readonly="true">
+        Components.classes["@mozilla.org/browser/nav-history-service;1"]
+                  .getService(Components.interfaces.nsIBrowserHistory);
+      </field>
       <field name="mTabBox" readonly="true">
         document.getAnonymousElementByAttribute(this, "anonid", "tabbox");
       </field>
       <field name="mPanelContainer" readonly="true">
         document.getAnonymousElementByAttribute(this, "anonid", "panelcontainer");
       </field>
       <field name="mStringBundle">
         document.getAnonymousElementByAttribute(this, "anonid", "tbstringbundle");
@@ -447,42 +451,49 @@
                   aWebProgress.isLoadingDocument &&
                   !(this.mBrowser.docShell.loadType & Ci.nsIDocShell.LOAD_CMD_PUSHSTATE)) {
                 this.mBrowser.mIconURL = null;
               }
 
               // changing location, clear out the missing plugins list
               this.mBrowser.missingPlugins = null;
 
-              if (this.mBlank)
-                return;
-
-              if (this.mTabBrowser.mCurrentTab == this.mTab) {
-                for (let i = 0; i < this.mTabBrowser.mProgressListeners.length; i++) {
-                  let p = this.mTabBrowser.mProgressListeners[i];
+              var browserHistory = this.mTabBrowser.mBrowserHistory;
+              if ("lastURI" in this.mBrowser && this.mBrowser.lastURI)
+                browserHistory.unregisterOpenPage(this.mBrowser.lastURI);
+              browserHistory.registerOpenPage(aLocation);
+
+              if (!this.mBlank) {
+                if (this.mTabBrowser.mCurrentTab == this.mTab) {
+                  for (let i = 0; i < this.mTabBrowser.mProgressListeners.length; i++) {
+                    let p = this.mTabBrowser.mProgressListeners[i];
+                    if (p)
+                      try {
+                        p.onLocationChange(aWebProgress, aRequest, aLocation);
+                      } catch (e) {
+                        // don't inhibit other listeners
+                        Components.utils.reportError(e);
+                      }
+                  }
+                }
+
+                for (let i = 0; i < this.mTabBrowser.mTabsProgressListeners.length; i++) {
+                  let p = this.mTabBrowser.mTabsProgressListeners[i];
                   if (p)
                     try {
-                      p.onLocationChange(aWebProgress, aRequest, aLocation);
+                      p.onLocationChange(this.mBrowser, aWebProgress, aRequest, aLocation);
                     } catch (e) {
                       // don't inhibit other listeners
                       Components.utils.reportError(e);
                     }
                 }
               }
 
-              for (let i = 0; i < this.mTabBrowser.mTabsProgressListeners.length; i++) {
-                let p = this.mTabBrowser.mTabsProgressListeners[i];
-                if (p)
-                  try {
-                    p.onLocationChange(this.mBrowser, aWebProgress, aRequest, aLocation);
-                  } catch (e) {
-                    // don't inhibit other listeners
-                    Components.utils.reportError(e);
-                  }
-              }
+              this.mBrowser.lastURI = aLocation;
+
             },
 
             onStatusChange : function(aWebProgress, aRequest, aStatus, aMessage)
             {
               if (this.mBlank)
                 return;
 
               if (this.mTabBrowser.mCurrentTab == this.mTab) {
@@ -1414,16 +1425,20 @@
             aTab.dispatchEvent(evt);
 
             // Remove the tab's filter and progress listener.
             const filter = this.mTabFilters[aTab._tPos];
             browser.webProgress.removeProgressListener(filter);
             filter.removeProgressListener(this.mTabListeners[aTab._tPos]);
             this.mTabListeners[aTab._tPos].destroy();
 
+            let closedBrowser = this.getBrowserForTab(aTab);
+            if (closedBrowser.currentURI)
+              this.mBrowserHistory.unregisterOpenPage(closedBrowser.currentURI);
+
             // We are no longer the primary content area.
             browser.setAttribute("type", "content-targetable");
 
             // Remove this tab as the owner of any other tabs, since it's going away.
             Array.forEach(this.tabs, function (tab) {
               if ("owner" in tab && tab.owner == aTab)
                 // |tab| is a child of the tab we're removing, make it an orphan
                 tab.owner = null;
@@ -2255,17 +2270,19 @@
           this.appendChild(this._autoScrollPopup);
           this.mCurrentBrowser.setAttribute("autoscrollpopup", this._autoScrollPopup.id);
         ]]>
       </constructor>
 
       <destructor>
         <![CDATA[
           for (var i = 0; i < this.mTabListeners.length; ++i) {
-            this.getBrowserAtIndex(i).webProgress.removeProgressListener(this.mTabFilters[i]);
+            let browser = this.getBrowserAtIndex(i);
+            this.mBrowserHistory.unregisterOpenPage(browser.currentURI);
+            browser.webProgress.removeProgressListener(this.mTabFilters[i]);
             this.mTabFilters[i].removeProgressListener(this.mTabListeners[i]);
             this.mTabFilters[i] = null;
             this.mTabListeners[i].destroy();
             this.mTabListeners[i] = null;
           }
           document.removeEventListener("keypress", this, false);
         ]]>
       </destructor>
@@ -2278,17 +2295,17 @@
         </body>
       </method>
       <method name="getStripVisibility">
         <body>
           return this.tabContainer.visible;
         </body>
       </method>
       <property name="mContextTab" readonly="true"
-                onget="return this.tabContainer._contextTab;"/>
+                onget="return TabContextMenu.contextTab;"/>
       <property name="mPrefs" readonly="true"
                 onget="return Services.prefs;"/>
       <property name="mTabContainer" readonly="true"
                 onget="return this.tabContainer;"/>
       <property name="mTabs" readonly="true"
                 onget="return this.tabs;"/>
       <!--
         - Compatibility hack: several extensions depend on this property to
@@ -2400,57 +2417,20 @@
   </binding>
 
   <binding id="tabbrowser-tabs"
            extends="chrome://global/content/bindings/tabbox.xml#tabs">
     <resources>
       <stylesheet src="chrome://browser/content/tabbrowser.css"/>
     </resources>
 
-    <content context="_child">
+    <content>
       <xul:hbox align="start">
         <xul:image class="tab-drop-indicator" anonid="tab-drop-indicator" collapsed="true"/>
       </xul:hbox>
-      <xul:menupopup anonid="tabContextMenu"
-                     onpopupshowing="if (event.target == this) this.parentNode._updateContextMenu(this);"
-                     onpopuphidden="if (event.target == this) this.parentNode._contextTab = null;">
-        <xul:menuitem id="context_newTab" label="&newTab.label;" accesskey="&newTab.accesskey;"
-                      command="cmd_newNavigatorTab"/>
-        <xul:menuseparator/>
-        <xul:menuitem id="context_reloadTab" label="&reloadTab.label;" accesskey="&reloadTab.accesskey;"
-                      oncommand="this.parentNode.parentNode._contextMenuAction('reloadTab');"/>
-        <xul:menuitem id="context_reloadAllTabs" label="&reloadAllTabs.label;" accesskey="&reloadAllTabs.accesskey;"
-                      tbattr="tabbrowser-multiple"
-                      oncommand="this.parentNode.parentNode._contextMenuAction('reloadAllTabs');"/>
-        <xul:menuitem id="context_closeOtherTabs" label="&closeOtherTabs.label;" accesskey="&closeOtherTabs.accesskey;"
-                      tbattr="tabbrowser-multiple"
-                      oncommand="this.parentNode.parentNode._contextMenuAction('removeAllTabsBut');"/>
-        <xul:menuseparator/>
-        <xul:menuitem id="context_openTabInWindow" label="&openTabInNewWindow.label;"
-                      accesskey="&openTabInNewWindow.accesskey;"
-                      tbattr="tabbrowser-multiple"
-                      oncommand="this.parentNode.parentNode._contextMenuAction('replaceTabWithWindow');"/>
-        <xul:menuseparator/>
-        <xul:menuitem id="context_bookmarkTab"
-                      label="&bookmarkThisTab.label;"
-                      accesskey="&bookmarkThisTab.accesskey;"
-                      oncommand="this.parentNode.parentNode._contextMenuAction('BookmarkThisTab', window);"/>
-        <xul:menuitem id="context_bookmarkAllTabs"
-                      label="&bookmarkAllTabs.label;"
-                      accesskey="&bookmarkAllTabs.accesskey;"
-                      command="Browser:BookmarkAllTabs"/>
-        <xul:menuitem id="context_undoCloseTab"
-                      label="&undoCloseTab.label;"
-                      accesskey="&undoCloseTab.accesskey;"
-                      command="History:UndoCloseTab"/>
-        <xul:menuseparator/>
-        <xul:menuitem id="context_closeTab" label="&closeTab.label;" accesskey="&closeTab.accesskey;"
-                      tbattr="tabbrowser-multiple"
-                      oncommand="this.parentNode.parentNode._contextMenuAction('removeTab');"/>
-      </xul:menupopup>
       <xul:arrowscrollbox anonid="arrowscrollbox" orient="horizontal" flex="1"
                           style="min-width: 1px;"
 #ifndef XP_MACOSX
                           clicktoscroll="true"
 #endif
                           class="tabbrowser-arrowscrollbox">
 # This is a hack to circumvent bug 472020, otherwise the tabs show up on the
 # right of the newtab button.
@@ -2516,17 +2496,17 @@
         document.getElementById(this.getAttribute("tabbrowser"));
       </field>
 
       <field name="tabbox" readonly="true">
         this.tabbrowser.mTabBox;
       </field>
 
       <field name="contextMenu" readonly="true">
-        document.getAnonymousElementByAttribute(this, "anonid", "tabContextMenu");
+        document.getElementById(this.getAttribute("context"));
       </field>
 
       <field name="mTabstripWidth">0</field>
 
       <field name="mTabstrip">
         document.getAnonymousElementByAttribute(this, "anonid", "arrowscrollbox");
       </field>
 
@@ -2703,45 +2683,16 @@
             this._animateElement.setAttribute("notifybgtab", "true");
             setTimeout(function (ele) {
               ele.removeAttribute("notifybgtab");
             }, 150, this._animateElement);
           }
         ]]></body>
       </method>
 
-      <field name="_contextTab">null</field>
-      <method name="_updateContextMenu">
-        <parameter name="aPopupMenu"/>
-        <body><![CDATA[
-          this._contextTab = document.popupNode.localName == "tab" ?
-                             document.popupNode : this.selectedItem;
-          var disabled = this.childNodes.length == 1;
-          var menuItems = aPopupMenu.getElementsByAttribute("tbattr", "tabbrowser-multiple");
-          for (var i = 0; i < menuItems.length; i++)
-            menuItems[i].disabled = disabled;
-
-          // Session store
-          // XXXzeniko should't we just disable this item as we disable
-          // the tabbrowser-multiple items above - for consistency?
-          document.getElementById("context_undoCloseTab").hidden =
-            Cc["@mozilla.org/browser/sessionstore;1"].
-            getService(Ci.nsISessionStore).
-            getClosedTabCount(window) == 0;
-        ]]></body>
-      </method>
-
-      <method name="_contextMenuAction">
-        <parameter name="aMethod"/>
-        <parameter name="aContext"/>
-        <body><![CDATA[
-          (aContext || this.tabbrowser)[aMethod](this._contextTab);
-        ]]></body>
-      </method>
-
       <method name="_getDragTargetTab">
         <parameter name="event"/>
         <body><![CDATA[
           return event.target.localName == "tab" ? event.target : null;
         ]]></body>
       </method>
 
       <method name="_getDropIndex">
--- a/browser/base/content/test/Makefile.in
+++ b/browser/base/content/test/Makefile.in
@@ -112,16 +112,17 @@ include $(topsrcdir)/config/rules.mk
                  browser_bug481560.js \
                  browser_bug484315.js \
                  browser_bug491431.js \
                  browser_bug495058.js \
                  browser_bug517902.js \
                  browser_bug520538.js \
                  browser_bug521216.js \
                  browser_bug537474.js \
+                 browser_bug555224.js \
                  browser_contextSearchTabPosition.js \
                  browser_ctrlTab.js \
                  browser_discovery.js \
                  browser_drag.js \
                  browser_gestureSupport.js \
                  browser_getshortcutoruri.js \
                  browser_overflowScroll.js \
                  browser_pageInfo.js \
@@ -145,16 +146,17 @@ include $(topsrcdir)/config/rules.mk
                  feed_tab.html \
                  plugin_unknown.html \
                  plugin_test.html \
                  plugin_both.html \
                  plugin_both2.html \
                  alltabslistener.html \
                  zoom_test.html \
                  dummy_page.html \
+                 browser_tabMatchesInAwesomebar.js \
     $(NULL)
 
 ifneq (cocoa,$(MOZ_WIDGET_TOOLKIT))
 _BROWSER_FILES += browser_bug462289.js
 else
 _BROWSER_FILES += browser_customize.js
 endif
 
--- a/browser/base/content/test/browser_bug484315.js
+++ b/browser/base/content/test/browser_bug484315.js
@@ -1,13 +1,11 @@
 function test() {
   var contentWin = window.open("about:blank", "", "width=100,height=100");
-  var enumerator = Cc["@mozilla.org/appshell/window-mediator;1"]
-                     .getService(Ci.nsIWindowMediator)
-                     .getEnumerator("navigator:browser");
+  var enumerator = Services.wm.getEnumerator("navigator:browser");
 
   while (enumerator.hasMoreElements()) {
     let win = enumerator.getNext();
     if (win.content == contentWin) {
       gPrefService.setBoolPref("browser.tabs.closeWindowWithLastTab", false);
       win.gBrowser.removeCurrentTab();
       ok(win.closed, "popup is closed");
 
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/browser_bug555224.js
@@ -0,0 +1,93 @@
+/* ***** 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 Browser Test Code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Ryan Flint <rflint@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 TEST_PAGE = "/browser/browser/base/content/test/dummy_page.html";
+var gTestTab, gBgTab, gTestZoom;
+
+function afterZoomAndLoad(aCallback, aTab) {
+  let didLoad = didZoom = false;
+  aTab.linkedBrowser.addEventListener("load", function() {
+    aTab.linkedBrowser.removeEventListener("load", arguments.callee, true);
+    didLoad = true;
+    if (didZoom)
+      executeSoon(aCallback);
+  }, true);
+  let oldAPTS = FullZoom._applyPrefToSetting;
+  FullZoom._applyPrefToSetting = function(value, browser) {
+    if (!value)
+      value = undefined;
+    oldAPTS.call(FullZoom, value, browser);
+    // Don't reset _applyPrefToSetting until we've seen the about:blank load(s)
+    if (browser && (browser.currentURI.spec.indexOf("http:") != -1)) {
+      FullZoom._applyPrefToSetting = oldAPTS;
+      didZoom = true;
+    }
+    if (didLoad && didZoom)
+      executeSoon(aCallback);
+  };
+}
+
+function testBackgroundLoad() {
+  is(ZoomManager.zoom, gTestZoom, "opening a background tab should not change foreground zoom");
+
+  gBrowser.removeTab(gBgTab);
+
+  FullZoom.reset();
+  gBrowser.removeTab(gTestTab);
+
+  finish();
+}
+
+function testInitialZoom() {
+  is(ZoomManager.zoom, 1, "initial zoom level should be 1");
+  FullZoom.enlarge();
+
+  gTestZoom = ZoomManager.zoom;
+  isnot(gTestZoom, 1, "zoom level should have changed");
+
+  afterZoomAndLoad(testBackgroundLoad,
+                   gBgTab = gBrowser.loadOneTab("http://mochi.test:8888" + TEST_PAGE,
+                                                {inBackground: true}));
+}
+
+function test() {
+  waitForExplicitFinish();
+
+  gTestTab = gBrowser.addTab();
+  gBrowser.selectedTab = gTestTab;
+
+  afterZoomAndLoad(testInitialZoom, gTestTab);
+  content.location = "http://example.org" + TEST_PAGE;
+}
--- a/browser/base/content/test/browser_getshortcutoruri.js
+++ b/browser/base/content/test/browser_getshortcutoruri.js
@@ -95,39 +95,35 @@ function test() {
   }
 
   cleanupKeywords();
 }
 
 var gBMFolder = null;
 var gAddedEngines = [];
 function setupKeywords() {
-  var searchService = Cc["@mozilla.org/browser/search-service;1"].
-                      getService(Ci.nsIBrowserSearchService);
   gBMFolder = Application.bookmarks.menu.addFolder("keyword-test");
   for each (var item in testData) {
     var data = item[0];
     if (data instanceof bmKeywordData) {
       var bm = gBMFolder.addBookmark(data.keyword, data.uri);
       bm.keyword = data.keyword;
       if (data.postData)
         bm.annotations.set("bookmarkProperties/POSTData", data.postData, Ci.nsIAnnotationService.EXPIRE_SESSION);
     }
 
     if (data instanceof searchKeywordData) {
-      searchService.addEngineWithDetails(data.keyword, "", data.keyword, "", data.method, data.uri.spec);
-      var addedEngine = searchService.getEngineByName(data.keyword);
+      Services.search.addEngineWithDetails(data.keyword, "", data.keyword, "", data.method, data.uri.spec);
+      var addedEngine = Services.search.getEngineByName(data.keyword);
       if (data.postData) {
         var [paramName, paramValue] = data.postData.split("=");
         addedEngine.addParam(paramName, paramValue, null);
       }
 
       gAddedEngines.push(addedEngine);
     }
   }
 }
 
 function cleanupKeywords() {
-  var searchService = Cc["@mozilla.org/browser/search-service;1"].
-                      getService(Ci.nsIBrowserSearchService);
   gBMFolder.remove();
-  gAddedEngines.map(searchService.removeEngine);
+  gAddedEngines.map(Services.search.removeEngine);
 }
--- a/browser/base/content/test/browser_pageInfo.js
+++ b/browser/base/content/test/browser_pageInfo.js
@@ -1,19 +1,17 @@
-var obs = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
-
 function test() {
   waitForExplicitFinish();
 
   var pageInfo, atTest = 0;
   gBrowser.selectedTab = gBrowser.addTab();
   gBrowser.selectedBrowser.addEventListener("load", function () {
     gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
     pageInfo = BrowserPageInfo();
-    obs.addObserver(observer, "page-info-dialog-loaded", false);
+    Services.obs.addObserver(observer, "page-info-dialog-loaded", false);
   }, true);
   content.location =
     "https://example.com/browser/browser/base/content/test/feed_tab.html";
 
   function observer(win, topic, data) {
     if (topic != "page-info-dialog-loaded")
       return;
 
@@ -24,17 +22,17 @@ function test() {
         break;
       case 1:
         atTest++;
         pageInfo = win;
         testLockClick();
         break;
       case 2:
         atTest++;
-        obs.removeObserver(observer, "page-info-dialog-loaded");
+        Services.obs.removeObserver(observer, "page-info-dialog-loaded");
         testLockDoubleClick();
         break;
     }
   }
 
   function $(aId) { return pageInfo.document.getElementById(aId) };
 
   function handlePageInfo() {
@@ -71,19 +69,17 @@ function test() {
       var lockIcon = document.getElementById("security-button");
       EventUtils.synthesizeMouse(lockIcon, 0, 0, {clickCount: 1});
       EventUtils.synthesizeMouse(lockIcon, 0, 0, {clickCount: 2});
     }, false);
     pageInfo.close();
   }
 
   function testLockDoubleClick() {
-    var pageInfoDialogs = Cc["@mozilla.org/appshell/window-mediator;1"]
-                            .getService(Ci.nsIWindowMediator)
-                            .getEnumerator("Browser:page-info");
+    var pageInfoDialogs = Services.wm.getEnumerator("Browser:page-info");
     var i = 0;
     while (pageInfoDialogs.hasMoreElements()) {
       i++;
       pageInfo = pageInfoDialogs.getNext();
       pageInfo.close();
     }
     is(i, 1, "When the lock is clicked twice there should be only one page info dialog");
     gBrowser.removeCurrentTab();
--- a/browser/base/content/test/browser_pluginnotification.js
+++ b/browser/base/content/test/browser_pluginnotification.js
@@ -1,16 +1,15 @@
 const gTestRoot = "chrome://mochikit/content/browser/browser/base/content/test/";
 
 var gTestBrowser = null;
 var gNextTest = null;
 
 function get_test_plugin() {
-  var ph = Components.classes["@mozilla.org/plugin/host;1"]
-                     .getService(Components.interfaces.nsIPluginHost);
+  var ph = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
   var tags = ph.getPluginTags();
   
   // Find the test plugin
   for (var i = 0; i < tags.length; i++) {
     if (tags[i].name == "Test Plug-in")
       return tags[i];
   }
 }
@@ -18,19 +17,17 @@ function get_test_plugin() {
 // This listens for the next opened window and checks it is of the right url.
 // opencallback is called when the new window is fully loaded
 // closecallback is called when the window is closed
 function WindowOpenListener(url, opencallback, closecallback) {
   this.url = url;
   this.opencallback = opencallback;
   this.closecallback = closecallback;
 
-  var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
-                     .getService(Components.interfaces.nsIWindowMediator);
-  wm.addListener(this);
+  Services.wm.addListener(this);
 }
 
 WindowOpenListener.prototype = {
   url: null,
   opencallback: null,
   closecallback: null,
   window: null,
   domwindow: null,
@@ -56,19 +53,17 @@ WindowOpenListener.prototype = {
                            .getInterface(Components.interfaces.nsIDOMWindowInternal);
     this.domwindow.addEventListener("load", this, false);
   },
 
   onCloseWindow: function(window) {
     if (this.window != window)
       return;
 
-    var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
-                       .getService(Components.interfaces.nsIWindowMediator);
-    wm.removeListener(this);
+    Services.wm.removeListener(this);
     this.opencallback = null;
     this.window = null;
     this.domwindow = null;
 
     // Let the window close complete
     executeSoon(this.closecallback);
     this.closecallback = null;
   }
--- a/browser/base/content/test/browser_sanitize-download-history.js
+++ b/browser/base/content/test/browser_sanitize-download-history.js
@@ -66,23 +66,21 @@ function test()
 
   function test_checkedAfterAddingDownload(aWin)
   {
     let doc = aWin.document;
     let downloads = doc.getElementById("downloads-checkbox");
     let history = doc.getElementById("history-checkbox");
 
     // Add download to DB
-    let ios = Cc["@mozilla.org/network/io-service;1"].
-              getService(Ci.nsIIOService);
     let file = Cc["@mozilla.org/file/directory_service;1"].
                getService(Ci.nsIProperties).get("TmpD", Ci.nsIFile);
     file.append("satitize-dm-test.file");
     file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0666);
-    let testPath = ios.newFileURI(file).spec;
+    let testPath = Services.io.newFileURI(file).spec;
     let data = {
       name: "381603.patch",
       source: "https://bugzilla.mozilla.org/attachment.cgi?id=266520",
       target: testPath,
       startTime: 1180493839859230,
       endTime: 1180493839859239,
       state: Ci.nsIDownloadManager.DOWNLOAD_FINISHED,
       currBytes: 0, maxBytes: -1, preferredAction: 0, autoResume: 0
@@ -137,42 +135,40 @@ function test()
   let dm = Cc["@mozilla.org/download-manager;1"].
            getService(Ci.nsIDownloadManager);
   let db = dm.DBConnection;
 
   // Empty any old downloads
   db.executeSimpleSQL("DELETE FROM moz_downloads");
 
   // Close the UI if necessary
-  let ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
-           getService(Ci.nsIWindowWatcher);
-  let win = ww.getWindowByName("Sanatize", null);
+  let win = Services.ww.getWindowByName("Sanatize", null);
   if (win && (win instanceof Ci.nsIDOMWindowInternal))
     win.close();
 
   // Start the test when the sanitize window loads
-  ww.registerNotification(function (aSubject, aTopic, aData) {
-    ww.unregisterNotification(arguments.callee);
+  Services.ww.registerNotification(function (aSubject, aTopic, aData) {
+    Services.ww.unregisterNotification(arguments.callee);
     aSubject.QueryInterface(Ci.nsIDOMEventTarget)
             .addEventListener("DOMContentLoaded", doTest, false);
   });
 
   // Let the methods that run onload finish before we test
   let doTest = function() setTimeout(function() {
-    let win = ww.getWindowByName("Sanitize", null)
+    let win = Services.ww.getWindowByName("Sanitize", null)
                 .QueryInterface(Ci.nsIDOMWindowInternal);
 
     for (let i = 0; i < tests.length; i++)
       tests[i](win);
 
     win.close();
     finish();
   }, 0);
  
   // Show the UI
-  ww.openWindow(window,
-                "chrome://browser/content/sanitize.xul",
-                "Sanitize",
-                "chrome,titlebar,centerscreen",
-                null);
+  Services.ww.openWindow(window,
+                         "chrome://browser/content/sanitize.xul",
+                         "Sanitize",
+                         "chrome,titlebar,centerscreen",
+                         null);
 
   waitForExplicitFinish();
 }
--- a/browser/base/content/test/browser_sanitize-sitepermissions.js
+++ b/browser/base/content/test/browser_sanitize-sitepermissions.js
@@ -1,18 +1,17 @@
 // Bug 380852 - Delete permission manager entries in Clear Recent History
 
 Cc["@mozilla.org/moz/jssubscript-loader;1"].getService(Ci.mozIJSSubScriptLoader)
                                            .loadSubScript("chrome://browser/content/sanitize.js");
 
 function test() {
   
   // Add a permission entry
-  var pm = Cc["@mozilla.org/permissionmanager;1"]
-             .getService(Ci.nsIPermissionManager);
+  var pm = Services.perms;
   pm.add(makeURI("http://example.com"), "testing", pm.ALLOW_ACTION);
   
   // Sanity check
   ok(pm.enumerator.hasMoreElements(), "Permission manager should have elements, since we just added one");
   
   // Set up the sanitizer to just clear siteSettings
   let s = new Sanitizer();
   s.ignoreTimespan = false;
--- a/browser/base/content/test/browser_sanitizeDialog.js
+++ b/browser/base/content/test/browser_sanitizeDialog.js
@@ -46,25 +46,23 @@
  * test checks the UI of the dialog and makes sure it's correctly connected to
  * the sanitize timespan code.
  *
  * Some of this code, especially the history creation parts, was taken from
  * browser/base/content/test/browser_sanitize-timespans.js.
  */
 
 Cc["@mozilla.org/moz/jssubscript-loader;1"].
-  getService(Components.interfaces.mozIJSSubScriptLoader).
+  getService(Ci.mozIJSSubScriptLoader).
   loadSubScript("chrome://mochikit/content/MochiKit/packed.js");
 
 Cc["@mozilla.org/moz/jssubscript-loader;1"].
-  getService(Components.interfaces.mozIJSSubScriptLoader).
+  getService(Ci.mozIJSSubScriptLoader).
   loadSubScript("chrome://browser/content/sanitize.js");
 
-const winWatch = Cc["@mozilla.org/embedcomp/window-watcher;1"].
-                 getService(Ci.nsIWindowWatcher);
 const dm = Cc["@mozilla.org/download-manager;1"].
            getService(Ci.nsIDownloadManager);
 const bhist = Cc["@mozilla.org/browser/global-history;2"].
               getService(Ci.nsIBrowserHistory);
 const formhist = Cc["@mozilla.org/satchel/form-history;1"].
                  getService(Ci.nsIFormHistory2);
 
 // Add tests here.  Each is a function that's called by doNextTest().
@@ -535,17 +533,17 @@ WindowHelper.prototype = {
    */
   open: function () {
     let wh = this;
 
     function windowObserver(aSubject, aTopic, aData) {
       if (aTopic != "domwindowopened")
         return;
 
-      winWatch.unregisterNotification(windowObserver);
+      Services.ww.unregisterNotification(windowObserver);
 
       var loaded = false;
       let win = aSubject.QueryInterface(Ci.nsIDOMWindow);
 
       win.addEventListener("load", function onload(event) {
         win.removeEventListener("load", onload, false);
 
         if (win.name !== "SanitizeDialog")
@@ -592,22 +590,22 @@ WindowHelper.prototype = {
           catch (exc) {
             win.close();
             ok(false, "Unexpected exception: " + exc + "\n" + exc.stack);
             finish();
           }
         });
       }, false);
     }
-    winWatch.registerNotification(windowObserver);
-    winWatch.openWindow(null,
-                        "chrome://browser/content/sanitize.xul",
-                        "SanitizeDialog",
-                        "chrome,titlebar,dialog,centerscreen,modal",
-                        null);
+    Services.ww.registerNotification(windowObserver);
+    Services.ww.openWindow(null,
+                           "chrome://browser/content/sanitize.xul",
+                           "SanitizeDialog",
+                           "chrome,titlebar,dialog,centerscreen,modal",
+                           null);
   },
 
   /**
    * Selects a duration in the duration dropdown.
    *
    * @param aDurVal
    *        One of the Sanitizer.TIMESPAN_* values
    */
--- a/browser/base/content/test/browser_sanitizeDialog_treeView.js
+++ b/browser/base/content/test/browser_sanitizeDialog_treeView.js
@@ -45,25 +45,23 @@
  * test checks the UI of the dialog and makes sure it's correctly connected to
  * the sanitize timespan code.
  *
  * Some of this code, especially the history creation parts, was taken from
  * browser/base/content/test/browser_sanitize-timespans.js.
  */
 
 Cc["@mozilla.org/moz/jssubscript-loader;1"].
-  getService(Components.interfaces.mozIJSSubScriptLoader).
+  getService(Ci.mozIJSSubScriptLoader).
   loadSubScript("chrome://mochikit/content/MochiKit/packed.js");
 
 Cc["@mozilla.org/moz/jssubscript-loader;1"].
-  getService(Components.interfaces.mozIJSSubScriptLoader).
+  getService(Ci.mozIJSSubScriptLoader).
   loadSubScript("chrome://browser/content/sanitize.js");
 
-const winWatch = Cc["@mozilla.org/embedcomp/window-watcher;1"].
-                 getService(Ci.nsIWindowWatcher);
 const dm = Cc["@mozilla.org/download-manager;1"].
            getService(Ci.nsIDownloadManager);
 const bhist = Cc["@mozilla.org/browser/global-history;2"].
               getService(Ci.nsIBrowserHistory);
 const formhist = Cc["@mozilla.org/satchel/form-history;1"].
                  getService(Ci.nsIFormHistory2);
 
 // Add tests here.  Each is a function that's called by doNextTest().
@@ -617,17 +615,17 @@ function ensureHistoryClearedState(aURIs
  * @param aOnloadCallback
  *        A function that will be called once the dialog has loaded
  */
 function openWindow(aOnloadCallback) {
   function windowObserver(aSubject, aTopic, aData) {
     if (aTopic != "domwindowopened")
       return;
 
-    winWatch.unregisterNotification(windowObserver);
+    Services.ww.unregisterNotification(windowObserver);
     let win = aSubject.QueryInterface(Ci.nsIDOMWindow);
     win.addEventListener("load", function onload(event) {
       win.removeEventListener("load", onload, false);
       executeSoon(function () {
         // Some exceptions that reach here don't reach the test harness, but
         // ok()/is() do...
         try {
           aOnloadCallback(win);
@@ -636,22 +634,22 @@ function openWindow(aOnloadCallback) {
         catch (exc) {
           win.close();
           ok(false, "Unexpected exception: " + exc + "\n" + exc.stack);
           finish();
         }
       });
     }, false);
   }
-  winWatch.registerNotification(windowObserver);
-  winWatch.openWindow(null,
-                      "chrome://browser/content/sanitize.xul",
-                      "Sanitize",
-                      "chrome,titlebar,dialog,centerscreen,modal",
-                      null);
+  Services.ww.registerNotification(windowObserver);
+  Services.ww.openWindow(null,
+                         "chrome://browser/content/sanitize.xul",
+                         "Sanitize",
+                         "chrome,titlebar,dialog,centerscreen,modal",
+                         null);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
 function test() {
   blankSlate();
   waitForExplicitFinish();
   // Kick off all the tests in the gAllTests array.
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/browser_tabMatchesInAwesomebar.js
@@ -0,0 +1,231 @@
+/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * vim:set ts=2 sw=2 sts=2 et:
+ * ***** 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 Places Test Code.
+ *
+ * The Initial Developer of the Original Code is the Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Blair McBride <bmcbride@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+Components.utils.import("resource://gre/modules/Services.jsm");
+
+const TEST_URL_BASES = [
+  "http://example.org/browser/browser/base/content/test/dummy_page.html#tabmatch",
+  "http://example.org/browser/browser/base/content/test/moz.png#tabmatch"
+];
+
+var gPrivateBrowsing = Cc["@mozilla.org/privatebrowsing;1"].
+                         getService(Ci.nsIPrivateBrowsingService);
+
+
+var gTabWaitCount = 0;
+var gTabCounter = 0;
+
+var gTestSteps = [
+  function() {
+    info("Running step 1");
+    for (let i = 0; i < 10; i++) {
+      let tab = gBrowser.addTab();
+      loadTab(tab, TEST_URL_BASES[0] + (++gTabCounter));
+    }
+  },
+  function() {
+    info("Running step 2");
+    gBrowser.selectTabAtIndex(1);
+    gBrowser.removeCurrentTab();
+    gBrowser.selectTabAtIndex(1);
+    gBrowser.removeCurrentTab();
+    for (let i = 1; i < gBrowser.tabs.length; i++)
+      loadTab(gBrowser.tabs[i], TEST_URL_BASES[1] + (++gTabCounter));
+  },
+  function() {
+    info("Running step 3");
+    for (let i = 1; i < gBrowser.tabs.length; i++)
+      loadTab(gBrowser.tabs[i], TEST_URL_BASES[0] + gTabCounter);
+  },
+  function() {
+    info("Running step 4");
+    let ps = Services.prefs;
+    ps.setBoolPref("browser.privatebrowsing.keep_current_session", true);
+    ps.setBoolPref("browser.tabs.warnOnClose", false);
+
+    gPrivateBrowsing.privateBrowsingEnabled = true;
+
+    executeSoon(function() {
+      ensure_opentabs_match_db();
+      nextStep();
+    });
+  },
+  function() {
+    info("Running step 5");
+    gPrivateBrowsing.privateBrowsingEnabled = false;
+
+    executeSoon(function() {
+      let ps = Services.prefs;
+      try {
+        ps.clearUserPref("browser.privatebrowsing.keep_current_session");
+      } catch (ex) {}
+      try {
+        ps.clearUserPref("browser.tabs.warnOnClose");
+      } catch (ex) {}
+
+      ensure_opentabs_match_db();
+      nextStep()
+    });
+  }
+];
+
+
+
+function test() {
+  waitForExplicitFinish();
+  nextStep();
+}
+
+function loadTab(tab, url) {
+  tab.linkedBrowser.addEventListener("load", function (event) {
+    tab.linkedBrowser.removeEventListener("load", arguments.callee, true);
+
+    if (--gTabWaitCount > 0)
+      return;
+    is(gTabWaitCount, 0,
+       "sanity check, gTabWaitCount should not be decremented below 0");
+
+    try {
+      ensure_opentabs_match_db();
+    } catch (e) {
+      ok(false, "exception from ensure_openpages_match_db: " + e);
+    }
+
+    executeSoon(nextStep);
+  }, true);
+  gTabWaitCount++;
+  tab.linkedBrowser.loadURI(url);
+}
+
+function nextStep() {
+  if (gTestSteps.length == 0) {
+    while (gBrowser.tabs.length > 1) {
+      gBrowser.selectTabAtIndex(1);
+      gBrowser.removeCurrentTab();
+    }
+
+    waitForClearHistory(finish);
+
+    return;
+  }
+
+  var stepFunc = gTestSteps.shift();
+  stepFunc();
+}
+
+function ensure_opentabs_match_db() {
+  var tabs = {};
+
+  var winEnum = Services.wm.getEnumerator("navigator:browser");
+  while (winEnum.hasMoreElements()) {
+    let browserWin = winEnum.getNext();
+    // skip closed-but-not-destroyed windows
+    if (browserWin.closed)
+      continue;
+
+    for (let i = 0; i < browserWin.gBrowser.tabContainer.childElementCount; i++) {
+      let browser = browserWin.gBrowser.getBrowserAtIndex(i);
+      let url = browser.currentURI.spec;
+      if (!(url in tabs))
+        tabs[url] = 1;
+      else
+        tabs[url]++;
+    }
+  }
+
+  var db = PlacesUtils.history.QueryInterface(Ci.nsPIPlacesDatabase)
+                              .DBConnection;
+
+  try {
+    var stmt = db.createStatement(
+                          "SELECT IFNULL(p_t.url, p.url) AS url, open_count, place_id " +
+                          "FROM moz_openpages_temp " +
+                          "LEFT JOIN moz_places p ON p.id=place_id " +
+                          "LEFT JOIN moz_places_temp p_t ON p_t.id=place_id");
+  } catch (e) {
+    ok(false, "error creating db statement: " + e);
+    return;
+  }
+
+  var dbtabs = [];
+  try {
+    while (stmt.executeStep()) {
+      ok(stmt.row.url in tabs,
+         "url is in db, should be in tab: " + stmt.row.url);
+      is(tabs[stmt.row.url], stmt.row.open_count,
+         "db count (" + stmt.row.open_count + ") " +
+         "should match actual open tab count " +
+         "(" + tabs[stmt.row.url] + "): " + stmt.row.url);
+      dbtabs.push(stmt.row.url);
+    }
+  } finally {
+    stmt.finalize();
+  }
+
+  for (let url in tabs) {
+    // ignore URLs that should never be in the places db
+    if (!is_expected_in_db(url))
+      continue;
+    ok(dbtabs.indexOf(url) > -1,
+       "tab is open (" + tabs[url] + " times) and should recorded in db: " + url);
+  }
+}
+
+function is_expected_in_db(url) {
+  var uri = Services.io.newURI(url, null, null);
+  return PlacesUtils.history.canAddURI(uri);
+}
+
+/**
+ * Clears history invoking callback when done.
+ */
+function waitForClearHistory(aCallback) {
+  const TOPIC_EXPIRATION_FINISHED = "places-expiration-finished";
+  let observer = {
+    observe: function(aSubject, aTopic, aData) {
+      Services.obs.removeObserver(this, TOPIC_EXPIRATION_FINISHED);
+      aCallback();
+    }
+  };
+  Services.obs.addObserver(observer, TOPIC_EXPIRATION_FINISHED, false);
+
+  let hs = Cc["@mozilla.org/browser/nav-history-service;1"].
+           getService(Ci.nsINavHistoryService);
+  hs.QueryInterface(Ci.nsIBrowserHistory).removeAllPages();
+}
--- a/browser/base/content/urlbarBindings.xml
+++ b/browser/base/content/urlbarBindings.xml
@@ -56,31 +56,66 @@
         this._setPlaceholder();
 
         this._urlTooltip = document.getElementById("urlTooltip");
 
         this.inputField.controllers.insertControllerAt(0, this._copyCutController);
         this.inputField.addEventListener("mousedown", this, false);
         this.inputField.addEventListener("mousemove", this, false);
         this.inputField.addEventListener("mouseout", this, false);
-        this.inputField.addEventListener("overflow", this, false);
-        this.inputField.addEventListener("underflow", this, false);
+        this.inputField.addEventListener("overflow", this, false);
+        this.inputField.addEventListener("underflow", this, false);
       ]]></constructor>
 
       <destructor><![CDATA[
         this._prefs.removeObserver("", this);
         this._prefs = null;
         this.inputField.controllers.removeController(this._copyCutController);
         this.inputField.removeEventListener("mousedown", this, false);
         this.inputField.removeEventListener("mousemove", this, false);
         this.inputField.removeEventListener("mouseout", this, false);
-        this.inputField.removeEventListener("overflow", this, false);
-        this.inputField.removeEventListener("underflow", this, false);
+        this.inputField.removeEventListener("overflow", this, false);
+        this.inputField.removeEventListener("underflow", this, false);
       ]]></destructor>
 
+      <field name="_value"></field>
+
+      <!--
+        onBeforeValueGet is called by the base-binding's .value getter.
+        It can return an object with a "value" property, to override the
+        return value of the getter.
+      -->
+      <method name="onBeforeValueGet">
+        <body><![CDATA[
+          if (this.hasAttribute("actiontype"))
+            return {value: this._value};
+          return null;
+        ]]></body>
+      </method>
+
+      <!--
+        onBeforeValueSet is called by the base-binding's .value setter.
+        It should return the value that the setter should use.
+      -->
+      <method name="onBeforeValueSet">
+        <parameter name="aValue"/>
+        <body><![CDATA[
+          this._value = aValue;
+          var returnValue = aValue;
+          var action = this._parseActionUrl(aValue);
+          if (action) {
+            returnValue = action.param;
+            this.setAttribute("actiontype", action.type);
+          } else {
+            this.removeAttribute("actiontype");
+          }
+          return returnValue;
+        ]]></body>
+      </method>
+
       <method name="handleRevert">
         <body><![CDATA[
           var isScrolling = this.popupOpen;
 
           gBrowser.userTypedValue = null;
 
           // don't revert to last valid url unless page is NOT loading
           // and user is NOT key-scrolling through autocomplete list
@@ -103,16 +138,23 @@
         <body><![CDATA[
           if (aTriggeringEvent instanceof MouseEvent && aTriggeringEvent.button == 2)
             return; // Do nothing for right clicks
 
           var [url, postData] = this._canonizeURL(aTriggeringEvent);
           if (!url)
             return;
 
+          var action = this._parseActionUrl(url);
+          if (action) {
+            if (action.type == "switchtab")
+              switchToTabHavingURI(action.param);
+            return;
+          }
+
           this.value = url;
           gBrowser.userTypedValue = url;
           try {
             addToUrlbarHistory(url);
           } catch (ex) {
             // Things may go wrong when adding url to session history,
             // but don't let that interfere with the loading of the url.
             Cu.reportError(ex);
@@ -211,22 +253,22 @@
           }
 
           var postData = {};
           url = getShortcutOrURI(url, postData);
 
           return [url, postData.value];
         ]]></body>
       </method>
-
-      <field name="_contentIsCropped">false</field>
+
+      <field name="_contentIsCropped">false</field>
 
       <method name="_initURLTooltip">
         <body><![CDATA[
-          if (this.focused || !this._contentIsCropped)
+          if (this.focused || !this._contentIsCropped)
             return;
           if (this._tooltipTimer)
             clearTimeout(this._tooltipTimer);
           this._tooltipTimer = setTimeout(function (self) {
             self._tooltipTimer = 0;
             var label = self._urlTooltip.firstChild;
             label.value = self.value;
             var bO = self.boxObject;
@@ -384,23 +426,23 @@
               }
               break;
             case "mousemove":
               this._initURLTooltip();
               break;
             case "mouseout":
               this._hideURLTooltip();
               break;
-            case "overflow":
-              this._contentIsCropped = true;
-              break;
-            case "underflow":
-              this._contentIsCropped = false;
-              this._hideURLTooltip();
-              break;
+            case "overflow":
+              this._contentIsCropped = true;
+              break;
+            case "underflow":
+              this._contentIsCropped = false;
+              this._hideURLTooltip();
+              break;
           }
         ]]></body>
       </method>
 
       <property name="textValue"
                 onget="return this.value;">
         <setter>
           <![CDATA[
@@ -437,16 +479,28 @@
               case 2:
                 type = "bookmark";
                 break;
             }
           }
           this.placeholder = this.getAttribute(type + "placeholder");
         ]]></body>
       </method>
+
+      <method name="_parseActionUrl">
+        <parameter name="aUrl"/>
+        <body><![CDATA[
+          if (!/^moz-action:/.test(aUrl))
+            return null;
+
+          // url is in the format moz-action:ACTION,PARAM
+          let [, action, param] = aUrl.match(/^moz-action:([^,]+),(.*)$/);
+          return {type: action, param: param};
+        ]]></body>
+      </method>
     </implementation>
 
     <handlers>
       <handler event="draggesture" phase="capturing"><![CDATA[
         // TODO: This should use dragstart but editor code is still using
         //       the old drag & drop APIs, so we have to handle draggesture.
         //       This can be changed once editor code is updated to the new API.
         //       See bug 499008 for details.
@@ -608,16 +662,25 @@
           // Check for middle-click or modified clicks on the URL bar
           if (gURLBar && this.mInput == gURLBar) {
             var url = controller.getValueAt(this.selectedIndex);
 
             // close the autocomplete popup and revert the entered address
             this.closePopup();
             controller.handleEscape();
 
+            // Check if this is meant to be an action
+            let action = this.mInput._parseActionUrl(url);
+            if (action) {
+              if (action.type == "switchtab")
+                url = action.param;
+              else
+                return;
+            }
+
             // respect the usual clicking subtleties
             openUILink(url, aEvent);
           }
         ]]>
         </body>
       </method>
 
       <method name="createResultLabel">
@@ -635,9 +698,10 @@
             }
             return label;
           ]]>
         </body>
       </method>
 
     </implementation>
   </binding>
+
 </bindings>
--- a/browser/components/Makefile.in
+++ b/browser/components/Makefile.in
@@ -80,15 +80,19 @@ ifndef WINCE
 PARALLEL_DIRS += wintaskbar
 endif
 endif
 
 ifdef MOZ_SAFE_BROWSING
 PARALLEL_DIRS += safebrowsing
 endif
 
+ifdef ENABLE_TESTS
+DIRS += test
+endif
+
 DIRS += build
 
 ifdef MOZILLA_OFFICIAL
 DEFINES += -DOFFICIAL_BUILD=1
 endif
 
 include $(topsrcdir)/config/rules.mk
--- a/browser/components/nsBrowserContentHandler.js
+++ b/browser/components/nsBrowserContentHandler.js
@@ -15,16 +15,17 @@
 #
 # The Initial Developer of the Original Code is
 # Benjamin Smedberg <benjamin@smedbergs.us>
 #
 # Portions created by the Initial Developer are Copyright (C) 2004
 # the Initial Developer. All Rights Reserved.
 #
 # Contributor(s):
+#   Robert Strong <robert.bugzilla@gmail.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
@@ -144,16 +145,50 @@ function needHomepageOverride(prefb) {
     
     prefb.setCharPref("browser.startup.homepage_override.mstone", mstone);
     return (savedmstone ? OVERRIDE_NEW_MSTONE : OVERRIDE_NEW_PROFILE);
   }
 
   return OVERRIDE_NONE;
 }
 
+/**
+ * Gets the override page for the first run after the application has been
+ * updated.
+ * @param  defaultOverridePage
+ *         The default override page.
+ * @return The override page.
+ */
+function getPostUpdateOverridePage(defaultOverridePage) {
+  var um = Components.classes["@mozilla.org/updates/update-manager;1"]
+                     .getService(Components.interfaces.nsIUpdateManager);
+  try {
+    // If the updates.xml file is deleted then getUpdateAt will throw.
+    var update = um.getUpdateAt(0)
+                   .QueryInterface(Components.interfaces.nsIPropertyBag);
+  } catch (e) {
+    // This should never happen.
+    Components.utils.reportError("Unable to find update: " + e);
+    return defaultOverridePage;
+  }
+
+  let actions = update.getProperty("actions");
+  // When the update doesn't specify actions fallback to the original behavior
+  // of displaying the default override page.
+  if (!actions)
+    return defaultOverridePage;
+
+  // The existence of silent or the non-existence of showURL in the actions both
+  // mean that an override page should not be displayed.
+  if (actions.indexOf("silent") != -1 || actions.indexOf("showURL") == -1)
+    return "";
+
+  return update.getProperty("openURL") || defaultOverridePage;
+}
+
 // Copies a pref override file into the user's profile pref-override folder,
 // and then tells the pref service to reload its default prefs.
 function copyPrefOverride() {
   try {
     var fileLocator = Components.classes["@mozilla.org/file/directory_service;1"]
                                 .getService(Components.interfaces.nsIProperties);
     const NS_APP_EXISTING_PREF_OVERRIDE = "ExistingPrefOverride";
     var prefOverride = fileLocator.get(NS_APP_EXISTING_PREF_OVERRIDE,
@@ -531,18 +566,20 @@ var nsBrowserContentHandler = {
           copyPrefOverride();
 
           // Check whether we have a session to restore. If we do, we assume
           // that this is an "update" session.
           var ss = Components.classes["@mozilla.org/browser/sessionstartup;1"]
                              .getService(Components.interfaces.nsISessionStartup);
           haveUpdateSession = ss.doRestore();
           overridePage = formatter.formatURLPref("startup.homepage_override_url");
+          if (prefb.prefHasUserValue("app.update.postupdate"))
+            overridePage = getPostUpdateOverridePage(overridePage);
           break;
-    }
+      }
     } catch (ex) {}
 
     // formatURLPref might return "about:blank" if getting the pref fails
     if (overridePage == "about:blank")
       overridePage = "";
 
     var startPage = "";
     try {
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -21,16 +21,17 @@
 # Contributor(s):
 #   Giorgio Maone <g.maone@informaction.com>
 #   Seth Spitzer <sspitzer@mozilla.com>
 #   Asaf Romano <mano@mozilla.com>
 #   Marco Bonardo <mak77@bonardo.net>
 #   Dietrich Ayala <dietrich@mozilla.com>
 #   Ehsan Akhgari <ehsan.akhgari@gmail.com>
 #   Nils Maier <maierman@web.de>
+#   Robert Strong <robert.bugzilla@gmail.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
@@ -212,16 +213,23 @@ BrowserGlue.prototype = {
         break;
       case "bookmarks-restore-success":
       case "bookmarks-restore-failed":
         this._observerService.removeObserver(this, "bookmarks-restore-success");
         this._observerService.removeObserver(this, "bookmarks-restore-failed");
         if (topic == "bookmarks-restore-success" && data == "html-initial")
           this.ensurePlacesDefaultQueriesInitialized();
         break;
+      case "browser-glue-test": // used by tests
+        if (data == "post-update-notification") {
+          if (this._prefs.prefHasUserValue("app.update.postupdate"))
+            this._showUpdateNotification();
+          break;
+        }
+        break;
     }
   }, 
 
   // initialization (called on application startup) 
   _init: function BG__init() {
     // observer registration
     const osvr = this._observerService;
     osvr.addObserver(this, "xpcom-shutdown", false);
@@ -334,16 +342,20 @@ BrowserGlue.prototype = {
   },
 
   // Browser startup complete. All initial windows have opened.
   _onBrowserStartup: function BG__onBrowserStartup() {
     // Show about:rights notification, if needed.
     if (this._shouldShowRights())
       this._showRightsNotification();
 
+    // Show update notification, if needed.
+    if (this._prefs.prefHasUserValue("app.update.postupdate"))
+      this._showUpdateNotification();
+
     // If new add-ons were installed during startup open the add-ons manager.
     if (this._prefs.prefHasUserValue(PREF_EM_NEW_ADDONS_LIST)) {
       var args = Cc["@mozilla.org/supports-array;1"].
                  createInstance(Ci.nsISupportsArray);
       var str = Cc["@mozilla.org/supports-string;1"].
                 createInstance(Ci.nsISupportsString);
       str.data = "";
       args.AppendElement(str);
@@ -571,17 +583,133 @@ BrowserGlue.prototype = {
 
     // Set pref to indicate we've shown the notification.
     var currentVersion = this._prefs.getIntPref("browser.rights.version");
     this._prefs.setBoolPref("browser.rights." + currentVersion + ".shown", true);
 
     var box = notifyBox.appendNotification(notifyRightsText, "about-rights", null, notifyBox.PRIORITY_INFO_LOW, buttons);
     box.persistence = 3; // arbitrary number, just so bar sticks around for a bit
   },
-  
+
+  _showUpdateNotification: function BG__showUpdateNotification() {
+    this._prefs.clearUserPref("app.update.postupdate");
+
+    var um = Cc["@mozilla.org/updates/update-manager;1"].
+             getService(Ci.nsIUpdateManager);
+    try {
+      // If the updates.xml file is deleted then getUpdateAt will throw.
+      var update = um.getUpdateAt(0).QueryInterface(Ci.nsIPropertyBag);
+    }
+    catch (e) {
+      // This should never happen.
+      Cu.reportError("Unable to find update: " + e);
+      return;
+    }
+
+    var actions = update.getProperty("actions");
+    if (!actions || actions.indexOf("silent") != -1)
+      return;
+
+    var formatter = Cc["@mozilla.org/toolkit/URLFormatterService;1"].
+                    getService(Ci.nsIURLFormatter);
+    var browserBundle = this._bundleService.
+                        createBundle("chrome://browser/locale/browser.properties");
+    var brandBundle = this._bundleService.
+                      createBundle("chrome://branding/locale/brand.properties");
+    var appName = brandBundle.GetStringFromName("brandShortName");
+
+    function getNotifyString(aPropData) {
+      var propValue = update.getProperty(aPropData.propName);
+      if (!propValue) {
+        if (aPropData.prefName)
+          propValue = formatter.formatURLPref(aPropData.prefName);
+        else if (aPropData.stringParams)
+          propValue = browserBundle.formatStringFromName(aPropData.stringName,
+                                                         aPropData.stringParams,
+                                                         aPropData.stringParams.length);
+        else
+          propValue = browserBundle.GetStringFromName(aPropData.stringName);
+      }
+      return propValue;
+    }
+
+    if (actions.indexOf("showNotification") != -1) {
+      let text = getNotifyString({propName: "notificationText",
+                                  stringName: "puNotifyText",
+                                  stringParams: [appName]});
+      let url = getNotifyString({propName: "notificationURL",
+                                 prefName: "startup.homepage_override_url"});
+      let label = getNotifyString({propName: "notificationButtonLabel",
+                                   stringName: "pu.notifyButton.label"});
+      let key = getNotifyString({propName: "notificationButtonAccessKey",
+                                 stringName: "pu.notifyButton.accesskey"});
+
+      let win = this.getMostRecentBrowserWindow();
+      let browser = win.gBrowser; // for closure in notification bar callback
+      let notifyBox = browser.getNotificationBox();
+
+      let buttons = [
+                      {
+                        label:     label,
+                        accessKey: key,
+                        popup:     null,
+                        callback: function(aNotificationBar, aButton) {
+                          browser.selectedTab = browser.addTab(url);
+                        }
+                      }
+                    ];
+
+      let box = notifyBox.appendNotification(text, "post-update-notification",
+                                             null, notifyBox.PRIORITY_INFO_LOW,
+                                             buttons);
+      box.persistence = 3;
+    }
+
+    if (actions.indexOf("showAlert") == -1)
+      return;
+
+    let notifier;
+    try {
+      notifier = Cc["@mozilla.org/alerts-service;1"].
+                 getService(Ci.nsIAlertsService);
+    }
+    catch (e) {
+      // nsIAlertsService is not available for this platform
+      return;
+    }
+
+    let title = getNotifyString({propName: "alertTitle",
+                                 stringName: "puAlertTitle",
+                                 stringParams: [appName]});
+    let text = getNotifyString({propName: "alertText",
+                                stringName: "puAlertText",
+                                stringParams: [appName]});
+    let url = getNotifyString({propName: "alertURL",
+                               prefName: "startup.homepage_override_url"});
+
+    var self = this;
+    function clickCallback(subject, topic, data) {
+      // This callback will be called twice but only once with this topic
+      if (topic != "alertclickcallback")
+        return;
+      let win = self.getMostRecentBrowserWindow();
+      let browser = win.gBrowser;
+      browser.selectedTab = browser.addTab(data);
+    }
+
+    try {
+      // This will throw NS_ERROR_NOT_AVAILABLE if the notification cannot
+      // be displayed per the idl.
+      notifier.showAlertNotification("post-update-notification", title, text,
+                                     true, url, clickCallback);
+    }
+    catch (e) {
+    }
+  },
+
   _showPluginUpdatePage: function BG__showPluginUpdatePage() {
     this._prefs.setBoolPref(PREF_PLUGINS_NOTIFYUSER, false);
 
     var formatter = Cc["@mozilla.org/toolkit/URLFormatterService;1"].
                     getService(Ci.nsIURLFormatter);
     var updateUrl = formatter.formatURLPref(PREF_PLUGINS_UPDATEURL);
 
     var win = this.getMostRecentBrowserWindow();
--- a/browser/components/places/content/treeView.js
+++ b/browser/components/places/content/treeView.js
@@ -142,17 +142,17 @@ PlacesTreeView.prototype = {
    * Gets the row number for a given node.  Assumes that the given node is
    * visible (i.e. it's not an obsolete node).
    *
    * @param aNode
    *        A result node.  Do not pass an obsolete node, or any
    *        node which isn't supposed to be in the tree (e.g. separators in
    *        sorted trees).
    * @param [optional] aForceBuild
-   *        @see isPlainContainer.
+   *        @see _isPlainContainer.
    *        If true, the row will be computed even if the node still isn't set
    *        in our rows array.
    * @param [optional] aParentRow
    *        The row of aNode's parent.
    *        DO NOT compute this yourself for the purpose of calling this
    *        function.  However, do pass it if you have it handy.
    *        Ignored for the root node.
    * @param [optional] aNodeIndex
@@ -250,18 +250,16 @@ PlacesTreeView.prototype = {
     // node is a container, it's the row's parent, otherwise, it's a sibling.
     if (rowNode instanceof Ci.nsINavHistoryContainerResultNode)
       return this._rows[aRow] = rowNode.getChild(aRow - row - 1);
 
     let [parent, parentRow] = this._getParentByChildRow(row);
     return this._rows[aRow] = parent.getChild(aRow - parentRow - 1);
   },
 
-  _rootNode: null,
-
   /**
    * This takes a container and recursively appends our rows array per its
    * contents.  Assumes that the rows arrays has no rows for the given
    * container.
    *
    * @param [in] aContainer
    *        A container result node.
    * @param [in] aFirstChildRow
@@ -279,78 +277,77 @@ PlacesTreeView.prototype = {
     if (!aContainer.containerOpen)
       return;
 
     // Inserting the new elements into the rows array in one shot (by
     // Array.concat) is faster than resizing the array (by splice) on each loop
     // iteration.
     let cc = aContainer.childCount;
     let newElements = new Array(cc);
-    this._rows =
-      this._rows.slice(0, aFirstChildRow).concat(newElements)
-          .concat(this._rows.slice(aFirstChildRow, this._rows.length));
+    this._rows = this._rows.splice(0, aFirstChildRow)
+                     .concat(newElements, this._rows);
 
     if (this._isPlainContainer(aContainer))
       return cc;
 
     const openLiteral = PlacesUIUtils.RDF.GetResource("http://home.netscape.com/NC-rdf#open");
     const trueLiteral = PlacesUIUtils.RDF.GetLiteral("true");
     let sortingMode = this._result.sortingMode;
 
-    let rowsInsertedCounter = 0;
+    let rowsInserted = 0;
     for (let i = 0; i < cc; i++) {
       let curChild = aContainer.getChild(i);
       let curChildType = curChild.type;
 
-      let row = aFirstChildRow + rowsInsertedCounter;
+      let row = aFirstChildRow + rowsInserted;
 
       // Don't display separators when sorted.
       if (curChildType == Ci.nsINavHistoryResultNode.RESULT_TYPE_SEPARATOR) {
         if (sortingMode != Ci.nsINavHistoryQueryOptions.SORT_BY_NONE) {
           // Remove the element for the filtered separator.
           // Notice that the rows array was initially resized to include all
           // children.
           this._rows.splice(row, 1);
           continue;
         }
       }
 
       this._rows[row] = curChild;
-      rowsInsertedCounter++;
+      rowsInserted++;
 
       // Recursively do containers.
       if (!this._flatList &&
           curChild instanceof Ci.nsINavHistoryContainerResultNode) {
         let resource = this._getResourceForNode(curChild);
         let isopen = resource != null &&
                      PlacesUIUtils.localStore.HasAssertion(resource,
                                                            openLiteral,
                                                            trueLiteral, true);
         if (isopen != curChild.containerOpen)
           aToOpen.push(curChild);
         else if (curChild.containerOpen && curChild.childCount > 0)
-          rowsAddedCounter += this._buildVisibleSection(curChild, aToOpen,
-                                                        row + 1);
+          rowsInserted += this._buildVisibleSection(curChild, aToOpen,
+                                                    row + 1);
       }
     }
 
-    return rowsInsertedCounter;
+    return rowsInserted;
   },
 
   /**
    * This counts how many rows a node takes in the tree.  For containers it
    * will count the node itself plus any child node following it.
    */
   _countVisibleRowsForNodeAtRow:
   function PTV__countVisibleRowsForNodeAtRow(aNodeRow) {
     let node = this._rows[aNodeRow];
 
-    // If it's not listed yet, we know that it's a leaf node.
-    if (node === undefined ||
-        !(node instanceof Ci.nsINavHistoryContainerResultNode))
+    // If it's not listed yet, we know that it's a leaf node (instanceof also
+    // null-checks).
+    if (!(node instanceof Ci.nsINavHistoryContainerResultNode))
       return 1;
 
     let outerLevel = node.indentLevel;
     for (let i = aNodeRow + 1; i < this._rows.length; i++) {
       let rowNode = this._rows[i];
       if (rowNode && rowNode.indentLevel <= outerLevel)
         return i - aNodeRow;
     }
@@ -410,22 +407,26 @@ PlacesTreeView.prototype = {
    * @return the row number of an equivalent node for aOldOne, if one was
    *         found, -1 otherwise.
    */
   _getNewRowForRemovedNode:
   function PTV__getNewRowForRemovedNode(aUpdatedContainer, aOldNode) {
     let parent = aOldNode.parent;
     if (parent) {
       // If the node's parent is still set, the node is not obsolete
-      // and we should just find out its new position.  However, if the node's
-      // parent is closed, the node is invisible.
-      if (parent.containerOpen)
-        return this._getRowForNode(aOldNode, true);
+      // and we should just find out its new position.
+      // However, if any of the node's ancestor is closed, the node is
+      // invisible.
+      let ancestors = PlacesUtils.nodeAncestors(aOldNode);
+      for (let ancestor in ancestors) {
+        if (!ancestor.containerOpen)
+          return -1;
+      }
 
-      return -1;
+      return this._getRowForNode(aOldNode, true);
     }
 
     // There's a broken edge case here.
     // If a visit appears in two queries, and the second one was
     // the old node, we'll select the first one after refresh.  There's
     // nothing we could do about that, because aOldNode.parent is
     // gone by the time invalidateContainer is called.
     let newNode = aUpdatedContainer.findNodeByDetails(aOldNode.uri,
@@ -467,17 +468,17 @@ PlacesTreeView.prototype = {
         selection.rangedSelect(row, row, true);
         if (nodeInfo.wasVisible && scrollToRow == -1)
           scrollToRow = row;
       }
     }
 
     // If only one node was previously selected and there's no selection now,
     // select the node at its old row, if any.
-    if (aNodesInfo.length == 1 && selection.getRangeCount() == 0) {
+    if (aNodesInfo.length == 1 && selection.count == 0) {
       let row = Math.min(aNodesInfo[0].oldRow, this._rows.length - 1);
       selection.rangedSelect(row, row, true);
       if (aNodesInfo[0].wasVisible && scrollToRow == -1)
         scrollToRow = aNodesInfo[0].oldRow;
     }
 
     if (scrollToRow != -1)
       this._tree.ensureRowIsVisible(scrollToRow);
@@ -1100,17 +1101,17 @@ PlacesTreeView.prototype = {
       aProperties.AppendElement(node._cellProperties[i]);
   },
 
   getColumnProperties: function(aColumn, aProperties) { },
 
   isContainer: function PTV_isContainer(aRow) {
     // Only leaf nodes aren't listed in the rows array.
     let node = this._rows[aRow];
-    if (!node)
+    if (node === undefined)
       return false;
 
     if (PlacesUtils.nodeIsContainer(node)) {
       // Flat-lists may ignore expandQueries and other query options when
       // they are asked to open a container.
       if (this._flatList)
         return true;
 
@@ -1563,12 +1564,13 @@ PlacesTreeView.prototype = {
   performActionOnRow: function(aAction, aRow) { },
   performActionOnCell: function(aAction, aRow, aColumn) { }
 };
 
 function PlacesTreeView(aFlatList, aOnOpenFlatContainer) {
   this._tree = null;
   this._result = null;
   this._selection = null;
+  this._rootNode = null;
   this._rows = [];
   this._flatList = aFlatList;
   this._openContainerCallback = aOnOpenFlatContainer;
 }
--- a/browser/components/places/tests/unit/head_bookmarks.js
+++ b/browser/components/places/tests/unit/head_bookmarks.js
@@ -32,321 +32,70 @@
  * 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 ***** */
 
-version(170);
-
-const NS_APP_USER_PROFILE_50_DIR = "ProfD";
-const NS_APP_PROFILE_DIR_STARTUP = "ProfDS";
-const NS_APP_BOOKMARKS_50_FILE = "BMarks";
+const Ci = Components.interfaces;
+const Cc = Components.classes;
+const Cr = Components.results;
+const Cu = Components.utils;
 
-var Ci = Components.interfaces;
-var Cc = Components.classes;
-var Cr = Components.results;
+Cu.import("resource://gre/modules/Services.jsm");
 
-function LOG(aMsg) {
-  aMsg = ("*** PLACES TESTS: " + aMsg);
-  Cc["@mozilla.org/consoleservice;1"].getService(Ci.nsIConsoleService).
-                                      logStringMessage(aMsg);
-  print(aMsg);
+// Import common head.
+let (commonFile = do_get_file("../../test_places/head_common.js", false)) {
+  let uri = Services.io.newFileURI(commonFile);
+  Services.scriptloader.loadSubScript(uri.spec, this);
 }
 
-var gProfD = do_get_profile();
-var dirSvc = Cc["@mozilla.org/file/directory_service;1"].
-             getService(Ci.nsIProperties);
+// Put any other stuff relative to this test folder below.
+
 
-var dirProvider = {
-  getFile: function(prop, persistent) {
-    persistent.value = true;
-    if (prop == NS_APP_BOOKMARKS_50_FILE) {
-      var bmarks = gProfD.clone();
-      bmarks.append("bookmarks.html");
-      return bmarks;
-    }
-    return null;
-  },
-  QueryInterface: function(iid) {
-    if (iid.equals(Ci.nsIDirectoryServiceProvider) ||
-        iid.equals(Ci.nsISupports)) {
-      return this;
-    }
-    throw Cr.NS_ERROR_NO_INTERFACE;
-  }
-};
-dirSvc.QueryInterface(Ci.nsIDirectoryService).registerProvider(dirProvider);
-
-var XULAppInfo = {
+// Needed by some test that relies on having an app  registered.
+let (XULAppInfo = {
   vendor: "Mozilla",
   name: "PlacesTest",
   ID: "{230de50e-4cd1-11dc-8314-0800200c9a66}",
   version: "1",
   appBuildID: "2007010101",
   platformVersion: "",
   platformBuildID: "2007010101",
   inSafeMode: false,
   logConsoleErrors: true,
   OS: "XPCShell",
   XPCOMABI: "noarch-spidermonkey",
 
-  QueryInterface: function QueryInterface(iid) {
-    if (iid.equals(Ci.nsIXULAppInfo) ||
-        iid.equals(Ci.nsIXULRuntime) ||
-        iid.equals(Ci.nsISupports))
-      return this;
-    throw Cr.NS_ERROR_NO_INTERFACE;
-  }
-};
-
-var XULAppInfoFactory = {
-  createInstance: function (outer, iid) {
-    if (outer != null)
-      throw Cr.NS_ERROR_NO_AGGREGATION;
-    return XULAppInfo.QueryInterface(iid);
-  }
-};
-
-var registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
-registrar.registerFactory(Components.ID("{fbfae60b-64a4-44ef-a911-08ceb70b9f31}"),
-                          "XULAppInfo", "@mozilla.org/xre/app-info;1",
-                          XULAppInfoFactory);
-
-var iosvc = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
-
-function uri(spec) {
-  return iosvc.newURI(spec, null, null);
+  QueryInterface: XPCOMUtils.generateQI([
+    Ci.nsIXULAppInfo,
+    Ci.nsIXULRuntime,
+  ])
+}) {
+  let XULAppInfoFactory = {
+    createInstance: function (outer, iid) {
+      if (outer != null)
+        throw Cr.NS_ERROR_NO_AGGREGATION;
+      return XULAppInfo.QueryInterface(iid);
+    }
+  };
+  let registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
+  registrar.registerFactory(Components.ID("{fbfae60b-64a4-44ef-a911-08ceb70b9f31}"),
+                            "XULAppInfo", "@mozilla.org/xre/app-info;1",
+                            XULAppInfoFactory);
 }
 
-/*
- * Removes all bookmarks and checks for correct cleanup
- */
-function remove_all_bookmarks() {
-  var bs = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
-           getService(Ci.nsINavBookmarksService);
-  // Clear all bookmarks.
-  bs.removeFolderChildren(bs.bookmarksMenuFolder);
-  bs.removeFolderChildren(bs.toolbarFolder);
-  bs.removeFolderChildren(bs.unfiledBookmarksFolder);
 
-  // Check for correct cleanup.
-  dump_table("moz_bookmarks");
-  dump_table("moz_places");
-  check_no_bookmarks()
+const FILENAME_BOOKMARKS_HTML = "bookmarks.html";
+let (backup_date = new Date().toLocaleFormat("%Y-%m-%d")) {
+  const FILENAME_BOOKMARKS_JSON = "bookmarks-" + backup_date + ".json";
 }
 
-/*
- * Checks that we don't have any bookmark
- */
-function check_no_bookmarks() {
-  var hs = Cc["@mozilla.org/browser/nav-history-service;1"].
-           getService(Ci.nsINavHistoryService);
-  var bs = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
-           getService(Ci.nsINavBookmarksService);
-  var query = hs.getNewQuery();
-  query.setFolders([bs.toolbarFolder, bs.bookmarksMenuFolder, bs.unfiledBookmarksFolder], 3);
-  var options = hs.getNewQueryOptions();
-  options.queryType = Ci.nsINavHistoryQueryOptions.QUERY_TYPE_BOOKMARKS;
-  var result = hs.executeQuery(query, options);
-  var root = result.root;
-  root.containerOpen = true;
-  var cc = root.childCount;
-  // Dump contents if found.
-  for (var i = 0; i < cc ; i++) {
-    var node = root.getChild(i);
-    print("Found unexpected child at " + i + ": " + node.title);
-  }
-  do_check_eq(cc, 0);
-  root.containerOpen = false;
-}
-
-let gTestDir = do_get_cwd();
-const FILENAME_BOOKMARKS_HTML = "bookmarks.html";
-let backup_date = new Date().toLocaleFormat("%Y-%m-%d");
-const FILENAME_BOOKMARKS_JSON = "bookmarks-" + backup_date + ".json";
-
 // Smart bookmarks constants.
 const SMART_BOOKMARKS_VERSION = 2;
 const SMART_BOOKMARKS_ON_TOOLBAR = 1;
 const SMART_BOOKMARKS_ON_MENU = 3; // Takes in count the additional separator.
 
 // Default bookmarks constants.
 const DEFAULT_BOOKMARKS_ON_TOOLBAR = 2;
 const DEFAULT_BOOKMARKS_ON_MENU = 3;
-
-/**
- * Creates a bookmarks.html file in the profile folder from a given source file.
- *
- * @param aFilename
- *        Name of the file to copy to the profile folder.  This file must
- *        exist in the directory that contains the test files.
- *
- * @return nsIFile object for the file.
- */
-function create_bookmarks_html(aFilename) {
-  if (!aFilename)
-    do_throw("you must pass a filename to create_bookmarks_html function");
-  remove_bookmarks_html();
-  let bookmarksHTMLFile = gTestDir.clone();
-  bookmarksHTMLFile.append(aFilename);
-  do_check_true(bookmarksHTMLFile.exists());
-  bookmarksHTMLFile.copyTo(gProfD, FILENAME_BOOKMARKS_HTML);
-  let profileBookmarksHTMLFile = gProfD.clone();
-  profileBookmarksHTMLFile.append(FILENAME_BOOKMARKS_HTML);
-  do_check_true(profileBookmarksHTMLFile.exists());
-  return profileBookmarksHTMLFile;
-}
-
-/**
- * Remove bookmarks.html file from the profile folder.
- */
-function remove_bookmarks_html() {
-  let profileBookmarksHTMLFile = gProfD.clone();
-  profileBookmarksHTMLFile.append(FILENAME_BOOKMARKS_HTML);
-  if (profileBookmarksHTMLFile.exists()) {
-    profileBookmarksHTMLFile.remove(false);
-    do_check_false(profileBookmarksHTMLFile.exists());
-  }
-}
-
-/**
- * Check bookmarks.html file exists in the profile folder.
- *
- * @return nsIFile object for the file.
- */
-function check_bookmarks_html() {
-  let profileBookmarksHTMLFile = gProfD.clone();
-  profileBookmarksHTMLFile.append(FILENAME_BOOKMARKS_HTML);
-  do_check_true(profileBookmarksHTMLFile.exists());
-  return profileBookmarksHTMLFile;
-}
-
-/**
- * Creates a JSON backup in the profile folder folder from a given source file.
- *
- * @param aFilename
- *        Name of the file to copy to the profile folder.  This file must
- *        exist in the directory that contains the test files.
- *
- * @return nsIFile object for the file.
- */
-function create_JSON_backup(aFilename) {
-  if (!aFilename)
-    do_throw("you must pass a filename to create_JSON_backup function");
-  remove_all_JSON_backups();
-  let bookmarksBackupDir = gProfD.clone();
-  bookmarksBackupDir.append("bookmarkbackups");
-  if (!bookmarksBackupDir.exists()) {
-    bookmarksBackupDir.create(Ci.nsIFile.DIRECTORY_TYPE, 0777);
-    do_check_true(bookmarksBackupDir.exists());
-  }
-  let bookmarksJSONFile = gTestDir.clone();
-  bookmarksJSONFile.append(aFilename);
-  do_check_true(bookmarksJSONFile.exists());
-  bookmarksJSONFile.copyTo(bookmarksBackupDir, FILENAME_BOOKMARKS_JSON);
-  let profileBookmarksJSONFile = bookmarksBackupDir.clone();
-  profileBookmarksJSONFile.append(FILENAME_BOOKMARKS_JSON);
-  do_check_true(profileBookmarksJSONFile.exists());
-  return profileBookmarksJSONFile;
-}
-
-/**
- * Remove bookmarksbackup dir and all backups from the profile folder.
- */
-function remove_all_JSON_backups() {
-  let bookmarksBackupDir = gProfD.clone();
-  bookmarksBackupDir.append("bookmarkbackups");
-  if (bookmarksBackupDir.exists()) {
-    bookmarksBackupDir.remove(true);
-    do_check_false(bookmarksBackupDir.exists());
-  }
-}
-
-/**
- * Check a JSON backup file for today exists in the profile folder.
- *
- * @return nsIFile object for the file.
- */
-function check_JSON_backup() {
-  let profileBookmarksJSONFile = gProfD.clone();
-  profileBookmarksJSONFile.append("bookmarkbackups");
-  profileBookmarksJSONFile.append(FILENAME_BOOKMARKS_JSON);
-  do_check_true(profileBookmarksJSONFile.exists());
-  return profileBookmarksJSONFile;
-}
-
-/**
- * Dumps the rows of a table out to the console.
- *
- * @param aName
- *        The name of the table or view to output.
- */
-function dump_table(aName)
-{
-  let db = Cc["@mozilla.org/browser/nav-history-service;1"].
-           getService(Ci.nsPIPlacesDatabase).
-           DBConnection;
-  let stmt = db.createStatement("SELECT * FROM " + aName);
-
-  dump("\n*** Printing data from " + aName + ":\n");
-  let count = 0;
-  while (stmt.executeStep()) {
-    let columns = stmt.numEntries;
-
-    if (count == 0) {
-      // print the column names
-      for (let i = 0; i < columns; i++)
-        dump(stmt.getColumnName(i) + "\t");
-      dump("\n");
-    }
-
-    // print the row
-    for (let i = 0; i < columns; i++) {
-      switch (stmt.getTypeOfIndex(i)) {
-        case Ci.mozIStorageValueArray.VALUE_TYPE_NULL:
-          dump("NULL\t");
-          break;
-        case Ci.mozIStorageValueArray.VALUE_TYPE_INTEGER:
-          dump(stmt.getInt64(i) + "\t");
-          break;
-        case Ci.mozIStorageValueArray.VALUE_TYPE_FLOAT:
-          dump(stmt.getDouble(i) + "\t");
-          break;
-        case Ci.mozIStorageValueArray.VALUE_TYPE_TEXT:
-          dump(stmt.getString(i) + "\t");
-          break;
-      }
-    }
-    dump("\n");
-
-    count++;
-  }
-  dump("*** There were a total of " + count + " rows of data.\n\n");
-
-  stmt.reset();
-  stmt.finalize();
-  stmt = null;
-}
-
-/**
- * Flushes any events in the event loop of the main thread.
- */
-function flush_main_thread_events()
-{
-  let tm = Cc["@mozilla.org/thread-manager;1"].getService(Ci.nsIThreadManager);
-  while (tm.mainThread.hasPendingEvents())
-    tm.mainThread.processNextEvent(false);
-}
-
-// These tests are known to randomly fail due to bug 507790 when database
-// flushes are active, so we turn off syncing for them.
-let randomFailingSyncTests = [
-  "test_browserGlue_smartBookmarks.js",
-];
-let currentTestFilename = do_get_file(_TEST_FILE[0], true).leafName;
-if (randomFailingSyncTests.indexOf(currentTestFilename) != -1) {
-  print("Test " + currentTestFilename + " is known random due to bug 507790, disabling PlacesDBFlush component.");
-  let sync = Cc["@mozilla.org/places/sync;1"].getService(Ci.nsIObserver);
-  sync.observe(null, "places-debug-stop-sync", null);
-}
--- a/browser/components/places/tests/unit/test_384370.js
+++ b/browser/components/places/tests/unit/test_384370.js
@@ -68,17 +68,17 @@ function run_test() {
   // avoid creating the places smart folder during tests
   Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch).
   setIntPref("browser.places.smartBookmarksVersion", -1);
 
   // file pointer to legacy bookmarks file
   //var bookmarksFileOld = do_get_file("bookmarks.large.html");
   var bookmarksFileOld = do_get_file("bookmarks.preplaces.html");
   // file pointer to a new places-exported json file
-  var jsonFile = dirSvc.get("ProfD", Ci.nsILocalFile);
+  var jsonFile = Services.dirsvc.get("ProfD", Ci.nsILocalFile);
   jsonFile.append("bookmarks.exported.json");
 
   // create bookmarks.exported.json
   if (jsonFile.exists())
     jsonFile.remove(false);
   jsonFile.create(Ci.nsILocalFile.NORMAL_FILE_TYPE, 0600);
   if (!jsonFile.exists())
     do_throw("couldn't create file: bookmarks.exported.json");
--- a/browser/components/places/tests/unit/test_457441-import-export-corrupt-bookmarks-html.js
+++ b/browser/components/places/tests/unit/test_457441-import-export-corrupt-bookmarks-html.js
@@ -85,17 +85,17 @@ function run_test() {
                                         uri("http://test.mozilla.org"),
                                         bs.DEFAULT_INDEX, "We love belugas");
   var stmt = dbConn.createStatement("UPDATE moz_bookmarks SET fk = NULL WHERE id = :itemId");
   stmt.params.itemId = corruptItemId;
   stmt.execute();
   stmt.finalize();
 
   // Export bookmarks
-  var bookmarksFile = dirSvc.get("ProfD", Ci.nsILocalFile);
+  var bookmarksFile = Services.dirsvc.get("ProfD", Ci.nsILocalFile);
   bookmarksFile.append("bookmarks.exported.html");
   if (bookmarksFile.exists())
     bookmarksFile.remove(false);
   bookmarksFile.create(Ci.nsILocalFile.NORMAL_FILE_TYPE, 0600);
   if (!bookmarksFile.exists())
     do_throw("couldn't create file: bookmarks.exported.html");
   try {
     ies.exportHTMLToFile(bookmarksFile);
--- a/browser/components/places/tests/unit/test_bookmarksRestoreNotification.js
+++ b/browser/components/places/tests/unit/test_bookmarksRestoreNotification.js
@@ -110,17 +110,17 @@ var tests = [
 
   {
     desc:       "JSON restore: nonexisting file should fail",
     currTopic:  NSIOBSERVER_TOPIC_BEGIN,
     finalTopic: NSIOBSERVER_TOPIC_FAILED,
     data:       NSIOBSERVER_DATA_JSON,
     folderId:   null,
     run:        function () {
-      this.file = dirSvc.get("ProfD", Ci.nsILocalFile);
+      this.file = Services.dirsvc.get("ProfD", Ci.nsILocalFile);
       this.file.append("this file doesn't exist because nobody created it");
       try {
         PlacesUtils.restoreBookmarksFromJSONFile(this.file);
         do_throw("  Restore should have failed");
       }
       catch (e) {}
     }
   },
@@ -164,17 +164,17 @@ var tests = [
 
   {
     desc:       "HTML restore: nonexisting file should fail",
     currTopic:  NSIOBSERVER_TOPIC_BEGIN,
     finalTopic: NSIOBSERVER_TOPIC_FAILED,
     data:       NSIOBSERVER_DATA_HTML,
     folderId:   null,
     run:        function () {
-      this.file = dirSvc.get("ProfD", Ci.nsILocalFile);
+      this.file = Services.dirsvc.get("ProfD", Ci.nsILocalFile);
       this.file.append("this file doesn't exist because nobody created it");
       try {
         importer.importHTMLFromFile(this.file, false);
         do_throw("  Restore should have failed");
       }
       catch (e) {}
     }
   },
@@ -218,17 +218,17 @@ var tests = [
 
   {
     desc:       "HTML initial restore: nonexisting file should fail",
     currTopic:  NSIOBSERVER_TOPIC_BEGIN,
     finalTopic: NSIOBSERVER_TOPIC_FAILED,
     data:       NSIOBSERVER_DATA_HTML_INIT,
     folderId:   null,
     run:        function () {
-      this.file = dirSvc.get("ProfD", Ci.nsILocalFile);
+      this.file = Services.dirsvc.get("ProfD", Ci.nsILocalFile);
       this.file.append("this file doesn't exist because nobody created it");
       try {
         importer.importHTMLFromFile(this.file, true);
         do_throw("  Restore should have failed");
       }
       catch (e) {}
     }
   },
@@ -279,17 +279,17 @@ var tests = [
   },
 
   {
     desc:       "HTML restore into folder: nonexisting file should fail",
     currTopic:  NSIOBSERVER_TOPIC_BEGIN,
     finalTopic: NSIOBSERVER_TOPIC_FAILED,
     data:       NSIOBSERVER_DATA_HTML,
     run:        function () {
-      this.file = dirSvc.get("ProfD", Ci.nsILocalFile);
+      this.file = Services.dirsvc.get("ProfD", Ci.nsILocalFile);
       this.file.append("this file doesn't exist because nobody created it");
       this.folderId = bmsvc.createFolder(bmsvc.unfiledBookmarksFolder,
                                          "test folder",
                                          bmsvc.DEFAULT_INDEX);
       print("  Sanity check: createFolder() should have succeeded");
       do_check_true(this.folderId > 0);
       try {
         importer.importHTMLFromFileToFolder(this.file, this.folderId, false);
@@ -402,17 +402,17 @@ function checkBookmarksExist() {
 /**
  * Creates an nsILocalFile in the profile directory.
  *
  * @param  aBasename
  *         e.g., "foo.txt" in the path /some/long/path/foo.txt
  * @return The nsILocalFile
  */
 function createFile(aBasename) {
-  var file = dirSvc.get("ProfD", Ci.nsILocalFile);
+  var file = Services.dirsvc.get("ProfD", Ci.nsILocalFile);
   file.append(aBasename);
   if (file.exists())
     file.remove(false);
   file.create(file.NORMAL_FILE_TYPE, 0666);
   if (!file.exists())
     do_throw("Couldn't create file: " + aBasename);
   return file;
 }
--- a/browser/components/places/tests/unit/test_bookmarks_html.js
+++ b/browser/components/places/tests/unit/test_bookmarks_html.js
@@ -99,17 +99,17 @@ function run_test() {
 
   // avoid creating the places smart folder during tests
   Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch).
   setIntPref("browser.places.smartBookmarksVersion", -1);
 
   // file pointer to legacy bookmarks file
   var bookmarksFileOld = do_get_file("bookmarks.preplaces.html");
   // file pointer to a new places-exported bookmarks file
-  var bookmarksFileNew = dirSvc.get("ProfD", Ci.nsILocalFile);
+  var bookmarksFileNew = Services.dirsvc.get("ProfD", Ci.nsILocalFile);
   bookmarksFileNew.append("bookmarks.exported.html");
 
   // create bookmarks.exported.html
   if (bookmarksFileNew.exists())
     bookmarksFileNew.remove(false);
   bookmarksFileNew.create(Ci.nsILocalFile.NORMAL_FILE_TYPE, 0600);
   if (!bookmarksFileNew.exists())
     do_throw("couldn't create file: bookmarks.exported.html");
--- a/browser/components/places/tests/unit/test_browserGlue_distribution.js
+++ b/browser/components/places/tests/unit/test_browserGlue_distribution.js
@@ -42,24 +42,23 @@
  * bookmark on init, we should not try to import.
  */
 
 const PREF_SMART_BOOKMARKS_VERSION = "browser.places.smartBookmarksVersion";
 const PREF_BMPROCESSED = "distribution.516444.bookmarksProcessed";
 const PREF_DISTRIBUTION_ID = "distribution.id";
 
 const TOPIC_FINAL_UI_STARTUP = "final-ui-startup";
-const TOPIC_PLACES_INIT_COMPLETE = "places-init-complete";
 const TOPIC_CUSTOMIZATION_COMPLETE = "distribution-customization-complete";
 
 function run_test() {
   do_test_pending();
 
   // Copy distribution.ini file to our app dir.
-  let distroDir = dirSvc.get("XCurProcD", Ci.nsIFile);
+  let distroDir = Services.dirsvc.get("XCurProcD", Ci.nsIFile);
   distroDir.append("distribution");
   let iniFile = distroDir.clone();
   iniFile.append("distribution.ini");
   if (iniFile.exists()) {
     iniFile.remove(false);
     print("distribution.ini already exists, did some test forget to cleanup?");
   }
 
@@ -92,23 +91,23 @@ function run_test() {
     observe: function(aSubject, aTopic, aData) {
       os.removeObserver(this, TOPIC_PLACES_INIT_COMPLETE);
 
       // Simulate browser startup.
       bg.QueryInterface(Ci.nsIObserver).observe(null,
                                                 TOPIC_FINAL_UI_STARTUP,
                                                 null);
       // Test will continue on customization complete notification.
-      let observer = {
+      let cObserver = {
         observe: function(aSubject, aTopic, aData) {
           os.removeObserver(this, TOPIC_CUSTOMIZATION_COMPLETE);
-          continue_test();
+          do_execute_soon(continue_test);
         }
       }
-      os.addObserver(observer, TOPIC_CUSTOMIZATION_COMPLETE, false);
+      os.addObserver(cObserver, TOPIC_CUSTOMIZATION_COMPLETE, false);
     }
   }
   os.addObserver(observer, TOPIC_PLACES_INIT_COMPLETE, false);
 }
 
 function continue_test() {
   let bs = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
            getService(Ci.nsINavBookmarksService);
@@ -140,14 +139,14 @@ function continue_test() {
   do_check_eq(ps.getCharPref(PREF_DISTRIBUTION_ID), "516444");
 
   do_test_finished();
 }
 
 do_register_cleanup(function() {
   // Remove the distribution file, even if the test failed, otherwise all
   // next tests will import it.
-  let iniFile = dirSvc.get("XCurProcD", Ci.nsIFile);
+  let iniFile = Services.dirsvc.get("XCurProcD", Ci.nsIFile);
   iniFile.append("distribution");
   iniFile.append("distribution.ini");
   iniFile.remove(false);
   do_check_false(iniFile.exists());
 });
--- a/browser/components/places/tests/unit/test_browserGlue_prefs.js
+++ b/browser/components/places/tests/unit/test_browserGlue_prefs.js
@@ -58,18 +58,17 @@ let ps = Cc["@mozilla.org/preferences-se
          getService(Ci.nsIPrefBranch);
 let os = Cc["@mozilla.org/observer-service;1"].
          getService(Ci.nsIObserverService);
 
 const PREF_IMPORT_BOOKMARKS_HTML = "browser.places.importBookmarksHTML";
 const PREF_RESTORE_DEFAULT_BOOKMARKS = "browser.bookmarks.restore_default_bookmarks";
 const PREF_SMART_BOOKMARKS_VERSION = "browser.places.smartBookmarksVersion";
 const PREF_AUTO_EXPORT_HTML = "browser.bookmarks.autoExportHTML";
-const TOPIC_PLACES_INIT_COMPLETE = "places-init-complete";
-const TOPIC_PLACES_DATABASE_LOCKED = "places-database-locked";
+
 let tests = [];
 //------------------------------------------------------------------------------
 
 tests.push({
   description: "Import from bookmarks.html if importBookmarksHTML is true.",
   exec: function() {
     // Sanity check: we should not have any bookmark on the toolbar.
     do_check_eq(bs.getIdForItemAt(bs.toolbarFolder, 0), -1);
--- a/browser/components/places/tests/unit/test_leftpane_corruption_handling.js
+++ b/browser/components/places/tests/unit/test_leftpane_corruption_handling.js
@@ -197,17 +197,18 @@ function compareJSON(aNodeJSON_1, aNodeJ
   let JSON = Cc["@mozilla.org/dom/json;1"].createInstance(Ci.nsIJSON);
   node1 = JSON.decode(aNodeJSON_1);
   node2 = JSON.decode(aNodeJSON_2);
 
   // List of properties we should not compare (expected to be different).
   const SKIP_PROPS = ["dateAdded", "lastModified", "id"];
 
   function compareObjects(obj1, obj2) {
-    do_check_eq(obj1.__count__, obj2.__count__);
+    function count(o) { var n = 0; for (let p in o) n++; return n; }
+    do_check_eq(count(obj1), count(obj2));
     for (let prop in obj1) {
       // Skip everchanging values.
       if (SKIP_PROPS.indexOf(prop) != -1)
         continue;
       // Skip undefined objects, otherwise we hang on them.
       if (!obj1[prop])
         continue;
       if (typeof(obj1[prop]) == "object")
--- a/browser/components/preferences/tests/browser_bug410900.js
+++ b/browser/components/preferences/tests/browser_bug410900.js
@@ -11,27 +11,24 @@ function test() {
               getService(Ci.nsIExternalProtocolService);
   var info = extps.getProtocolHandlerInfo("apppanetest");
   info.possibleApplicationHandlers.appendElement(handler, false);
 
   var hserv = Cc["@mozilla.org/uriloader/handler-service;1"].
               getService(Ci.nsIHandlerService);
   hserv.store(info);
 
-  var obs = Cc["@mozilla.org/observer-service;1"].
-            getService(Ci.nsIObserverService);
-
   function observer(win, topic, data) {
     if (topic != "app-handler-pane-loaded")
       return;
 
-    obs.removeObserver(observer, "app-handler-pane-loaded");
+    Services.obs.removeObserver(observer, "app-handler-pane-loaded");
     runTest(win);
   }
-  obs.addObserver(observer, "app-handler-pane-loaded", false);
+  Services.obs.addObserver(observer, "app-handler-pane-loaded", false);
 
   openDialog("chrome://browser/content/preferences/preferences.xul", "Preferences",
              "chrome,titlebar,toolbar,centerscreen,dialog=no", "paneApplications");
 }
 
 function runTest(win) {
   var sel = win.document.documentElement.getAttribute("lastSelected");
   ok(sel == "paneApplications", "Specified pane was opened");
--- a/browser/components/preferences/tests/privacypane_tests.js
+++ b/browser/components/preferences/tests/privacypane_tests.js
@@ -31,38 +31,36 @@
  * 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 ***** */
 
 function runTestOnPrivacyPrefPane(testFunc) {
-  let ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
-           getService(Ci.nsIWindowWatcher);
   let observer = {
     observe: function(aSubject, aTopic, aData) {
       if (aTopic == "domwindowopened") {
-        ww.unregisterNotification(this);
+        Services.ww.unregisterNotification(this);
 
         let win = aSubject.QueryInterface(Ci.nsIDOMEventTarget);
         win.addEventListener("load", function() {
           win.removeEventListener("load", arguments.callee, false);
           testFunc(dialog.document.defaultView);
 
-          ww.registerNotification(observer);
+          Services.ww.registerNotification(observer);
           dialog.close();
         }, false);
       } else if (aTopic == "domwindowclosed") {
-        ww.unregisterNotification(this);
+        Services.ww.unregisterNotification(this);
         testRunner.runNext();
       }
     }
   };
-  ww.registerNotification(observer);
+  Services.ww.registerNotification(observer);
 
   let dialog = openDialog("chrome://browser/content/preferences/preferences.xul", "Preferences",
                           "chrome,titlebar,toolbar,centerscreen,dialog=no", "panePrivacy");
 }
 
 function controlChanged(element) {
   element.doCommand();
 }
@@ -523,30 +521,28 @@ function reset_preferences(win) {
   let prefs = win.document.getElementsByTagName("preference");
   for (let i = 0; i < prefs.length; ++i)
     if (prefs[i].hasUserValue)
       prefs[i].reset();
 }
 
 let testRunner;
 function run_test_subset(subset) {
-  let psvc = Cc["@mozilla.org/preferences-service;1"].
-             getService(Ci.nsIPrefBranch);
-  let instantApplyOrig = psvc.getBoolPref("browser.preferences.instantApply");
-  psvc.setBoolPref("browser.preferences.instantApply", true);
+  let instantApplyOrig = Services.prefs.getBoolPref("browser.preferences.instantApply");
+  Services.prefs.setBoolPref("browser.preferences.instantApply", true);
 
   waitForExplicitFinish();
 
   testRunner = {
     tests: subset,
     counter: 0,
     runNext: function() {
       if (this.counter == this.tests.length) {
         // cleanup
-        psvc.setBoolPref("browser.preferences.instantApply", instantApplyOrig);
+        Services.prefs.setBoolPref("browser.preferences.instantApply", instantApplyOrig);
         finish();
       } else {
         let self = this;
         setTimeout(function() {
           runTestOnPrivacyPrefPane(self.tests[self.counter++]);
         }, 0);
       }
     }
--- a/browser/components/privatebrowsing/test/browser/Makefile.in
+++ b/browser/components/privatebrowsing/test/browser/Makefile.in
@@ -67,16 +67,17 @@ include $(topsrcdir)/config/rules.mk
 		browser_privatebrowsing_protocolhandler.js \
 		browser_privatebrowsing_protocolhandler_page.html \
 		browser_privatebrowsing_searchbar.js \
 		browser_privatebrowsing_sslsite_transition.js \
 		browser_privatebrowsing_theming.js \
 		browser_privatebrowsing_transition.js \
 		browser_privatebrowsing_ui.js \
 		browser_privatebrowsing_urlbarfocus.js \
+		browser_privatebrowsing_urlbarundo.js \
 		browser_privatebrowsing_viewsource.js \
 		browser_privatebrowsing_windowtitle.js \
 		browser_privatebrowsing_windowtitle_page.html \
 		browser_privatebrowsing_zoom.js \
 		browser_privatebrowsing_zoomrestore.js \
 		ctxmenu.html \
 		ctxmenu-image.png \
 		popup.html \
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_beforeunload.js
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_beforeunload.js
@@ -52,19 +52,17 @@ function test() {
     let dialogWin = aSubject.QueryInterface(Ci.nsIDOMWindow);
     confirmCalls++;
     if (acceptDialog-- > 0)
       dialogWin.document.documentElement.getButton("accept").click();
     else if (rejectDialog-- > 0)
       dialogWin.document.documentElement.getButton("cancel").click();
   }
 
-  Cc["@mozilla.org/observer-service;1"]
-    .getService(Ci.nsIObserverService)
-    .addObserver(promptObserver, "common-dialog-loaded", false);
+  Services.obs.addObserver(promptObserver, "common-dialog-loaded", false);
 
   waitForExplicitFinish();
   let browser1 = gBrowser.getBrowserForTab(gBrowser.addTab());
   browser1.addEventListener("load", function() {
     browser1.removeEventListener("load", arguments.callee, true);
 
     let browser2 = gBrowser.getBrowserForTab(gBrowser.addTab());
     browser2.addEventListener("load", function() {
@@ -145,19 +143,17 @@ function test() {
                  "The last tab should be the same one we opened");
               is(acceptDialog, 0, "Two confirm dialogs should have been accepted");
               is(acceptDialog, 0, "Two prompts should have been raised");
 
               acceptDialog = 2;
               gBrowser.removeTab(gBrowser.tabContainer.lastChild);
               gBrowser.removeTab(gBrowser.tabContainer.lastChild);
 
-              Cc["@mozilla.org/observer-service;1"]
-                .getService(Ci.nsIObserverService)
-                .removeObserver(promptObserver, "common-dialog-loaded", false);
+              Services.obs.removeObserver(promptObserver, "common-dialog-loaded", false);
               finish();
             }
             for (let i = 0; i < gBrowser.browsers.length; ++i)
               gBrowser.browsers[i].addEventListener("load", waitForLoad, true);
           }, true);
           gBrowser.selectedBrowser.loadURI(TEST_PAGE_2);
         }, true);
         gBrowser.selectedBrowser.loadURI(TEST_PAGE_1);
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_certexceptionsui.js
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_certexceptionsui.js
@@ -58,20 +58,18 @@ function test() {
   function step1() {
     let params = {
       exceptionAdded : false,
       location: INVALID_CERT_LOCATION,
       handlePrivateBrowsing : true,
       prefetchCert: true,
     };
     function testCheckbox() {
-      let obsSvc = Cc["@mozilla.org/observer-service;1"].
-                   getService(Ci.nsIObserverService);
-      obsSvc.addObserver(function (aSubject, aTopic, aData) {
-        obsSvc.removeObserver(arguments.callee, "cert-exception-ui-ready", false);
+      Services.obs.addObserver(function (aSubject, aTopic, aData) {
+        Services.obs.removeObserver(arguments.callee, "cert-exception-ui-ready", false);
         ok(win.gCert, "The certificate information should be available now");
 
         let checkbox = win.document.getElementById("permanent");
         ok(checkbox.hasAttribute("disabled"),
           "the permanent checkbox should be disabled when handling the private browsing mode");
         ok(!checkbox.hasAttribute("checked"),
           "the permanent checkbox should not be checked when handling the private browsing mode");
         win.close();
@@ -85,20 +83,18 @@ function test() {
   // Test the certificate excetions dialog as it is invoked from the Preferences dialog
   function step2() {
     let params = {
       exceptionAdded : false,
       location: INVALID_CERT_LOCATION,
       prefetchCert: true,
     };
     function testCheckbox() {
-      let obsSvc = Cc["@mozilla.org/observer-service;1"].
-                   getService(Ci.nsIObserverService);
-      obsSvc.addObserver(function (aSubject, aTopic, aData) {
-        obsSvc.removeObserver(arguments.callee, "cert-exception-ui-ready", false);
+      Services.obs.addObserver(function (aSubject, aTopic, aData) {
+        Services.obs.removeObserver(arguments.callee, "cert-exception-ui-ready", false);
         ok(win.gCert, "The certificate information should be available now");
 
         let checkbox = win.document.getElementById("permanent");
         ok(!checkbox.hasAttribute("disabled"),
           "the permanent checkbox should not be disabled when not handling the private browsing mode");
         ok(checkbox.hasAttribute("checked"),
           "the permanent checkbox should be checked when not handling the private browsing mode");
         win.close();
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_commandline_toggle.js
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_commandline_toggle.js
@@ -37,18 +37,16 @@
 
 // This test makes sure that private browsing toggles correctly via the -private
 // command line argument.
 
 function test() {
   // initialization
   let pb = Cc["@mozilla.org/privatebrowsing;1"].
            getService(Ci.nsIPrivateBrowsingService);
-  let ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
-           getService(Ci.nsIWindowWatcher);
 
   waitForExplicitFinish();
 
   function simulatePrivateCommandLineArgument() {
     function testprivatecl() {
     }
 
     testprivatecl.prototype = {
@@ -115,17 +113,17 @@ function test() {
       let handler = Cc[contractID].getService(Ci.nsICommandLineHandler);
       handler.handle(testcl);
     }
   }
 
   function observer(aSubject, aTopic, aData) {
     isnot(aTopic, "domwindowopened", "The -private-toggle argument should be silent");
   }
-  ww.registerNotification(observer);
+  Services.ww.registerNotification(observer);
 
   let tab = gBrowser.selectedTab;
   let browser = gBrowser.getBrowserForTab(tab);
   browser.addEventListener("load", function () {
     browser.removeEventListener("load", arguments.callee, true);
     ok(!pb.privateBrowsingEnabled, "The private browsing mode should not be started");
     is(browser.contentWindow.location, "about:", "The correct page has been loaded");
 
@@ -144,15 +142,15 @@ function test() {
       browser.addEventListener("load", function() {
         browser.removeEventListener("load", arguments.callee, true);
         ok(!pb.privateBrowsingEnabled, "The private browsing mode should be stopped");
         is(browser.contentWindow.location, "about:",
            "about: should now be loaded");
 
         let newTab = gBrowser.addTab();
         gBrowser.removeTab(tab);
-        ww.unregisterNotification(observer);
+        Services.ww.unregisterNotification(observer);
         finish();
       }, true);
     }, true);
   }, true);
   browser.loadURI("about:");
 }
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_cookieacceptdialog.js
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_cookieacceptdialog.js
@@ -37,29 +37,27 @@
 
 // This test makes sure that private browsing mode disables the "remember"
 // option in the cookie accept dialog.
 
 function test() {
   // initialization
   let pb = Cc["@mozilla.org/privatebrowsing;1"].
            getService(Ci.nsIPrivateBrowsingService);
-  let ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
-           getService(Ci.nsIWindowWatcher);
   let cp = Cc["@mozilla.org/embedcomp/cookieprompt-service;1"].
            getService(Ci.nsICookiePromptService);
 
   waitForExplicitFinish();
 
   function checkRememberOption(expectedDisabled, callback) {
     function observer(aSubject, aTopic, aData) {
       if (aTopic != "domwindowopened")
         return;
 
-      ww.unregisterNotification(observer);
+      Services.ww.unregisterNotification(observer);
       let win = aSubject.QueryInterface(Ci.nsIDOMWindow);
       win.addEventListener("load", function onLoad(event) {
         win.removeEventListener("load", onLoad, false);
 
         executeSoon(function () {
           let doc = win.document;
           let remember = doc.getElementById("persistDomainAcceptance");
           ok(remember, "The remember checkbox should exist");
@@ -71,17 +69,17 @@ function test() {
             ok(!remember.hasAttribute("disabled"),
                "The checkbox should not be disabled");
 
           win.close();
           callback();
         });
       }, false);
     }
-    ww.registerNotification(observer);
+    Services.ww.registerNotification(observer);
 
     let remember = {};
     const time = (new Date("Jan 1, 2030")).getTime() / 1000;
     let cookie = {
       name: "foo",
       value: "bar",
       isDomain: true,
       host: "mozilla.org",
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_downloadmonitor.js
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_downloadmonitor.js
@@ -41,18 +41,16 @@
 function test() {
   // initialization
   let pb = Cc["@mozilla.org/privatebrowsing;1"].
            getService(Ci.nsIPrivateBrowsingService);
   let dm = Cc["@mozilla.org/download-manager;1"].
            getService(Ci.nsIDownloadManager);
   if (!gDownloadMgr)
     gDownloadMgr = dm;
-  let iosvc = Cc["@mozilla.org/network/io-service;1"].
-              getService(Ci.nsIIOService);
   let panel = document.getElementById("download-monitor");
   waitForExplicitFinish();
 
   // Add a new download
   addDownload(dm, {
     resultFileName: "pbtest-1",
     downloadName: "PB Test 1"
   });
@@ -154,15 +152,13 @@ function addDownload(dm, aParams)
   aParams.runBeforeStart.call(undefined, dl);
 
   persist.progressListener = dl.QueryInterface(Ci.nsIWebProgressListener);
   persist.saveURI(dl.source, null, null, null, null, dl.targetFile);
 
   return dl;
 }
 
-function createURI(aObj)
-{
-  let ios = Cc["@mozilla.org/network/io-service;1"].
-            getService(Ci.nsIIOService);
+function createURI(aObj) {
+  let ios = Services.io;
   return (aObj instanceof Ci.nsIFile) ? ios.newFileURI(aObj) :
                                         ios.newURI(aObj, null, null);
 }
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_fastswitch.js
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_fastswitch.js
@@ -37,18 +37,16 @@
 
 // This test makes sure that users are prevented from toggling the private
 // browsing mode too quickly, hence be proctected from symptoms in bug 526194.
 
 function test() {
   // initialization
   let pb = Cc["@mozilla.org/privatebrowsing;1"].
            getService(Ci.nsIPrivateBrowsingService);
-  let os = Cc["@mozilla.org/observer-service;1"].
-           getService(Ci.nsIObserverService);
   let pbCmd = document.getElementById("Tools:PrivateBrowsing");
   waitForExplicitFinish();
 
   let pass = 1;
   function observer(aSubject, aTopic, aData) {
     switch (aTopic) {
       case "private-browsing":
         setTimeout(function () {
@@ -66,21 +64,21 @@ function test() {
             pb.privateBrowsingEnabled = false;
           }, 100);
         }
         else {
           setTimeout(function () {
             ok(!pbCmd.hasAttribute("disabled"),
                "The private browsing command should be re-enabled after exiting the private browsing mode");
 
-            os.removeObserver(observer, "private-browsing");
-            os.removeObserver(observer, "private-browsing-transition-complete");
+            Services.obs.removeObserver(observer, "private-browsing");
+            Services.obs.removeObserver(observer, "private-browsing-transition-complete");
             finish();
           }, 100);
         }
         break;
     }
   }
-  os.addObserver(observer, "private-browsing", false);
-  os.addObserver(observer, "private-browsing-transition-complete", false);
+  Services.obs.addObserver(observer, "private-browsing", false);
+  Services.obs.addObserver(observer, "private-browsing-transition-complete", false);
 
   pb.privateBrowsingEnabled = true;
 }
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_forgetthissite.js
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_forgetthissite.js
@@ -37,34 +37,32 @@
 
 // This test makes sure that the Forget This Site command is hidden in private
 // browsing mode.
 
 function test() {
   // initialization
   let pb = Cc["@mozilla.org/privatebrowsing;1"].
            getService(Ci.nsIPrivateBrowsingService);
-  let ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
-           getService(Ci.nsIWindowWatcher);
   waitForExplicitFinish();
 
   // Add a history entry.
   const TEST_URI = "http://www.mozilla.org/privatebrowsing";
   ok(PlacesUtils, "checking PlacesUtils, running in chrome context?");
   let history = PlacesUtils.history;
   let visitId = history.addVisit(PlacesUtils._uri(TEST_URI), Date.now() * 1000,
                                  null, PlacesUtils.history.TRANSITION_TYPED, false, 0);
   ok(visitId > 0, TEST_URI + " successfully marked visited");
 
   function testForgetThisSiteVisibility(expected, funcNext) {
     function observer(aSubject, aTopic, aData) {
       if (aTopic != "domwindowopened")
         return;
 
-      ww.unregisterNotification(observer);
+      Services.ww.unregisterNotification(observer);
       let organizer = aSubject.QueryInterface(Ci.nsIDOMWindow);
       organizer.addEventListener("load", function onLoad(event) {
         organizer.removeEventListener("load", onLoad, false);
         executeSoon(function () {
           // Select History in the left pane.
           let PO = organizer.PlacesOrganizer;
           PO.selectLeftPaneQuery('History');
           let histContainer = PO._places.selectedNode.QueryInterface(Ci.nsINavHistoryContainerResultNode);
@@ -98,22 +96,22 @@ function test() {
           event.initMouseEvent("contextmenu", true, true, organizer, 0,
                                0, 0, 0, 0, false, false, false, false,
                                0, null);
           tree.dispatchEvent(event);
         });
       }, false);
     }
 
-    ww.registerNotification(observer);
-    ww.openWindow(null,
-                  "chrome://browser/content/places/places.xul",
-                  "",
-                  "chrome,toolbar=yes,dialog=no,resizable",
-                  null);
+    Services.ww.registerNotification(observer);
+    Services.ww.openWindow(null,
+                           "chrome://browser/content/places/places.xul",
+                           "",
+                           "chrome,toolbar=yes,dialog=no,resizable",
+                           null);
   }
 
   testForgetThisSiteVisibility(true, function() {
     // Enter private browsing mode
     pb.privateBrowsingEnabled = true;
     testForgetThisSiteVisibility(false, function() {
       // Leave private browsing mode
       pb.privateBrowsingEnabled = false;
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_openlocation.js
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_openlocation.js
@@ -37,18 +37,16 @@
 
 // This test makes sure that Open Location dialog is usable inside the private browsing
 // mode without leaving any trace of the URLs visited.
 
 function test() {
   // initialization
   let pb = Cc["@mozilla.org/privatebrowsing;1"].
            getService(Ci.nsIPrivateBrowsingService);
-  let ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
-           getService(Ci.nsIWindowWatcher);
   waitForExplicitFinish();
 
   function openLocation(url, autofilled, callback) {
     function observer(aSubject, aTopic, aData) {
       switch (aTopic) {
         case "domwindowopened":
           let dialog = aSubject.QueryInterface(Ci.nsIDOMWindow);
           dialog.addEventListener("load", function () {
@@ -70,22 +68,22 @@ function test() {
               for (let i = 0; i < url.length; ++i)
                 EventUtils.synthesizeKey(url[i], {}, dialog);
               EventUtils.synthesizeKey("VK_RETURN", {}, dialog);
             });
           }, false);
           break;
 
         case "domwindowclosed":
-          ww.unregisterNotification(arguments.callee);
+          Services.ww.unregisterNotification(arguments.callee);
           break;
       }
     }
 
-    ww.registerNotification(observer);
+    Services.ww.registerNotification(observer);
     gPrefService.setIntPref("general.open_location.last_window_choice", 0);
     openDialog("chrome://browser/content/openLocation.xul", "_blank",
                "chrome,titlebar", window);
   }
 
 
   if (gPrefService.prefHasUserValue("general.open_location.last_url"))
     gPrefService.clearUserPref("general.open_location.last_url");
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_transition.js
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_transition.js
@@ -37,41 +37,39 @@
  
 // Tests the order of events and notifications when entering/exiting private
 // browsing mode. This ensures that all private data is removed on exit, e.g.
 // a cookie set in on unload handler, see bug 476463.
 let cookieManager = Cc["@mozilla.org/cookiemanager;1"].
                     getService(Ci.nsICookieManager2);
 let pb = Cc["@mozilla.org/privatebrowsing;1"].
          getService(Ci.nsIPrivateBrowsingService);
-let _obs = Cc["@mozilla.org/observer-service;1"].
-           getService(Ci.nsIObserverService);
 let observerNotified = 0, firstUnloadFired = 0, secondUnloadFired = 0;
 
 function pbObserver(aSubject, aTopic, aData) {
   if (aTopic != "private-browsing")
     return;
   switch (aData) {
     case "enter":
       observerNotified++;
       is(observerNotified, 1, "This should be the first notification");
       is(firstUnloadFired, 1, "The first unload event should have been processed by now");
       break;
     case "exit":
-      _obs.removeObserver(pbObserver, "private-browsing");
+      Services.obs.removeObserver(pbObserver, "private-browsing");
       observerNotified++;
       is(observerNotified, 2, "This should be the second notification");
       is(secondUnloadFired, 1, "The second unload event should have been processed by now");
       break;
   }
 }
 
 function test() {
   waitForExplicitFinish();
-  _obs.addObserver(pbObserver, "private-browsing", false);
+  Services.obs.addObserver(pbObserver, "private-browsing", false);
   is(gBrowser.tabs.length, 1, "There should only be one tab");
   let testTab = gBrowser.addTab();
   gBrowser.selectedTab = testTab;
   testTab.linkedBrowser.addEventListener("unload", function () {
     testTab.linkedBrowser.removeEventListener("unload", arguments.callee, true);
     firstUnloadFired++;
     is(observerNotified, 0, "The notification shouldn't have been sent yet");
   }, true);
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_ui.js
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_ui.js
@@ -43,19 +43,17 @@ function test() {
   gPrefService.setBoolPref("browser.privatebrowsing.keep_current_session", true);
   let pb = Cc["@mozilla.org/privatebrowsing;1"].
            getService(Ci.nsIPrivateBrowsingService);
   let observerData;
   function observer(aSubject, aTopic, aData) {
     if (aTopic == "private-browsing")
       observerData = aData;
   }
-  let os = Cc["@mozilla.org/observer-service;1"].
-           getService(Ci.nsIObserverService);
-  os.addObserver(observer, "private-browsing", false);
+  Services.obs.addObserver(observer, "private-browsing", false);
   let pbMenuItem = document.getElementById("privateBrowsingItem");
   // add a new blank tab to ensure the title can be meaningfully compared later
   gBrowser.selectedTab = gBrowser.addTab();
   let originalTitle = document.title;
 
   // test the gPrivateBrowsingUI object
   ok(gPrivateBrowsingUI, "The gPrivateBrowsingUI object exists");
   is(pb.privateBrowsingEnabled, false, "The private browsing mode should not be started initially");
@@ -87,11 +85,11 @@ function test() {
   func.call(cmd);
   // check to see if the Private Browsing mode was deactivated successfully
   is(observerData, "exit", "Private Browsing mode was deactivated using the command object");
   // check to see that the window title has been restored correctly
   is(document.title, originalTitle, "Private browsing mode has correctly restored the title");
 
   // cleanup
   gBrowser.removeCurrentTab();
-  os.removeObserver(observer, "private-browsing");
+  Services.obs.removeObserver(observer, "private-browsing");
   gPrefService.clearUserPref("browser.privatebrowsing.keep_current_session");
 }
new file mode 100644
--- /dev/null
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_urlbarundo.js
@@ -0,0 +1,64 @@
+/* ***** 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 Private Browsing Tests.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Ehsan Akhgari <ehsan.akhgari@gmail.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// This test makes sure that the undo history of the URL bar is cleared when
+// leaving the private browsing mode.
+
+function test() {
+  // initialization
+  Services.prefs.setBoolPref("browser.privatebrowsing.keep_current_session", true);
+  let pb = Cc["@mozilla.org/privatebrowsing;1"].
+           getService(Ci.nsIPrivateBrowsingService);
+
+  // enter private browsing mode
+  pb.privateBrowsingEnabled = true;
+
+  // fill in the URL bar with something
+  gURLBar.value = "some test value";
+
+  ok(gURLBar.editor.transactionManager.numberOfUndoItems > 0,
+     "The undo history for the URL bar should not be empty");
+
+  // leave private browsing mode
+  pb.privateBrowsingEnabled = false;
+
+  is(gURLBar.editor.transactionManager.numberOfUndoItems, 0,
+     "The undo history of the URL bar should be cleared after leaving the private browsing mode");
+
+  // cleanup
+  Services.prefs.clearUserPref("browser.privatebrowsing.keep_current_session");
+}
+
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_viewsource.js
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_viewsource.js
@@ -45,58 +45,56 @@ function test() {
 
   waitForExplicitFinish();
 
   gBrowser.selectedTab = gBrowser.addTab();
   let aboutBrowser = gBrowser.selectedBrowser;
   aboutBrowser.addEventListener("load", function () {
     aboutBrowser.removeEventListener("load", arguments.callee, true);
 
-    let ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
-             getService(Ci.nsIWindowWatcher);
     function observer(aSubject, aTopic, aData) {
       if (aTopic != "domwindowopened")
         return;
 
-      ww.unregisterNotification(observer);
+      Services.ww.unregisterNotification(observer);
 
       let win = aSubject.QueryInterface(Ci.nsIDOMEventTarget);
       win.addEventListener("load", function () {
         win.removeEventListener("load", arguments.callee, false);
 
         let browser = win.gBrowser;
         browser.addEventListener("load", function () {
           browser.removeEventListener("load", arguments.callee, true);
           
           // view source window is loaded, proceed with the rest of the test
           step1();
         }, true);
       }, false);
     }
-    ww.registerNotification(observer);
+    Services.ww.registerNotification(observer);
 
     openViewSource();
 
     function openViewSource() {
       // invoke the View Source command
       document.getElementById("View:PageSource").doCommand();
     }
 
     function step1() {
       function observer(aSubject, aTopic, aData) {
         if (aTopic == "domwindowclosed") {
           ok(true, "Entering the private browsing mode should close the view source window");
-          ww.unregisterNotification(observer);
+          Services.ww.unregisterNotification(observer);
 
           step2();
         }
         else if (aTopic == "domwindowopened")
           ok(false, "Entering the private browsing mode should not open any view source window");
       }
-      ww.registerNotification(observer);
+      Services.ww.registerNotification(observer);
 
       gBrowser.addTabsProgressListener({
         onLocationChange: function() {},
         onProgressChange: function() {},
         onSecurityChange: function() {},
         onStatusChange: function() {},
         onRefreshAttempted: function() {},
         onStateChange: function(aBrowser, aWebProgress, aRequest, aStateFlags, aStatus) {
@@ -119,49 +117,49 @@ function test() {
         step4();
     }
 
     function step4() {
       function observer(aSubject, aTopic, aData) {
         if (aTopic != "domwindowopened")
           return;
 
-        ww.unregisterNotification(observer);
+        Services.ww.unregisterNotification(observer);
 
         let win = aSubject.QueryInterface(Ci.nsIDOMEventTarget);
         win.addEventListener("load", function () {
           win.removeEventListener("load", arguments.callee, false);
 
           let browser = win.gBrowser;
           browser.addEventListener("load", function () {
             browser.removeEventListener("load", arguments.callee, true);
             
             // view source window inside private browsing mode opened
             step5();
           }, true);
         }, false);
       }
-      ww.registerNotification(observer);
+      Services.ww.registerNotification(observer);
 
       openViewSource();
     }
 
     function step5() {
       let events = 0;
 
       function observer(aSubject, aTopic, aData) {
         if (aTopic == "domwindowclosed") {
           ok(true, "Leaving the private browsing mode should close the existing view source window");
           if (++events == 2)
-            ww.unregisterNotification(observer);
+            Services.ww.unregisterNotification(observer);
         }
         else if (aTopic == "domwindowopened") {
           ok(true, "Leaving the private browsing mode should restore the previous view source window");
           if (++events == 2)
-            ww.unregisterNotification(observer);
+            Services.ww.unregisterNotification(observer);
 
           let win = aSubject.QueryInterface(Ci.nsIDOMEventTarget);
           win.addEventListener("load", function () {
             win.removeEventListener("load", arguments.callee, false);
 
             let browser = win.gBrowser;
             browser.addEventListener("load", function () {
               browser.removeEventListener("load", arguments.callee, true);
@@ -172,16 +170,16 @@ function test() {
               // cleanup
               win.close();
               gBrowser.removeCurrentTab();
               finish();
             }, true);
           }, false);
         }
       }
-      ww.registerNotification(observer);
+      Services.ww.registerNotification(observer);
 
       // exit private browsing mode
       pb.privateBrowsingEnabled = false;
     }
   }, true);
   aboutBrowser.loadURI("about:");
 }
--- a/browser/components/search/test/browser_415700.js
+++ b/browser/components/search/test/browser_415700.js
@@ -28,20 +28,17 @@
  * 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 ***** */
-var gSS = Cc["@mozilla.org/browser/search-service;1"].
-           getService(Ci.nsIBrowserSearchService);
-var gObs = Cc["@mozilla.org/observer-service;1"].
-           getService(Ci.nsIObserverService);
+var gSS = Services.search;
 
 function observers(aSubject, aTopic, aData) {
   switch (aData) {
     case "engine-added":
       test2();
       break;
     case "engine-current":
       test3();
@@ -49,17 +46,17 @@ function observers(aSubject, aTopic, aDa
     case "engine-removed":
       test4();
       break;
   }
 }
 
 function test() {
   waitForExplicitFinish();
-  gObs.addObserver(observers, "browser-search-engine-modified", false);
+  Services.obs.addObserver(observers, "browser-search-engine-modified", false);
 
   gSS.addEngine("http://mochi.test:8888/browser/browser/components/search/test/testEngine.xml",
                 Ci.nsISearchEngine.DATA_XML, "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAABGklEQVQoz2NgGB6AnZ1dUlJSXl4eSDIyMhLW4Ovr%2B%2Fr168uXL69Zs4YoG%2BLi4i5dusTExMTGxsbNzd3f37937976%2BnpmZmagbHR09J49e5YvX66kpATVEBYW9ubNm2nTphkbG7e2tp44cQLIuHfvXm5urpaWFlDKysqqu7v73LlzECMYIiIiHj58mJCQoKKicvXq1bS0NKBgW1vbjh074uPjgeqAXE1NzSdPnvDz84M0AEUvXLgAsW379u1z5swBen3jxo2zZ892cHB4%2BvQp0KlAfwI1cHJyghQFBwfv2rULokFXV%2FfixYu7d%2B8GGqGgoMDKyrpu3br9%2B%2FcDuXl5eVA%2FAEWBfoWHAdAYoNuAYQ0XAeoUERFhGDYAAPoUaT2dfWJuAAAAAElFTkSuQmCC",
                 false);
 }
 
 function test2() {
   var engine = gSS.getEngineByName("Foo");
@@ -78,11 +75,11 @@ function test3() {
   gSS.removeEngine(engine);
 }
 
 function test4() {
   var engine = gSS.currentEngine;
   ok(engine, "An engine is present.");
   isnot(engine.name, "Foo", "Current engine reset after removal");
 
-  gObs.removeObserver(observers, "browser-search-engine-modified");
+  Services.obs.removeObserver(observers, "browser-search-engine-modified");
   finish();
 }
--- a/browser/components/search/test/browser_426329.js
+++ b/browser/components/search/test/browser_426329.js
@@ -3,41 +3,38 @@ function test() {
 
   var searchBar = BrowserSearch.searchBar;
   var searchButton = document.getAnonymousElementByAttribute(searchBar,
                      "anonid", "search-go-button");
   ok(searchButton, "got search-go-button");
 
   searchBar.value = "test";
 
-  var obs = Cc["@mozilla.org/observer-service;1"].
-            getService(Ci.nsIObserverService);
-  var ss = Cc["@mozilla.org/browser/search-service;1"].
-           getService(Ci.nsIBrowserSearchService);
+  var ss = Services.search;
 
   function observer(aSub, aTopic, aData) {
     switch (aData) {
       case "engine-added":
         var engine = ss.getEngineByName("Bug 426329");
         ok(engine, "Engine was added.");
         //XXX Bug 493051
         //ss.currentEngine = engine;
         break;
       case "engine-current":
         ok(ss.currentEngine.name == "Bug 426329", "currentEngine set");
         testReturn();
         break;
       case "engine-removed":
-        obs.removeObserver(observer, "browser-search-engine-modified");
+        Services.obs.removeObserver(observer, "browser-search-engine-modified");
         finish();
         break;
     }
   }
 
-  obs.addObserver(observer, "browser-search-engine-modified", false);
+  Services.obs.addObserver(observer, "browser-search-engine-modified", false);
   ss.addEngine("http://mochi.test:8888/browser/browser/components/search/test/426329.xml",
                Ci.nsISearchEngine.DATA_XML, "data:image/x-icon,%00",
                false);
 
   var preSelectedBrowser, preTabNo;
   function init() {
     preSelectedBrowser = gBrowser.selectedBrowser;
     preTabNo = gBrowser.mTabs.length;
--- a/browser/components/search/test/browser_483086.js
+++ b/browser/components/search/test/browser_483086.js
@@ -28,59 +28,56 @@
  * 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 ***** */
-let gSS = Cc["@mozilla.org/browser/search-service;1"].
-           getService(Ci.nsIBrowserSearchService);
-let gObs = Cc["@mozilla.org/observer-service;1"].
-           getService(Ci.nsIObserverService);
+let gSS = Services.search;
 
 function test() {
   waitForExplicitFinish();
 
   function observer(aSubject, aTopic, aData) {
     switch (aData) {
       case "engine-added":
         let engine = gSS.getEngineByName("483086a");
         ok(engine, "Test engine 1 installed");
         isnot(engine.searchForm, "foo://example.com",
               "Invalid SearchForm URL dropped");
         gSS.removeEngine(engine);
         break;
       case "engine-removed":
-        gObs.removeObserver(observer, "browser-search-engine-modified");
+        Services.obs.removeObserver(observer, "browser-search-engine-modified");
         test2();
         break;
     }
   }
 
-  gObs.addObserver(observer, "browser-search-engine-modified", false);
+  Services.obs.addObserver(observer, "browser-search-engine-modified", false);
   gSS.addEngine("http://mochi.test:8888/browser/browser/components/search/test/483086-1.xml",
                 Ci.nsISearchEngine.DATA_XML, "data:image/x-icon;%00",
                 false);
 }
 
 function test2() {
   function observer(aSubject, aTopic, aData) {
     switch (aData) {
       case "engine-added":
         let engine = gSS.getEngineByName("483086b");
         ok(engine, "Test engine 2 installed");
         is(engine.searchForm, "http://example.com", "SearchForm is correct");
         gSS.removeEngine(engine);
         break;
       case "engine-removed":  
-        gObs.removeObserver(observer, "browser-search-engine-modified");
+        Services.obs.removeObserver(observer, "browser-search-engine-modified");
         finish();
         break;
     }
   }
 
-  gObs.addObserver(observer, "browser-search-engine-modified", false);
+  Services.obs.addObserver(observer, "browser-search-engine-modified", false);
   gSS.addEngine("http://mochi.test:8888/browser/browser/components/search/test/483086-2.xml",
                 Ci.nsISearchEngine.DATA_XML, "data:image/x-icon;%00",
                 false);
 }
--- a/browser/components/sessionstore/test/browser/browser_248970_a.js
+++ b/browser/components/sessionstore/test/browser/browser_248970_a.js
@@ -58,23 +58,21 @@ function test() {
   function getSessionstorejsModificationTime() {
     let file = getSessionstoreFile();
     if (file.exists())
       return file.lastModifiedTime;
     else
       return -1;
   }
 
-  let os = Cc["@mozilla.org/observer-service;1"].
-           getService(Ci.nsIObserverService);
   function waitForFileExistence(aMessage, aDoNext) {
     const TOPIC = "sessionstore-state-write-complete";
-    os.addObserver(function (aSubject, aTopic, aData) {
+    Services.obs.addObserver(function (aSubject, aTopic, aData) {
       // Remove the observer so we do not leak.
-      os.removeObserver(arguments.callee, TOPIC);
+      Services.obs.removeObserver(arguments.callee, TOPIC);
 
       // Check that the file exists.
       ok(getSessionstoreFile().exists(), aMessage);
 
       // Run our next set of work.
       aDoNext();
     }, TOPIC, false);
   }
--- a/browser/components/sessionstore/test/browser/browser_354894.js
+++ b/browser/components/sessionstore/test/browser/browser_354894.js
@@ -104,19 +104,17 @@
  * nsSessionStore restore a window next time it gets a chance and will post
  * notifications. The latter won't.
  */
 
 function browserWindowsCount(expected, msg) {
   if (typeof expected == "number")
     expected = [expected, expected];
   let count = 0;
-  let e = Cc["@mozilla.org/appshell/window-mediator;1"]
-            .getService(Ci.nsIWindowMediator)
-            .getEnumerator("navigator:browser");
+  let e = Services.wm.getEnumerator("navigator:browser");
   while (e.hasMoreElements()) {
     if (!e.getNext().closed)
       ++count;
   }
   is(count, expected[0], msg + " (nsIWindowMediator)");
   let state = Cc["@mozilla.org/browser/sessionstore;1"]
                 .getService(Ci.nsISessionStore)
                 .getBrowserState();
@@ -167,18 +165,16 @@ function test() {
     observing[aTopic]++;
 
     // handle some tests
     if (++hitCount == 1) {
       // Test 6
       aCancel.QueryInterface(Ci.nsISupportsPRBool).data = true;
     }
   }
-  let observerService = Cc["@mozilla.org/observer-service;1"].
-                        getService(Ci.nsIObserverService);
 
   /**
    * Helper: Sets prefs as the testsuite requires
    * @note Will be reset in cleanTestSuite just before finishing the tests
    */
   function setPrefs() {
     gPrefService.setIntPref("browser.startup.page", 3);
     gPrefService.setBoolPref(
@@ -189,30 +185,30 @@ function test() {
   }
 
   /**
    * Helper: Sets up this testsuite
    */
   function setupTestsuite(testFn) {
     // Register our observers
     for (let o in observing)
-      observerService.addObserver(observer, o, false);
+      Services.obs.addObserver(observer, o, false);
 
     // Make the main test window not count as a browser window any longer
     oldWinType = document.documentElement.getAttribute("windowtype");
     document.documentElement.setAttribute("windowtype", "navigator:testrunner");
   }
 
   /**
    * Helper: Cleans up behind the testsuite
    */
   function cleanupTestsuite(callback) {
     // Finally remove observers again
     for (let o in observing)
-      observerService.removeObserver(observer, o, false);
+      Services.obs.removeObserver(observer, o, false);
 
     // Reset the prefs we touched
     [
       "browser.startup.page",
       "browser.privatebrowsing.keep_current_session"
     ].forEach(function (pref) {
       if (gPrefService.prefHasUserValue(pref))
         gPrefService.clearUserPref(pref);
--- a/browser/components/sessionstore/test/browser/browser_394759.js
+++ b/browser/components/sessionstore/test/browser/browser_394759.js
@@ -32,19 +32,17 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 function browserWindowsCount() {
   let count = 0;
-  let e = Cc["@mozilla.org/appshell/window-mediator;1"]
-            .getService(Ci.nsIWindowMediator)
-            .getEnumerator("navigator:browser");
+  let e = Services.wm.getEnumerator("navigator:browser");
   while (e.hasMoreElements()) {
     if (!e.getNext().closed)
       ++count;
   }
   return count;
 }
 
 function test() {
--- a/browser/components/sessionstore/test/browser/browser_394759_privatebrowsing.js
+++ b/browser/components/sessionstore/test/browser/browser_394759_privatebrowsing.js
@@ -34,19 +34,17 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 function browserWindowsCount() {
   let count = 0;
-  let e = Cc["@mozilla.org/appshell/window-mediator;1"]
-            .getService(Ci.nsIWindowMediator)
-            .getEnumerator("navigator:browser");
+  let e = Services.wm.getEnumerator("navigator:browser");
   while (e.hasMoreElements()) {
     if (!e.getNext().closed)
       ++count;
   }
   return count;
 }
 
 function test() {
@@ -69,20 +67,18 @@ function test() {
     }],
     _closedWindows: []
   });
   ss.setBrowserState(blankState);
 
   // Wait for the sessionstore.js file to be written before going on.
   // Note: we don't wait for the complete event, since if asyncCopy fails we
   // would timeout.
-  let os = Cc["@mozilla.org/observer-service;1"].
-           getService(Ci.nsIObserverService);
-  os.addObserver(function (aSubject, aTopic, aData) {
-    os.removeObserver(arguments.callee, aTopic);
+  Services.obs.addObserver(function (aSubject, aTopic, aData) {
+    Services.obs.removeObserver(arguments.callee, aTopic);
     info("sessionstore.js is being written");
     executeSoon(continue_test);
   }, "sessionstore-state-write", false);
 
   // Remove the sessionstore.js file before setting the interval to 0
   let profilePath = Cc["@mozilla.org/file/directory_service;1"].
                     getService(Ci.nsIProperties).
                     get("ProfD", Ci.nsIFile);
--- a/browser/components/sessionstore/test/browser/browser_423132.js
+++ b/browser/components/sessionstore/test/browser/browser_423132.js
@@ -31,19 +31,17 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 function browserWindowsCount() {
   let count = 0;
-  let e = Cc["@mozilla.org/appshell/window-mediator;1"]
-            .getService(Ci.nsIWindowMediator)
-            .getEnumerator("navigator:browser");
+  let e = Services.wm.getEnumerator("navigator:browser");
   while (e.hasMoreElements()) {
     if (!e.getNext().closed)
       ++count;
   }
   return count;
 }
 
 function test() {
--- a/browser/components/sessionstore/test/browser/browser_448741.js
+++ b/browser/components/sessionstore/test/browser/browser_448741.js
@@ -34,17 +34,16 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 function test() {
   /** Test for Bug 448741 **/
 
   // test setup
   let ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);
-  let os = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
   waitForExplicitFinish();
 
   let uniqueName = "bug 448741";
   let uniqueValue = "as good as unique: " + Date.now();
 
   // set a unique value on a new, blank tab
   var tab = gBrowser.addTab();
   tab.linkedBrowser.stop();
@@ -66,32 +65,32 @@ function test() {
           delete tabData.extData[uniqueName];
           valueWasCleaned = true;
         }
       });
     });
 
     ok(valueWasCleaned, "found and removed the specific tab value");
     aSubject.data = uneval(state);
-    os.removeObserver(cleaningObserver, aTopic, false);
+    Services.obs.removeObserver(cleaningObserver, aTopic, false);
   }
 
   // make sure that all later observers don't see that value any longer
   function checkingObserver(aSubject, aTopic, aData) {
     ok(valueWasCleaned && aSubject instanceof Ci.nsISupportsString,
        "ready to check the cleaned state?");
     ok(aSubject.data.indexOf(uniqueValue) == -1, "data no longer contains our value?");
 
     // clean up
     gBrowser.removeTab(tab);
-    os.removeObserver(checkingObserver, aTopic, false);
+    Services.obs.removeObserver(checkingObserver, aTopic, false);
     if (gPrefService.prefHasUserValue("browser.sessionstore.interval"))
       gPrefService.clearUserPref("browser.sessionstore.interval");
     finish();
   }
 
   // last added observers are invoked first
-  os.addObserver(checkingObserver, "sessionstore-state-write", false);
-  os.addObserver(cleaningObserver, "sessionstore-state-write", false);
+  Services.obs.addObserver(checkingObserver, "sessionstore-state-write", false);
+  Services.obs.addObserver(cleaningObserver, "sessionstore-state-write", false);
 
   // trigger an immediate save operation
   gPrefService.setIntPref("browser.sessionstore.interval", 0);
 }
--- a/browser/components/sessionstore/test/browser/browser_461634.js
+++ b/browser/components/sessionstore/test/browser/browser_461634.js
@@ -32,19 +32,17 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 function browserWindowsCount() {
   let count = 0;
-  let e = Cc["@mozilla.org/appshell/window-mediator;1"]
-            .getService(Ci.nsIWindowMediator)
-            .getEnumerator("navigator:browser");
+  let e = Services.wm.getEnumerator("navigator:browser");
   while (e.hasMoreElements()) {
     if (!e.getNext().closed)
       ++count;
   }
   return count;
 }
 
 function test() {
--- a/browser/components/sessionstore/test/browser/browser_464199.js
+++ b/browser/components/sessionstore/test/browser/browser_464199.js
@@ -31,19 +31,17 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 function browserWindowsCount() {
   let count = 0;
-  let e = Cc["@mozilla.org/appshell/window-mediator;1"]
-            .getService(Ci.nsIWindowMediator)
-            .getEnumerator("navigator:browser");
+  let e = Services.wm.getEnumerator("navigator:browser");
   while (e.hasMoreElements()) {
     if (!e.getNext().closed)
       ++count;
   }
   return count;
 }
 
 function test() {
--- a/browser/components/sessionstore/test/browser/browser_465223.js
+++ b/browser/components/sessionstore/test/browser/browser_465223.js
@@ -31,19 +31,17 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 function browserWindowsCount() {
   let count = 0;
-  let e = Cc["@mozilla.org/appshell/window-mediator;1"]
-            .getService(Ci.nsIWindowMediator)
-            .getEnumerator("navigator:browser");
+  let e = Services.wm.getEnumerator("navigator:browser");
   while (e.hasMoreElements()) {
     if (!e.getNext().closed)
       ++count;
   }
   return count;
 }
 
 function test() {
--- a/browser/components/sessionstore/test/browser/browser_477657.js
+++ b/browser/components/sessionstore/test/browser/browser_477657.js
@@ -31,19 +31,17 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 function browserWindowsCount() {
   let count = 0;
-  let e = Cc["@mozilla.org/appshell/window-mediator;1"]
-            .getService(Ci.nsIWindowMediator)
-            .getEnumerator("navigator:browser");
+  let e = Services.wm.getEnumerator("navigator:browser");
   while (e.hasMoreElements()) {
     if (!e.getNext().closed)
       ++count;
   }
   return count;
 }
 
 function test() {
--- a/browser/components/sessionstore/test/browser/browser_480148.js
+++ b/browser/components/sessionstore/test/browser/browser_480148.js
@@ -31,19 +31,17 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 function browserWindowsCount() {
   let count = 0;
-  let e = Cc["@mozilla.org/appshell/window-mediator;1"]
-            .getService(Ci.nsIWindowMediator)
-            .getEnumerator("navigator:browser");
+  let e = Services.wm.getEnumerator("navigator:browser");
   while (e.hasMoreElements()) {
     if (!e.getNext().closed)
       ++count;
   }
   return count;
 }
 
 function test() {
--- a/browser/components/sessionstore/test/browser/browser_490040.js
+++ b/browser/components/sessionstore/test/browser/browser_490040.js
@@ -32,36 +32,30 @@
  * 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 ***** */
 
 function browserWindowsCount() {
   let count = 0;
-  let e = Cc["@mozilla.org/appshell/window-mediator;1"]
-            .getService(Ci.nsIWindowMediator)
-            .getEnumerator("navigator:browser");
+  let e = Services.wm.getEnumerator("navigator:browser");
   while (e.hasMoreElements()) {
     if (!e.getNext().closed)
       ++count;
   }
   return count;
 }
 
 function test() {
   /** Test for Bug 490040 **/
   is(browserWindowsCount(), 1, "Only one browser window should be open initially");
 
   let ss = Cc["@mozilla.org/browser/sessionstore;1"].
            getService(Ci.nsISessionStore);
-  let os = Cc["@mozilla.org/observer-service;1"].
-           getService(Ci.nsIObserverService);
-  let ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
-           getService(Ci.nsIWindowWatcher);
 
   waitForExplicitFinish();
 
   function testWithState(aState) {
     // Ensure we can store the window if needed.
     let curClosedWindowCount = ss.getClosedWindowCount();
     gPrefService.setIntPref("browser.sessionstore.max_windows_undo",
                             curClosedWindowCount + 1);
@@ -93,34 +87,34 @@ function test() {
               }
               ss.setWindowState(theWin, JSON.stringify(aState.windowState),
                                 true);
             });
           }, false);
           break;
 
         case "domwindowclosed":
-          ww.unregisterNotification(windowObserver);
+          Services.ww.unregisterNotification(windowObserver);
           // Use executeSoon to ensure this happens after SS observer.
           executeSoon(function () {
             is(ss.getClosedWindowCount(),
                curClosedWindowCount + (aState.shouldBeAdded ? 1 : 0),
                "That window should " + (aState.shouldBeAdded ? "" : "not ") +
                "be restorable");
             executeSoon(runNextTest);
           });
           break;
       }
     }
-    ww.registerNotification(windowObserver);
-    ww.openWindow(null,
-                  location,
-                  "_blank",
-                  "chrome,all,dialog=no",
-                  null);
+    Services.ww.registerNotification(windowObserver);
+    Services.ww.openWindow(null,
+                           location,
+                           "_blank",
+                           "chrome,all,dialog=no",
+                           null);
   }
 
   // Only windows with open tabs are restorable. Windows where a lone tab is
   // detached may have _closedTabs, but is left with just an empty tab.
   let states = [
     {
       shouldBeAdded: true,
       windowState: {
--- a/browser/components/sessionstore/test/browser/browser_491168.js
+++ b/browser/components/sessionstore/test/browser/browser_491168.js
@@ -31,33 +31,30 @@
  * 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 ***** */
 
 function browserWindowsCount() {
   let count = 0;
-  let e = Cc["@mozilla.org/appshell/window-mediator;1"]
-            .getService(Ci.nsIWindowMediator)
-            .getEnumerator("navigator:browser");
+  let e = Services.wm.getEnumerator("navigator:browser");
   while (e.hasMoreElements()) {
     if (!e.getNext().closed)
       ++count;
   }
   return count;
 }
 
 function test() {
   /** Test for Bug 491168 **/
   is(browserWindowsCount(), 1, "Only one browser window should be open initially");
 
   // test setup
   let ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);
-  let ioService = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
 
   waitForExplicitFinish();
 
   const REFERRER1 = "http://example.org/?" + Date.now();
   const REFERRER2 = "http://example.org/?" + Math.random();
 
   let tab = gBrowser.addTab();
   gBrowser.selectedTab = tab;
@@ -86,11 +83,11 @@ function test() {
         gBrowser.removeTab(newTab);
 
         is(browserWindowsCount(), 1, "Only one browser window should be open eventually");
         finish();
       }, true);
     }, true);
   },true);
 
-  let referrerURI = ioService.newURI(REFERRER1, null, null);
+  let referrerURI = Services.io.newURI(REFERRER1, null, null);
   browser.loadURI("http://example.org", referrerURI, null);
 }
--- a/browser/components/sessionstore/test/browser/browser_491577.js
+++ b/browser/components/sessionstore/test/browser/browser_491577.js
@@ -32,19 +32,17 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 function browserWindowsCount() {
   let count = 0;
-  let e = Cc["@mozilla.org/appshell/window-mediator;1"]
-            .getService(Ci.nsIWindowMediator)
-            .getEnumerator("navigator:browser");
+  let e = Services.wm.getEnumerator("navigator:browser");
   while (e.hasMoreElements()) {
     if (!e.getNext().closed)
       ++count;
   }
   return count;
 }
 
 function test() {
--- a/browser/components/sessionstore/test/browser/browser_493467.js
+++ b/browser/components/sessionstore/test/browser/browser_493467.js
@@ -31,19 +31,17 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 function browserWindowsCount() {
   let count = 0;
-  let e = Cc["@mozilla.org/appshell/window-mediator;1"]
-            .getService(Ci.nsIWindowMediator)
-            .getEnumerator("navigator:browser");
+  let e = Services.wm.getEnumerator("navigator:browser");
   while (e.hasMoreElements()) {
     if (!e.getNext().closed)
       ++count;
   }
   return count;
 }
 
 function test() {
--- a/browser/components/sessionstore/test/browser/browser_495495.js
+++ b/browser/components/sessionstore/test/browser/browser_495495.js
@@ -31,19 +31,17 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 function browserWindowsCount() {
   let count = 0;
-  let e = Cc["@mozilla.org/appshell/window-mediator;1"]
-            .getService(Ci.nsIWindowMediator)
-            .getEnumerator("navigator:browser");
+  let e = Services.wm.getEnumerator("navigator:browser");
   while (e.hasMoreElements()) {
     if (!e.getNext().closed)
       ++count;
   }
   return count;
 }
 
 function test() {
--- a/browser/components/sessionstore/test/browser/browser_514751.js
+++ b/browser/components/sessionstore/test/browser/browser_514751.js
@@ -31,19 +31,17 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 function browserWindowsCount() {
   let count = 0;
-  let e = Cc["@mozilla.org/appshell/window-mediator;1"]
-            .getService(Ci.nsIWindowMediator)
-            .getEnumerator("navigator:browser");
+  let e = Services.wm.getEnumerator("navigator:browser");
   while (e.hasMoreElements()) {
     if (!e.getNext().closed)
       ++count;
   }
   return count;
 }
 
 function test() {
--- a/browser/components/sessionstore/test/browser/browser_522545.js
+++ b/browser/components/sessionstore/test/browser/browser_522545.js
@@ -32,19 +32,17 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 function browserWindowsCount() {
   let count = 0;
-  let e = Cc["@mozilla.org/appshell/window-mediator;1"]
-            .getService(Ci.nsIWindowMediator)
-            .getEnumerator("navigator:browser");
+  let e = Services.wm.getEnumerator("navigator:browser");
   while (e.hasMoreElements()) {
     if (!e.getNext().closed)
       ++count;
   }
   return count;
 }
 
 function test() {
--- a/browser/components/sessionstore/test/browser/browser_524745.js
+++ b/browser/components/sessionstore/test/browser/browser_524745.js
@@ -32,34 +32,30 @@
  * 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 ***** */
 
 function browserWindowsCount() {
   let count = 0;
-  let e = Cc["@mozilla.org/appshell/window-mediator;1"]
-            .getService(Ci.nsIWindowMediator)
-            .getEnumerator("navigator:browser");
+  let e = Services.wm.getEnumerator("navigator:browser");
   while (e.hasMoreElements()) {
     if (!e.getNext().closed)
       ++count;
   }
   return count;
 }
 
 function test() {
   /** Test for Bug 524745 **/
   is(browserWindowsCount(), 1, "Only one browser window should be open initially");
 
   let ss = Cc["@mozilla.org/browser/sessionstore;1"].
            getService(Ci.nsISessionStore);
-  let ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
-           getService(Ci.nsIWindowWatcher);
   let uniqKey = "bug524745";
   let uniqVal = Date.now();
 
   waitForExplicitFinish();
 
   let window_B = openDialog(location, "_blank", "chrome,all,dialog=no");
   window_B.addEventListener("load", function(aEvent) {
     window_B.removeEventListener("load", arguments.callee, false);
--- a/browser/components/sessionstore/test/browser/browser_526613.js
+++ b/browser/components/sessionstore/test/browser/browser_526613.js
@@ -36,25 +36,21 @@
  * ***** END LICENSE BLOCK ***** */
 
 function test() {
   /** Test for Bug 526613 **/
   
   // test setup
   let ss = Cc["@mozilla.org/browser/sessionstore;1"].
            getService(Ci.nsISessionStore);
-  let os = Cc["@mozilla.org/observer-service;1"].
-           getService(Ci.nsIObserverService);
-  let wm = Cc["@mozilla.org/appshell/window-mediator;1"].
-           getService(Ci.nsIWindowMediator);
   waitForExplicitFinish();
 
   function browserWindowsCount(expected) {
     let count = 0;
-    let e = wm.getEnumerator("navigator:browser");
+    let e = Services.wm.getEnumerator("navigator:browser");
     while (e.hasMoreElements()) {
       if (!e.getNext().closed)
         ++count;
     }
     is(count, expected,
        "number of open browser windows according to nsIWindowMediator");
     let state = ss.getBrowserState();
     info(state);
@@ -82,30 +78,30 @@ function test() {
     is(aTopic, "sessionstore-browser-state-restored",
        "The sessionstore-browser-state-restored notification was observed");
 
     if (pass++ == 1) {
       browserWindowsCount(2);
 
       // let the first window be focused (see above)
       function pollMostRecentWindow() {
-        if (wm.getMostRecentWindow("navigator:browser") == window) {
+        if (Services.wm.getMostRecentWindow("navigator:browser") == window) {
           ss.setBrowserState(oldState);
         } else {
           info("waiting for the current window to become active");
           setTimeout(pollMostRecentWindow, 0);
           window.focus(); //XXX Why is this needed?
         }
       }
       pollMostRecentWindow();
     }
     else {
       browserWindowsCount(1);
       ok(!window.closed, "Restoring the old state should have left this window open");
-      os.removeObserver(observer, "sessionstore-browser-state-restored");
+      Services.obs.removeObserver(observer, "sessionstore-browser-state-restored");
       finish();
     }
   }
-  os.addObserver(observer, "sessionstore-browser-state-restored", false);
+  Services.obs.addObserver(observer, "sessionstore-browser-state-restored", false);
 
   // set browser to test state
   ss.setBrowserState(JSON.stringify(testState));
 }
--- a/browser/components/sessionstore/test/browser/browser_528776.js
+++ b/browser/components/sessionstore/test/browser/browser_528776.js
@@ -1,14 +1,13 @@
 var ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);
-var wm = Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator);
 
 function browserWindowsCount(expected) {
   var count = 0;
-  var e = wm.getEnumerator("navigator:browser");
+  var e = Services.wm.getEnumerator("navigator:browser");
   while (e.hasMoreElements()) {
     if (!e.getNext().closed)
       ++count;
   }
   is(count, expected,
      "number of open browser windows according to nsIWindowMediator");
   is(JSON.parse(ss.getBrowserState()).windows.length, expected,
      "number of open browser windows according to getBrowserState");
new file mode 100644
--- /dev/null
+++ b/browser/components/test/Makefile.in
@@ -0,0 +1,48 @@
+#
+# ***** 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
+# the Mozilla Foundation.
+# Portions created by the Initial Developer are Copyright (C) 2010
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#   Robert Strong <robert.bugzilla@gmail.com> (Original Author)
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either of the GNU General Public License Version 2 or later (the "GPL"),
+# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+DEPTH     = ../../..
+topsrcdir = @top_srcdir@
+srcdir    = @srcdir@
+VPATH     = @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+DIRS = browser
+
+include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/browser/components/test/browser/Makefile.in
@@ -0,0 +1,52 @@
+# ***** 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
+# the Mozilla Foundation.
+# Portions created by the Initial Developer are Copyright (C) 2010
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#   Robert Strong <robert.bugzilla@gmail.com> (Original Author)
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either of the GNU General Public License Version 2 or later (the "GPL"),
+# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+DEPTH     = ../../../..
+topsrcdir = @top_srcdir@
+srcdir    = @srcdir@
+VPATH     = @srcdir@
+relativesrcdir  = browser/components/test/browser
+
+include $(DEPTH)/config/autoconf.mk
+include $(topsrcdir)/config/rules.mk
+
+_BROWSER_TEST_FILES = \
+  browser_bug538331.js \
+  $(NULL)
+
+libs:: $(_BROWSER_TEST_FILES)
+	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/browser/$(relativesrcdir)
new file mode 100644
--- /dev/null
+++ b/browser/components/test/browser/browser_bug538331.js
@@ -0,0 +1,373 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+const PREF_POSTUPDATE = "app.update.postupdate";
+const PREF_MSTONE = "browser.startup.homepage_override.mstone";
+const PREF_OVERRIDE_URL = "startup.homepage_override_url";
+
+const DEFAULT_PREF_URL = "http://pref.example.com/";
+const DEFAULT_UPDATE_URL = "http://example.com/";
+
+const XML_EMPTY = "<?xml version=\"1.0\"?><updates xmlns=" +
+                  "\"http://www.mozilla.org/2005/app-update\"></updates>";
+
+const XML_PREFIX =  "<updates xmlns=\"http://www.mozilla.org/2005/app-update\"" +
+                    "><update appVersion=\"1.0\" buildID=\"20080811053724\" " +
+                    "channel=\"nightly\" displayVersion=\"Version 1.0\" " +
+                    "extensionVersion=\"1.0\" installDate=\"1238441400314\" " +
+                    "isCompleteUpdate=\"true\" name=\"Update Test 1.0\" " +
+                    "serviceURL=\"https://example.com/\" showNeverForVersion=" +
+                    "\"false\" showPrompt=\"false\" showSurvey=\"false\" type=" +
+                    "\"minor\" version=\"version 1.0\" detailsURL=" +
+                    "\"http://example.com/\" previousAppVersion=\"1.0\" " +
+                    "statusText=\"The Update was successfully installed\" " +
+                    "foregroundDownload=\"true\"";
+
+const XML_SUFFIX = "><patch type=\"complete\" URL=\"http://example.com/\" " +
+                   "hashFunction=\"MD5\" hashValue=" +
+                   "\"6232cd43a1c77e30191c53a329a3f99d\" size=\"775\" " +
+                   "selected=\"true\" state=\"succeeded\"/></update></updates>";
+
+// nsBrowserContentHandler.js defaultArgs tests
+const BCH_TESTS = [
+  {
+    description: "no mstone change and no update",
+    noPostUpdatePref: true,
+    noMstoneChange: true
+  }, {
+    description: "mstone changed and no update",
+    noPostUpdatePref: true,
+    prefURL: DEFAULT_PREF_URL
+  }, {
+    description: "no mstone change and update with 'showURL' for actions",
+    actions: "showURL",
+    noMstoneChange: true
+  }, {
+    description: "update without actions",
+    prefURL: DEFAULT_PREF_URL
+  }, {
+    description: "update with 'showURL' for actions",
+    actions: "showURL",
+    prefURL: DEFAULT_PREF_URL
+  }, {
+    description: "update with 'showURL' for actions and openURL",
+    actions: "showURL",
+    openURL: DEFAULT_UPDATE_URL
+    }, {
+    description: "update with 'showURL showAlert' for actions",
+    actions: "showAlert showURL",
+    prefURL: DEFAULT_PREF_URL
+  }, {
+    description: "update with 'showAlert showURL' for actions and openURL",
+    actions: "showAlert showURL",
+    openURL: DEFAULT_UPDATE_URL
+  }, {
+    description: "update with 'showURL showNotification' for actions",
+    actions: "showURL showNotification",
+    prefURL: DEFAULT_PREF_URL
+  }, {
+    description: "update with 'showNotification showURL' for actions and " +
+                 "openURL",
+    actions: "showNotification showURL",
+    openURL: DEFAULT_UPDATE_URL
+  }, {
+    description: "update with 'showAlert showURL showNotification' for actions",
+    actions: "showAlert showURL showNotification",
+    prefURL: DEFAULT_PREF_URL
+  }, {
+    description: "update with 'showNotification showURL showAlert' for " +
+                 "actions and openURL",
+    actions: "showNotification showURL showAlert",
+    openURL: DEFAULT_UPDATE_URL
+  }, {
+    description: "update with 'showAlert' for actions",
+    actions: "showAlert"
+  }, {
+    description: "update with 'showAlert showNotification' for actions",
+    actions: "showAlert showNotification"
+  }, {
+    description: "update with 'showNotification' for actions",
+    actions: "showNotification"
+  }, {
+    description: "update with 'showNotification showAlert' for actions",
+    actions: "showNotification showAlert"
+  }, {
+    description: "update with 'silent' for actions",
+    actions: "silent"
+  }, {
+    description: "update with 'silent showURL showAlert showNotification' " +
+                 "for actions and openURL",
+    actions: "silent showURL showAlert showNotification"
+  }
+];
+
+var gOriginalMStone;
+var gOriginalOverrideURL;
+
+__defineGetter__("gBG", function() {
+  delete this.gBG;
+  return this.gBG = Cc["@mozilla.org/browser/browserglue;1"].
+                    getService(Ci.nsIBrowserGlue).
+                    QueryInterface(Ci.nsIObserver);
+});
+
+function test()
+{
+  waitForExplicitFinish();
+
+  if (gPrefService.prefHasUserValue(PREF_MSTONE)) {
+    gOriginalMStone = gPrefService.getCharPref(PREF_MSTONE);
+  }
+
+  if (gPrefService.prefHasUserValue(PREF_OVERRIDE_URL)) {
+    gOriginalOverrideURL = gPrefService.getCharPref(PREF_OVERRIDE_URL);
+  }
+
+  testDefaultArgs();
+}
+
+function finish_test()
+{
+  // Reset browser.startup.homepage_override.mstone to the original value or
+  // clear it if it didn't exist.
+  if (gOriginalMStone) {
+    gPrefService.setCharPref(PREF_MSTONE, gOriginalMStone);
+  } else if (gPrefService.prefHasUserValue(PREF_MSTONE)) {
+    gPrefService.clearUserPref(PREF_MSTONE);
+  }
+
+  // Reset startup.homepage_override_url to the original value or clear it if
+  // it didn't exist.
+  if (gOriginalOverrideURL) {
+    gPrefService.setCharPref(PREF_OVERRIDE_URL, gOriginalOverrideURL);
+  } else if (gPrefService.prefHasUserValue(PREF_OVERRIDE_URL)) {
+    gPrefService.clearUserPref(PREF_OVERRIDE_URL);
+  }
+
+  writeUpdatesToXMLFile(XML_EMPTY);
+  reloadUpdateManagerData();
+
+  finish();
+}
+
+// Test the defaultArgs returned by nsBrowserContentHandler after an update
+function testDefaultArgs()
+{
+  // Clear any pre-existing override in defaultArgs that are hanging around.
+  // This will also set the browser.startup.homepage_override.mstone preference
+  // if it isn't already set.
+  Cc["@mozilla.org/browser/clh;1"].getService(Ci.nsIBrowserHandler).defaultArgs;
+
+  let originalMstone = gPrefService.getCharPref(PREF_MSTONE);
+
+  gPrefService.setCharPref(PREF_OVERRIDE_URL, DEFAULT_PREF_URL);
+
+  writeUpdatesToXMLFile(XML_EMPTY);
+  reloadUpdateManagerData();
+
+  for (let i = 0; i < BCH_TESTS.length; i++) {
+    let test = BCH_TESTS[i];
+    ok(true, "Test nsBrowserContentHandler " + (i + 1) + ": " + test.description);
+
+    if (test.actions) {
+      let actionsXML = " actions=\"" + test.actions + "\"";
+      if (test.openURL) {
+        actionsXML += " openURL=\"" + test.openURL + "\"";
+      }
+      writeUpdatesToXMLFile(XML_PREFIX + actionsXML + XML_SUFFIX);
+    } else {
+      writeUpdatesToXMLFile(XML_EMPTY);
+    }
+
+    reloadUpdateManagerData();
+
+    let noOverrideArgs = Cc["@mozilla.org/browser/clh;1"].
+                         getService(Ci.nsIBrowserHandler).defaultArgs;
+
+    let overrideArgs = "";
+    if (test.prefURL) {
+      overrideArgs = test.prefURL;
+    } else if (test.openURL) {
+      overrideArgs = test.openURL;
+    }
+
+    if (overrideArgs == "" && noOverrideArgs) {
+      overrideArgs = noOverrideArgs;
+    } else if (noOverrideArgs) {
+      overrideArgs += "|" + noOverrideArgs;
+    }
+
+    if (test.noMstoneChange === undefined) {
+      gPrefService.setCharPref(PREF_MSTONE, "PreviousMilestone");
+    }
+
+    if (test.noPostUpdatePref == undefined) {
+      gPrefService.setBoolPref(PREF_POSTUPDATE, true);
+    }
+
+    let defaultArgs = Cc["@mozilla.org/browser/clh;1"].
+                      getService(Ci.nsIBrowserHandler).defaultArgs;
+    is(defaultArgs, overrideArgs, "correct value returned by defaultArgs");
+
+    if (test.noMstoneChange === undefined || test.noMstoneChange != true) {
+      let newMstone = gPrefService.getCharPref(PREF_MSTONE);
+      is(originalMstone, newMstone, "preference " + PREF_MSTONE +
+         " should have been updated");
+    }
+
+    if (gPrefService.prefHasUserValue(PREF_POSTUPDATE)) {
+      gPrefService.clearUserPref(PREF_POSTUPDATE);
+    }
+  }
+
+  testShowNotification();
+}
+
+// nsBrowserGlue.js _showUpdateNotification notification tests
+const BG_NOTIFY_TESTS = [
+  {
+    description: "'silent showNotification' actions should not display a notification",
+    actions: "silent showNotification"
+  }, {
+    description: "'showNotification' for actions should display a notification",
+    actions: "showNotification"
+  }, {
+    description: "no actions and empty updates.xml",
+  }, {
+    description: "'showAlert' for actions should not display a notification",
+    actions: "showAlert"
+  }, {
+    // This test MUST be the last test in the array to test opening the url
+    // provided by the updates.xml.
+    description: "'showNotification' for actions with custom notification " +
+                 "attributes should display a notification",
+    actions: "showNotification",
+    notificationText: "notification text",
+    notificationURL: DEFAULT_UPDATE_URL,
+    notificationButtonLabel: "button label",
+    notificationButtonAccessKey: "b"
+  }
+];
+
+// Test showing a notification after an update
+// _showUpdateNotification in nsBrowserGlue.js
+function testShowNotification()
+{
+  let gTestBrowser = gBrowser.selectedBrowser;
+  let notifyBox = gBrowser.getNotificationBox(gTestBrowser);
+
+  for (let i = 0; i < BG_NOTIFY_TESTS.length; i++) {
+    let test = BG_NOTIFY_TESTS[i];
+    ok(true, "Test showNotification " + (i + 1) + ": " + test.description);
+
+    if (test.actions) {
+      let actionsXML = " actions=\"" + test.actions + "\"";
+      if (test.notificationText) {
+        actionsXML += " notificationText=\"" + test.notificationText + "\"";
+      }
+      if (test.notificationURL) {
+        actionsXML += " notificationURL=\"" + test.notificationURL + "\"";
+      }
+      if (test.notificationButtonLabel) {
+        actionsXML += " notificationButtonLabel=\"" + test.notificationButtonLabel + "\"";
+      }
+      if (test.notificationButtonAccessKey) {
+        actionsXML += " notificationButtonAccessKey=\"" + test.notificationButtonAccessKey + "\"";
+      }
+      writeUpdatesToXMLFile(XML_PREFIX + actionsXML + XML_SUFFIX);
+    } else {
+      writeUpdatesToXMLFile(XML_EMPTY);
+    }
+
+    reloadUpdateManagerData();
+    gPrefService.setBoolPref(PREF_POSTUPDATE, true);
+
+    gBG.observe(null, "browser-glue-test", "post-update-notification");
+
+    let updateBox = notifyBox.getNotificationWithValue("post-update-notification");
+    if (test.actions && test.actions.indexOf("showNotification") != -1 &&
+        test.actions.indexOf("silent") == -1) {
+      ok(updateBox, "Update notification box should have been displayed");
+      if (updateBox) {
+        if (test.notificationText) {
+          is(updateBox.label, test.notificationText, "Update notification box " +
+             "should have the label provided by the update");
+        }
+        if (test.notificationButtonLabel) {
+          var button = updateBox.getElementsByTagName("button").item(0);
+          is(button.label, test.notificationButtonLabel, "Update notification " +
+             "box button should have the label provided by the update");
+          if (test.notificationButtonAccessKey) {
+            let accessKey = button.getAttribute("accesskey");
+            is(accessKey, test.notificationButtonAccessKey, "Update " +
+               "notification box button should have the accesskey " +
+               "provided by the update");
+          }
+        }
+        // The last test opens an url and verifies the url from the updates.xml
+        // is correct.
+        if (i == (BG_NOTIFY_TESTS.length - 1)) {
+          button.click();
+          gBrowser.selectedBrowser.addEventListener("load", testNotificationURL, true);
+        }
+      } else if (i == (BG_NOTIFY_TESTS.length - 1)) {
+        // If updateBox is null the test has already reported errors so bail
+        finish_test();
+      }
+      notifyBox.removeAllNotifications(true);
+    } else {
+      ok(!updateBox, "Update notification box should not have been displayed");
+    }
+
+    let prefHasUserValue = gPrefService.prefHasUserValue(PREF_POSTUPDATE);
+    is(prefHasUserValue, false, "preference " + PREF_POSTUPDATE +
+       " shouldn't have a user value");
+  }
+}
+
+// Test opening the url provided by the updates.xml in the last test
+function testNotificationURL()
+{
+  ok(true, "Test testNotificationURL: clicking the notification button " +
+           "opened the url specified by the update");
+  let href = gBrowser.selectedBrowser.contentWindow.location.href;
+  let expectedURL = BG_NOTIFY_TESTS[BG_NOTIFY_TESTS.length - 1].notificationURL;
+  is(href, expectedURL, "The url opened from the notification should be the " +
+     "url provided by the update");
+  gBrowser.removeCurrentTab();
+  window.focus();
+  finish_test();
+}
+
+/* Reloads the update metadata from disk */
+function reloadUpdateManagerData()
+{
+  Cc["@mozilla.org/updates/update-manager;1"].getService(Ci.nsIUpdateManager).
+  QueryInterface(Ci.nsIObserver).observe(null, "um-reload-update-data", "");
+}
+
+
+function writeUpdatesToXMLFile(aText)
+{
+  const PERMS_FILE = 0644;
+
+  const MODE_WRONLY   = 0x02;
+  const MODE_CREATE   = 0x08;
+  const MODE_TRUNCATE = 0x20;
+
+  let file = Cc["@mozilla.org/file/directory_service;1"].
+             getService(Ci.nsIProperties).
+             get("XCurProcD", Ci.nsIFile);
+  file.append("updates.xml");
+  let fos = Cc["@mozilla.org/network/file-output-stream;1"].
+            createInstance(Ci.nsIFileOutputStream);
+  if (!file.exists()) {
+    file.create(Ci.nsILocalFile.NORMAL_FILE_TYPE, PERMS_FILE);
+  }
+  fos.init(file, MODE_WRONLY | MODE_CREATE | MODE_TRUNCATE, PERMS_FILE, 0);
+  fos.write(aText, aText.length);
+  fos.close();
+}
--- a/browser/components/wintaskbar/WindowsPreviewPerTab.jsm
+++ b/browser/components/wintaskbar/WindowsPreviewPerTab.jsm
@@ -175,16 +175,22 @@ function PreviewController(win, tab) {
 
 PreviewController.prototype = {
   QueryInterface: XPCOMUtils.generateQI([Ci.nsITaskbarPreviewController,
                                          Ci.nsIDOMEventListener]),
   destroy: function () {
     this.linkedBrowser.removeEventListener("pageshow", this, false);
     this.linkedBrowser.removeEventListener("DOMTitleChanged", this, false);
     this.linkedBrowser.removeEventListener("MozAfterPaint", this, false);
+
+    // Break cycles, otherwise we end up leaking the window with everything
+    // attached to it.
+    delete this.win;
+    delete this.preview;
+    delete this.dirtyRegion;
   },
   get wrappedJSObject() {
     return this;
   },
 
   get dirtyRects() {
     let rectstream = this.dirtyRegion.getRects();
     if (!rectstream)
@@ -378,17 +384,16 @@ function TabWindow(win) {
   this.tabbrowser = win.gBrowser;
 
   this.previews = [];
 
   for (let i = 0; i < this.events.length; i++)
     this.tabbrowser.tabContainer.addEventListener(this.events[i], this, false);
   this.tabbrowser.addTabsProgressListener(this);
 
-
   AeroPeek.windows.push(this);
   let tabs = this.tabbrowser.tabs;
   for (let i = 0; i < tabs.length; i++)
     this.newTab(tabs[i]);
 
   this.updateTabOrdering();
   AeroPeek.checkPreviewCount();
 }
@@ -397,16 +402,18 @@ TabWindow.prototype = {
   _enabled: false,
   events: ["TabOpen", "TabClose", "TabSelect", "TabMove"],
 
   destroy: function () {
     this._destroying = true;
 
     let tabs = this.tabbrowser.tabs;
 
+    this.tabbrowser.removeTabsProgressListener(this);
+
     for (let i = 0; i < this.events.length; i++)
       this.tabbrowser.tabContainer.removeEventListener(this.events[i], this, false);
 
     for (let i = 0; i < tabs.length; i++)
       this.removeTab(tabs[i]);
 
     let idx = AeroPeek.windows.indexOf(this.win.gTaskbarTabGroup);
     AeroPeek.windows.splice(idx, 1);
@@ -584,16 +591,27 @@ var AeroPeek = {
 
     this.cacheLifespan = this.prefs.getIntPref(CACHE_EXPIRATION_TIME_PREF_NAME);
 
     this.maxpreviews = this.prefs.getIntPref(DISABLE_THRESHOLD_PREF_NAME);
 
     this.enabled = this._prefenabled = this.prefs.getBoolPref(TOGGLE_PREF_NAME);
   },
 
+  destroy: function destroy() {
+    this._enabled = false;
+
+    this.prefs.removeObserver(TOGGLE_PREF_NAME, this);
+    this.prefs.removeObserver(DISABLE_THRESHOLD_PREF_NAME, this);
+    this.prefs.removeObserver(CACHE_EXPIRATION_TIME_PREF_NAME, this);
+
+    if (this.cacheTimer)
+      this.cacheTimer.cancel();
+  },
+
   get enabled() {
     return this._enabled;
   },
 
   set enabled(enable) {
     if (this._enabled == enable)
       return;
 
@@ -631,17 +649,20 @@ var AeroPeek = {
   },
 
   onCloseWindow: function (win) {
     // This occurs when the taskbar service is not available (xp, vista)
     if (!this.available)
       return;
 
     win.gTaskbarTabGroup.destroy();
-    win.gTaskbarTabGroup = null;
+    delete win.gTaskbarTabGroup;
+
+    if (this.windows.length == 0)
+      this.destroy();
   },
 
   resetCacheTimer: function () {
     this.cacheTimer.cancel();
     this.cacheTimer.init(this, 1000*this.cacheLifespan, Ci.nsITimer.TYPE_ONE_SHOT);
   },
 
   //// nsIObserver
--- a/browser/confvars.sh
+++ b/browser/confvars.sh
@@ -37,17 +37,16 @@
 # ***** END LICENSE BLOCK *****
 
 MOZ_APP_NAME=firefox
 MOZ_UPDATER=1
 MOZ_PHOENIX=1
 
 MOZ_ENABLE_LIBXUL=1
 MOZ_STATIC_BUILD_UNSUPPORTED=1
-MOZ_PLACES=1
 # always enabled for form history
 MOZ_MORKREADER=1
 MOZ_SAFE_BROWSING=1
 MOZ_APP_VERSION=$FIREFOX_VERSION
 MOZ_EXTENSIONS_DEFAULT=" gnomevfs reporter"
 # MOZ_APP_DISPLAYNAME will be set by branding/configure.sh
 MOZ_BRANDING_DIRECTORY=browser/branding/nightly
 MOZ_OFFICIAL_BRANDING_DIRECTORY=other-licenses/branding/firefox
--- a/browser/fuel/test/browser_Application.js
+++ b/browser/fuel/test/browser_Application.js
@@ -1,22 +1,17 @@
-const Ci = Components.interfaces;
-const Cc = Components.classes;
-
 // This listens for the next opened window and checks it is of the right url.
 // opencallback is called when the new window is fully loaded
 // closecallback is called when the window is closed
 function WindowOpenListener(url, opencallback, closecallback) {
   this.url = url;
   this.opencallback = opencallback;
   this.closecallback = closecallback;
 
-  var wm = Cc["@mozilla.org/appshell/window-mediator;1"].
-           getService(Ci.nsIWindowMediator);
-  wm.addListener(this);
+  Services.wm.addListener(this);
 }
 
 WindowOpenListener.prototype = {
   url: null,
   opencallback: null,
   closecallback: null,
   window: null,
   domwindow: null,
@@ -42,19 +37,17 @@ WindowOpenListener.prototype = {
                            .getInterface(Ci.nsIDOMWindowInternal);
     this.domwindow.addEventListener("load", this, false);
   },
 
   onCloseWindow: function(window) {
     if (this.window != window)
       return;
 
-    var wm = Cc["@mozilla.org/appshell/window-mediator;1"].
-             getService(Ci.nsIWindowMediator);
-    wm.removeListener(this);
+    Services.wm.removeListener(this);
     this.opencallback = null;
     this.window = null;
     this.domwindow = null;
 
     // Let the window close complete
     executeSoon(this.closecallback);
     this.closecallback = null;
   }
--- a/browser/fuel/test/browser_ApplicationQuitting.js
+++ b/browser/fuel/test/browser_ApplicationQuitting.js
@@ -1,18 +1,17 @@
 function test() {
   function quitRequestObserver(aSubject, aTopic, aData) {
     ok(aTopic == "quit-application-requested" &&
        aSubject instanceof Components.interfaces.nsISupportsPRBool,
        "Received a quit request we're going to deny");
     aSubject.data = true;
   }
-  
+
   // ensure that we don't accidentally quit
-  let os = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
-  os.addObserver(quitRequestObserver, "quit-application-requested", false);
-  
+  Services.obs.addObserver(quitRequestObserver, "quit-application-requested", false);
+
   ok(!Application.quit(),    "Tried to quit - and didn't succeed");
   ok(!Application.restart(), "Tried to restart - and didn't succeed");
-  
+
   // clean up
-  os.removeObserver(quitRequestObserver, "quit-application-requested", false);
+  Services.obs.removeObserver(quitRequestObserver, "quit-application-requested", false);
 }
--- a/browser/fuel/test/browser_Bookmarks.js
+++ b/browser/fuel/test/browser_Bookmarks.js
@@ -1,17 +1,13 @@
-const Ci = Components.interfaces;
-const Cc = Components.classes;
-
 var gLastFolderAction = "";
 var gLastBookmarkAction = "";
 
 function url(spec) {
-  var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
-  return ios.newURI(spec, null, null);
+  return Services.io.newURI(spec, null, null);
 }
 
 function test() {
   // Some very basic tests on the tags root
   var tags = Application.bookmarks.tags;
   ok(tags, "Check access to bookmark tags root");
   ok(!tags.parent, "Check tags parent (should be null)");
 
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -43,22 +43,23 @@
 @BINPATH@/@DLL_PREFIX@mozjs@DLL_SUFFIX@
 @BINPATH@/@DLL_PREFIX@plc4@DLL_SUFFIX@
 @BINPATH@/@DLL_PREFIX@plds4@DLL_SUFFIX@
 @BINPATH@/@DLL_PREFIX@xpcom@DLL_SUFFIX@
 @BINPATH@/@DLL_PREFIX@nspr4@DLL_SUFFIX@
 @BINPATH@/@DLL_PREFIX@mozalloc@DLL_SUFFIX@
 #ifdef XP_MACOSX
 @BINPATH@/XUL
+@BINPATH@/mozilla-runtime@BIN_SUFFIX@
 #else
 @BINPATH@/@DLL_PREFIX@xul@DLL_SUFFIX@
-#endif
 #ifdef MOZ_IPC
 @BINPATH@/mozilla-runtime@BIN_SUFFIX@
 #endif
+#endif
 #ifdef WINCE
 @BINPATH@/mozce_shunt.dll
 #elifdef XP_WIN32
 #ifndef MOZ_MEMORY
 @BINPATH@/Microsoft.VC80.CRT.manifest
 @BINPATH@/msvcm80.dll
 @BINPATH@/msvcp80.dll
 @BINPATH@/msvcr80.dll
@@ -90,17 +91,16 @@
 @BINPATH@/plugins/npnulos2.dll
 #endif
 #ifndef XP_OS2
 @BINPATH@/@DLL_PREFIX@mozsqlite3@DLL_SUFFIX@
 #else
 @BINPATH@/mozsqlt3@DLL_SUFFIX@
 #endif
 @BINPATH@/README.txt
-@BINPATH@/LICENSE
 @BINPATH@/blocklist.xml
 #ifdef XP_UNIX
 @BINPATH@/run-mozilla.sh
 #ifndef XP_MACOSX
 @BINPATH@/mozilla-xremote-client
 #endif
 #endif
 #ifdef MOZ_SPLASHSCREEN
@@ -191,17 +191,16 @@
 @BINPATH@/components/layout_xul.xpt
 #ifdef XP_UNIX
 #ifndef XP_MACOSX
 @BINPATH@/components/libimgicon@DLL_SUFFIX@
 #endif
 #endif
 @BINPATH@/components/locale.xpt
 @BINPATH@/components/lwbrk.xpt
-@BINPATH@/components/microsummaries.xpt
 #ifndef WINCE
 @BINPATH@/components/migration.xpt
 #endif
 @BINPATH@/components/mimetype.xpt
 @BINPATH@/components/mozfind.xpt
 @BINPATH@/components/necko_about.xpt
 @BINPATH@/components/necko_cache.xpt
 @BINPATH@/components/necko_cookie.xpt
--- a/browser/installer/removed-files.in
+++ b/browser/installer/removed-files.in
@@ -1,8 +1,9 @@
+.autoreg
 chrome/classic.jar
 chrome/classic.manifest
 chrome/comm.jar
 chrome/comm.manifest
 chrome/reporter.jar
 chrome/reporter.manifest
 chrome/US.jar
 chrome/en-win.jar
@@ -613,17 +614,16 @@ res/fonts/fontNameMap.properties
 @DLL_PREFIX@xpcom_compat@DLL_SUFFIX@
 components/nsDictionary.js
 components/nsXmlRpcClient.js
 components/nsInterfaceInfoToIDL.js
 components/nsScriptableIO.js
 chrome/chromelist.txt
 modules/JSON.jsm
 #ifdef XP_MACOSX
-LICENSE
 extensions/inspector@mozilla.org/chrome/chromelist.txt
 components/accessibility.xpt
 components/content.xpt
 components/crashreporter.xpt
 components/gksvgrenderer.xpt
 components/jsconsole.xpt
 components/necko_data.xpt
 components/nsKillAll.js
@@ -726,17 +726,16 @@ components/jar.xpt
 components/jsdservice.xpt
 components/layout_base.xpt
 components/layout_printing.xpt
 components/layout_xul.xpt
 components/layout_xul_tree.xpt
 components/locale.xpt
 components/loginmgr.xpt
 components/lwbrk.xpt
-components/microsummaries.xpt
 components/migration.xpt
 components/mimetype.xpt
 components/mozbrwsr.xpt
 components/mozfind.xpt
 components/necko.xpt
 components/necko_about.xpt
 components/necko_cache.xpt
 components/necko_cookie.xpt
@@ -837,8 +836,10 @@ js3250.dll
 components/brwsrcmp.dll
 #endif
 #ifndef MOZ_UPDATER
 components/nsUpdateService.js
 components/nsUpdateServiceStub.js
 #endif
 @DLL_PREFIX@sqlite3@DLL_SUFFIX@
 old-homepage-default.properties
+components/microsummaries.xpt
+LICENSE
--- a/browser/installer/windows/nsis/installer.nsi
+++ b/browser/installer/windows/nsis/installer.nsi
@@ -258,17 +258,16 @@ Section "-Application" APP_IDX
   ${EndIf}
 
   ; Write extra files created by the application to the uninstall log so they
   ; will be removed when the application is uninstalled. To remove an empty
   ; directory write a bogus filename to the deepest directory and all empty
   ; parent directories will be removed.
   ${LogUninstall} "File: \components\compreg.dat"
   ${LogUninstall} "File: \components\xpti.dat"
-  ${LogUninstall} "File: \.autoreg"
   ${LogUninstall} "File: \active-update.xml"
   ${LogUninstall} "File: \install.log"
   ${LogUninstall} "File: \install_status.log"
   ${LogUninstall} "File: \install_wizard.log"
   ${LogUninstall} "File: \updates.xml"
 
   SetDetailsPrint both
   DetailPrint $(STATUS_INSTALL_LANG)
--- a/browser/locales/en-US/chrome/browser/browser.dtd
+++ b/browser/locales/en-US/chrome/browser/browser.dtd
@@ -6,16 +6,36 @@
 <!-- LOCALIZATION NOTE (mainWindow.titlemodifier) : DONT_TRANSLATE -->
 <!ENTITY mainWindow.titlemodifier "&brandFullName;">
 <!-- LOCALIZATION NOTE (mainWindow.titlemodifiermenuseparator): DONT_TRANSLATE -->
 <!ENTITY mainWindow.titlemodifiermenuseparator " - ">
 <!-- LOCALIZATION NOTE (mainWindow.titlePrivateBrowsingSuffix): This will be appended to the window's title
                                                                 inside the private browsing mode -->
 <!ENTITY mainWindow.titlePrivateBrowsingSuffix "(Private Browsing)">
 
+<!-- Tab context menu -->
+<!ENTITY  newTab.label                       "New Tab">
+<!ENTITY  newTab.accesskey                   "N">
+<!ENTITY  reloadTab.label                    "Reload Tab">
+<!ENTITY  reloadTab.accesskey                "R">
+<!ENTITY  reloadAllTabs.label                "Reload All Tabs">
+<!ENTITY  reloadAllTabs.accesskey            "A">
+<!ENTITY  closeOtherTabs.label               "Close Other Tabs">
+<!ENTITY  closeOtherTabs.accesskey           "o">
+<!ENTITY  openTabInNewWindow.label           "Open in a New Window">
+<!ENTITY  openTabInNewWindow.accesskey       "W">
+<!ENTITY  bookmarkThisTab.label              "Bookmark This Tab">
+<!ENTITY  bookmarkThisTab.accesskey          "B">
+<!ENTITY  bookmarkAllTabs.label              "Bookmark All Tabs…">
+<!ENTITY  bookmarkAllTabs.accesskey          "T">
+<!ENTITY  undoCloseTab.label                 "Undo Close Tab">
+<!ENTITY  undoCloseTab.accesskey             "U">
+<!ENTITY  closeTab.label                     "Close Tab">
+<!ENTITY  closeTab.accesskey                 "c">
+
 <!ENTITY tabCmd.label "New Tab">
 <!ENTITY tabCmd.accesskey "T">
 <!ENTITY tabCmd.commandkey "t">
 <!ENTITY openLocationCmd.label "Open Location…">
 <!ENTITY openLocationCmd.accesskey "L">
 <!ENTITY openFileCmd.label "Open File…">
 <!ENTITY openFileCmd.accesskey "O">
 <!ENTITY openFileCmd.commandkey "o">
@@ -185,16 +205,18 @@
 <!ENTITY viewMenu.label         "View"> 
 <!ENTITY viewMenu.accesskey       "V"> 
 <!ENTITY viewToolbarsMenu.label       "Toolbars"> 
 <!ENTITY viewToolbarsMenu.accesskey     "T"> 
 <!ENTITY viewSidebarMenu.label "Sidebar">
 <!ENTITY viewSidebarMenu.accesskey "e">
 <!ENTITY viewCustomizeToolbar.label       "Customize…"> 
 <!ENTITY viewCustomizeToolbar.accesskey     "C">
+<!ENTITY viewTabsOnTop.label            "Tabs on top">
+<!ENTITY viewTabsOnTop.accesskey        "T">
 
 <!ENTITY historyMenu.label "History">
 <!ENTITY historyMenu.accesskey "s">
 <!ENTITY historyUndoMenu.label "Recently Closed Tabs">
 <!-- LOCALIZATION NOTE (historyUndoWindowMenu): see bug 394759 -->
 <!ENTITY historyUndoWindowMenu.label "Recently Closed Windows">
 
 <!ENTITY historyHomeCmd.label "Home">
@@ -202,16 +224,17 @@
 <!ENTITY showAllHistoryCmd.commandkey "H">
 
 <!ENTITY openCmd.commandkey           "l">
 <!ENTITY urlbar.bookmarkhistory.emptyText "Search Bookmarks and History">
 <!ENTITY urlbar.bookmark.emptyText    "Search Bookmarks">
 <!ENTITY urlbar.history.emptyText     "Search History">
 <!ENTITY urlbar.none.emptyText        "Type a Web address">
 <!ENTITY urlbar.accesskey             "d">
+<!ENTITY urlbar.switchToTab.label     "Switch to tab:">
 
 <!-- 
   Comment duplicated from browser-sets.inc:
 
   Search Command Key Logic works like this:
   
   Unix: Ctrl+J (0.8, 0.9 support)
         Ctrl+K (cross platform binding)
--- a/browser/locales/en-US/chrome/browser/browser.properties
+++ b/browser/locales/en-US/chrome/browser/browser.properties
@@ -186,16 +186,24 @@ editBookmarkPanel.editBookmarkTitle=Edit
 
 # LOCALIZATION NOTE (editBookmark.removeBookmarks.label)
 # Semi-colon list of plural forms. Replacement for #1 is
 # the number of bookmarks to be removed.
 # If this causes problems with localization you can also do "Remove Bookmarks (#1)"
 # instead of "Remove #1 Bookmarks".
 editBookmark.removeBookmarks.label=Remove Bookmark;Remove #1 Bookmarks
 
+# Post Update Notifications
+pu.notifyButton.label=Details…
+pu.notifyButton.accesskey=D
+# LOCALIZATION NOTE %S will be replaced by the short name of the application.
+puNotifyText=%S has been updated
+puAlertTitle=%S Updated
+puAlertText=Click here for details
+
 # Geolocation UI
 
 # LOCALIZATION NOTE (geolocation.shareLocation geolocation.dontShareLocation): 
 #If you're having trouble with the word Share, please use Allow and Block in your language.
 geolocation.shareLocation=Share Location
 geolocation.shareLocation.accesskey=a
 geolocation.dontShareLocation=Don't Share
 geolocation.dontShareLocation.accesskey=o
--- a/browser/locales/en-US/chrome/browser/tabbrowser.dtd
+++ b/browser/locales/en-US/chrome/browser/tabbrowser.dtd
@@ -1,20 +1,3 @@
-<!ENTITY  newTab.label           "New Tab">
-<!ENTITY  newTab.accesskey       "N">
 <!ENTITY  closeTab.label         "Close Tab">
-<!ENTITY  closeTab.accesskey         "c">
-<!ENTITY  closeOtherTabs.accesskey  "o">
-<!ENTITY  closeOtherTabs.label   "Close Other Tabs">
-<!ENTITY  reloadAllTabs.label    "Reload All Tabs">
-<!ENTITY  reloadAllTabs.accesskey         "A">
-<!ENTITY  reloadTab.label        "Reload Tab">
-<!ENTITY  reloadTab.accesskey         "r">
-<!ENTITY  openTabInNewWindow.label    "Open in a New Window">
-<!ENTITY  openTabInNewWindow.accesskey "W">
 <!ENTITY  listAllTabs.label      "List all tabs">
-<!ENTITY  bookmarkAllTabs.label       "Bookmark All Tabs…">
-<!ENTITY  bookmarkAllTabs.accesskey   "T">
-<!ENTITY  bookmarkThisTab.label       "Bookmark This Tab">
-<!ENTITY  bookmarkThisTab.accesskey   "B">
-<!ENTITY  undoCloseTab.label          "Undo Close Tab">
-<!ENTITY  undoCloseTab.accesskey      "U">
 <!ENTITY  newTabButton.tooltip        "Open a new tab">
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..fed3d7f7cde2835388bf7ad5694e18d8042dba77
GIT binary patch
literal 293
zc%17D@N?(olHy`uVBq!ia0vp^;y^6G!3HG%>OYYHQY`6?zK#qG8~eHcB(eheoCO|{
z#S9F5hd`K7RKu$QC@5Lt8c`CQpH@<ySd_{TkeHcQqUYxtqEKe6XR2rD_uS$qP|+e!
z7sn6_|F;vpxta|`T<<zPJGWV5`olAGBYp)oZP_xnL}O|5I-PsWTzo#JP6r$L`550H
z|1e4AcTOU6eC#9Td)x=T(=Ki)+Iu9}=7=qWl-!<_XUD7OH_z!^aa5Hd%J|dy>HRWO
z=DSET@Sb0_Q?vA6U|*YhU5{b-Qmw)nKN#<?x+fg}ZjSbvt;Y}C%Qmt3c-HI1!k~$~
m{APuVmaaba{la~-3yjQFY5TRMSrdV-W$<+Mb6Mw<&;$U6Ic<Od
--- a/browser/themes/gnomestripe/browser/browser.css
+++ b/browser/themes/gnomestripe/browser/browser.css
@@ -795,16 +795,27 @@ toolbar[iconsize="small"] #fullscreen-bu
 #urlbar-search-splitter + #search-container > #searchbar > .searchbar-textbox {
   -moz-margin-start: 0;
 }
 
 #wrapper-urlbar-container #urlbar > .autocomplete-history-dropmarker {
   display: none;
 }
 
+#urlbar-display {
+  margin-top: -2px;
+  margin-bottom: -2px;
+  padding-top: 3px;
+  padding-bottom: 2px;
+  -moz-padding-end: 3px;
+  color: GrayText;
+  -moz-border-end: 1px solid #AAA;
+  -moz-margin-end: 3px;
+}
+
 #PopupAutoComplete,
 #PopupAutoCompleteRichResult {
   direction: ltr !important;
 }
 
 #PopupAutoComplete:-moz-locale-dir(rtl) > tree > treerows {
   direction: rtl;
 }
@@ -993,16 +1004,20 @@ toolbar[iconsize="small"] #fullscreen-bu
 .ac-extra > .ac-comment {
   font-size: inherit;
 }
 
 .ac-url-text {
   color: -moz-nativehyperlinktext;
 }
 
+richlistitem[type="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-icon {
+  list-style-image: url("chrome://browser/skin/actionicon-tab.png");
+}
+
 .autocomplete-treebody::-moz-tree-cell-text(treecolAutoCompleteComment) {
   color: GrayText;
 }
 
 .ac-comment[selected="true"], .ac-url-text[selected="true"] {
   color: inherit !important;
 }
 
--- a/browser/themes/gnomestripe/browser/jar.mn
+++ b/browser/themes/gnomestripe/browser/jar.mn
@@ -1,16 +1,17 @@
 browser.jar:
 % skin browser classic/1.0 %skin/classic/browser/
 % override chrome://global/skin/icons/warning-16.png moz-icon://stock/gtk-dialog-warning?size=menu
   skin/classic/browser/sanitizeDialog.css             (sanitizeDialog.css)
 * skin/classic/browser/aboutPrivateBrowsing.css             (aboutPrivateBrowsing.css)
 * skin/classic/browser/aboutSessionRestore.css        (aboutSessionRestore.css)
   skin/classic/browser/aboutSessionRestore-window-icon.png
   skin/classic/browser/aboutCertError.css             (aboutCertError.css)
+  skin/classic/browser/actionicon-tab.png
 * skin/classic/browser/browser.css                    (browser.css)
 * skin/classic/browser/engineManager.css              (engineManager.css)
   skin/classic/browser/fullscreen-video.css
   skin/classic/browser/Geo.png
   skin/classic/browser/Go-arrow.png
   skin/classic/browser/identity.png
   skin/classic/browser/Info.png
   skin/classic/browser/KUI-close.png
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..fed3d7f7cde2835388bf7ad5694e18d8042dba77
GIT binary patch
literal 293
zc%17D@N?(olHy`uVBq!ia0vp^;y^6G!3HG%>OYYHQY`6?zK#qG8~eHcB(eheoCO|{
z#S9F5hd`K7RKu$QC@5Lt8c`CQpH@<ySd_{TkeHcQqUYxtqEKe6XR2rD_uS$qP|+e!
z7sn6_|F;vpxta|`T<<zPJGWV5`olAGBYp)oZP_xnL}O|5I-PsWTzo#JP6r$L`550H
z|1e4AcTOU6eC#9Td)x=T(=Ki)+Iu9}=7=qWl-!<_XUD7OH_z!^aa5Hd%J|dy>HRWO
z=DSET@Sb0_Q?vA6U|*YhU5{b-Qmw)nKN#<?x+fg}ZjSbvt;Y}C%Qmt3c-HI1!k~$~
m{APuVmaaba{la~-3yjQFY5TRMSrdV-W$<+Mb6Mw<&;$U6Ic<Od
--- a/browser/themes/pinstripe/browser/browser.css
+++ b/browser/themes/pinstripe/browser/browser.css
@@ -863,16 +863,27 @@ toolbar[iconsize="small"] #unified-back-
 #wrapper-urlbar-container .autocomplete-history-dropmarker > .dropmarker-icon {
   display: none;
 }
 
 #wrapper-urlbar-container .autocomplete-history-dropmarker {
   width: 10px;
 }
 
+#urlbar-display {
+  margin-top: -2px;
+  margin-bottom: -2px;
+  padding-top: 3px;
+  padding-bottom: 2px;
+  -moz-padding-end: 3px;
+  color: GrayText;
+  -moz-border-end: 1px solid #AAA;
+  -moz-margin-end: 3px;
+}
+
 #PopupAutoCompleteRichResult {
   direction: ltr !important;
   margin-top: 2px;
 }
 
 statusbarpanel#statusbar-display {
   -moz-padding-start: 0;
 }
@@ -924,16 +935,20 @@ richlistitem[selected="true"][current="t
   font-size: inherit;
 }
 
 .ac-url-text {
   color: -moz-nativehyperlinktext;
   font-size: 0.95em;
 }
 
+richlistitem[type="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-icon {
+  list-style-image: url("chrome://browser/skin/actionicon-tab.png");
+}
+
 .autocomplete-treebody::-moz-tree-cell-text(treecolAutoCompleteComment) {
   color: GrayText;
 }
 
 .ac-comment[selected="true"], .ac-url-text[selected="true"] {
   color: inherit !important;
 }
 
@@ -1570,16 +1585,19 @@ toolbarbutton.chevron > .toolbarbutton-m
 
 .tabbrowser-tab:-moz-lwtheme {
   color: inherit;
   text-shadow: inherit;
 }
 
 #TabsToolbar {
   -moz-appearance: none;
+}
+
+#navigator-toolbox:not([tabsontop="true"]) > #TabsToolbar {
   margin-top: -1px;
   border-bottom: 1px solid #404040;
 }
 
 #TabsToolbar:not(:-moz-lwtheme) {
   background: #9B9B9B url("chrome://browser/skin/tabbrowser/tabbrowser-tabs-bkgnd.png") repeat-x;
 }
 
--- a/browser/themes/pinstripe/browser/jar.mn
+++ b/browser/themes/pinstripe/browser/jar.mn
@@ -1,15 +1,16 @@
 browser.jar:
 % skin browser classic/1.0 %skin/classic/browser/
   skin/classic/browser/sanitizeDialog.css                   (sanitizeDialog.css)
 * skin/classic/browser/aboutPrivateBrowsing.css             (aboutPrivateBrowsing.css)
 * skin/classic/browser/aboutSessionRestore.css              (aboutSessionRestore.css)
   skin/classic/browser/aboutSessionRestore-window-icon.png
   skin/classic/browser/aboutCertError.css                   (aboutCertError.css)
+  skin/classic/browser/actionicon-tab.png
 * skin/classic/browser/browser.css                          (browser.css)
 * skin/classic/browser/engineManager.css                    (en