Merge from mozilla-central.
authorJan de Mooij <jdemooij@mozilla.com>
Thu, 21 Mar 2013 11:23:12 +0100
changeset 139215 e5978106c61a8a1be42ed34566c55f668683a2ea
parent 139214 280e5ed3f0b71bea873ba9a1be0dc5bcefa7e0b5 (current diff)
parent 136787 1d6fe70c79c55c1b8dd64a0c8153c896c3955565 (diff)
child 139216 872c29501019d020a444538a3c234e0adc63a1ed
push id350
push userbbajaj@mozilla.com
push dateMon, 29 Jul 2013 23:00:49 +0000
treeherdermozilla-release@064965b37dbd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone22.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge from mozilla-central.
accessible/Makefile.in
accessible/tests/Makefile.in
addon-sdk/source/test/addons/private-browsing-supported/tabs.js
addon-sdk/source/test/addons/private-browsing-supported/windows.js
browser/components/feeds/public/Makefile.in
browser/components/migration/public/Makefile.in
browser/components/privatebrowsing/Makefile.in
browser/components/privatebrowsing/test/Makefile.in
browser/components/sessionstore/Makefile.in
browser/components/shell/public/Makefile.in
browser/fuel/public/Makefile.in
caps/Makefile.in
chrome/public/Makefile.in
content/Makefile.in
content/html/content/test/forms/test_input_file_b2g_disabled.html
content/html/document/public/Makefile.in
content/svg/content/src/DOMSVGAnimatedTransformList.cpp
content/svg/content/src/DOMSVGAnimatedTransformList.h
content/svg/content/src/SVGAnimatedTransformList.cpp
content/svg/content/src/SVGAnimatedTransformList.h
content/svg/content/src/SVGFEGaussianBlurElement.cpp
content/svg/content/src/SVGFEGaussianBlurElement.h
content/svg/content/src/nsSVGFilters.cpp
content/xul/content/Makefile.in
content/xul/content/public/Makefile.in
content/xul/document/Makefile.in
content/xul/templates/Makefile.in
content/xul/templates/public/Makefile.in
docshell/Makefile.in
docshell/shistory/Makefile.in
dom/Makefile.in
dom/icc/tests/Makefile.in
dom/imptests/webapps/WebStorage/tests/submissions/Makefile.in
dom/interfaces/smil/Makefile.in
dom/interfaces/svg/Makefile.in
dom/interfaces/xpath/Makefile.in
editor/composer/public/Makefile.in
editor/txmgr/Makefile.in
editor/txmgr/idl/Makefile.in
editor/txtsvc/Makefile.in
embedding/android/AlertNotification.java
embedding/android/AndroidManifest.xml.in
embedding/android/App.java.in
embedding/android/CrashReporter.java.in
embedding/android/GeckoApp.java
embedding/android/GeckoAppShell.java
embedding/android/GeckoBatteryManager.java
embedding/android/GeckoConnectivityReceiver.java
embedding/android/GeckoEvent.java
embedding/android/GeckoInputConnection.java
embedding/android/GeckoNetworkManager.java
embedding/android/GeckoScreenOrientationListener.java
embedding/android/GeckoSurfaceView.java
embedding/android/LauncherShortcuts.java.in
embedding/android/Makefile.in
embedding/android/NotificationHandler.java.in
embedding/android/Restarter.java.in
embedding/android/SmsManager.java.in
embedding/android/SurfaceInfo.java
embedding/android/VideoPlayer.java
embedding/android/locales/Makefile.in
embedding/android/locales/en-US/android_strings.dtd
embedding/android/locales/l10n.ini
embedding/android/locales/moz.build
embedding/android/moz.build
embedding/android/resources/drawable/crash_reporter.png
embedding/android/resources/drawable/desktop_notification.png
embedding/android/resources/layout/crash_reporter.xml
embedding/android/resources/layout/launch_app_list.xml
embedding/android/resources/layout/launch_app_listitem.xml
embedding/android/resources/layout/notification_icon_text.xml
embedding/android/resources/layout/notification_progress.xml
embedding/android/resources/layout/notification_progress_text.xml
embedding/android/resources/layout/videoplayer.xml
embedding/android/resources/values/colors.xml
embedding/android/resources/values/themes.xml
embedding/android/strings.xml.in
embedding/components/commandhandler/Makefile.in
embedding/components/commandhandler/public/Makefile.in
embedding/components/find/Makefile.in
embedding/components/find/public/Makefile.in
embedding/components/webbrowserpersist/Makefile.in
extensions/pref/autoconfig/Makefile.in
extensions/pref/autoconfig/public/Makefile.in
extensions/spellcheck/Makefile.in
extensions/spellcheck/idl/Makefile.in
extensions/universalchardet/Makefile.in
extensions/universalchardet/src/Makefile.in
gfx/Makefile.in
image/Makefile.in
image/decoders/icon/qt/public/Makefile.in
intl/hyphenation/Makefile.in
intl/locale/Makefile.in
intl/lwbrk/Makefile.in
intl/lwbrk/idl/Makefile.in
intl/strres/Makefile.in
intl/uconv/Makefile.in
intl/unicharutil/Makefile.in
js/jsd/idl/Makefile.in
js/src/Makefile.in
js/src/builtin/ParallelArray-inl.h
js/src/ion/CodeGenerator.cpp
js/src/ion/CodeGenerator.h
js/src/ion/Ion.cpp
js/src/ion/IonBuilder.cpp
js/src/ion/IonBuilder.h
js/src/ion/MIR.h
js/src/ion/TypePolicy.cpp
js/src/ion/VMFunctions.cpp
js/src/ion/VMFunctions.h
js/src/jit-test/tests/parallelarray/filter-1.js
js/src/jit-test/tests/parallelarray/filter-2.js
js/src/jit-test/tests/parallelarray/filter-3.js
js/src/jit-test/tests/parallelarray/filter-4.js
js/src/jit-test/tests/parallelarray/filter-throws.js
js/src/jit-test/tests/parallelarray/get-5.js
js/src/jit-test/tests/parallelarray/get-throws.js
js/src/jit-test/tests/parallelarray/map-1.js
js/src/jit-test/tests/parallelarray/reduce-1.js
js/src/jit-test/tests/parallelarray/reduce-2.js
js/src/jit-test/tests/parallelarray/reduce-3.js
js/src/jscntxt.cpp
js/src/jscntxt.h
js/src/jsfun.cpp
js/src/jsgc.cpp
js/src/jsinferinlines.h
js/src/shell/js.cpp
js/src/vm/SelfHosting.cpp
js/xpconnect/Makefile.in
layout/Makefile.in
layout/inspector/public/Makefile.in
layout/tools/layout-debug/Makefile.in
media/libcubeb/Makefile.in
media/libnestegg/Makefile.in
media/libogg/Makefile.in
media/libogg/include/Makefile.in
media/libspeex_resampler/Makefile.in
media/libsydneyaudio/AUTHORS
media/libsydneyaudio/Makefile.in
media/libsydneyaudio/README_MOZILLA
media/libsydneyaudio/include/Makefile.in
media/libsydneyaudio/include/moz.build
media/libsydneyaudio/include/sydney_audio.h
media/libsydneyaudio/moz.build
media/libsydneyaudio/src/Makefile.in
media/libsydneyaudio/src/gonk/AudioSystem.h
media/libsydneyaudio/src/gonk/AudioTrack.h
media/libsydneyaudio/src/gonk/EffectApi.h
media/libsydneyaudio/src/gonk/IAudioFlinger.h
media/libsydneyaudio/src/gonk/IAudioFlingerClient.h
media/libsydneyaudio/src/gonk/IAudioRecord.h
media/libsydneyaudio/src/gonk/IAudioTrack.h
media/libsydneyaudio/src/gonk/IEffect.h
media/libsydneyaudio/src/gonk/IEffectClient.h
media/libsydneyaudio/src/moz.build
media/libsydneyaudio/src/sydney_audio_aix.c
media/libsydneyaudio/src/sydney_audio_alsa.c
media/libsydneyaudio/src/sydney_audio_android.c
media/libsydneyaudio/src/sydney_audio_gonk.cpp
media/libsydneyaudio/src/sydney_audio_mac.c
media/libsydneyaudio/src/sydney_audio_os2.c
media/libsydneyaudio/src/sydney_audio_oss.c
media/libsydneyaudio/src/sydney_audio_pulseaudio.c
media/libsydneyaudio/src/sydney_audio_sunaudio.c
media/libsydneyaudio/src/sydney_audio_waveapi.c
media/libtheora/Makefile.in
media/libtheora/include/Makefile.in
media/libtremor/Makefile.in
media/libvorbis/Makefile.in
media/libvorbis/include/Makefile.in
mobile/android/base/NotificationHandler.java.in
modules/libbz2/Makefile.in
modules/libjar/zipwriter/Makefile.in
modules/libjar/zipwriter/public/Makefile.in
modules/libmar/Makefile.in
modules/libpref/Makefile.in
modules/zlib/Makefile.in
netwerk/system/Makefile.in
parser/htmlparser/Makefile.in
parser/xml/public/Makefile.in
profile/Makefile.in
profile/dirserviceprovider/Makefile.in
profile/public/Makefile.in
rdf/Makefile.in
rdf/util/Makefile.in
security/manager/boot/Makefile.in
security/manager/pki/Makefile.in
security/manager/ssl/Makefile.in
security/manager/ssl/tests/mochitest/Makefile.in
storage/Makefile.in
toolkit/components/exthelper/Makefile.in
toolkit/components/startup/public/Makefile.in
view/Makefile.in
xpcom/reflect/Makefile.in
xpcom/reflect/xptcall/Makefile.in
xpcom/reflect/xptinfo/Makefile.in
xpcom/string/Makefile.in
xpcom/system/Makefile.in
xpcom/typelib/Makefile.in
xpcom/typelib/xpt/Makefile.in
xpfe/appshell/Makefile.in
xpfe/components/Makefile.in
xpfe/components/autocomplete/public/Makefile.in
xpfe/components/autocomplete/test/Makefile.in
--- a/CLOBBER
+++ b/CLOBBER
@@ -14,9 +14,9 @@
 #          O <-- Clobber   O  <-- Clobber
 #
 # Note: The description below will be part of the error message shown to users.
 #
 #  *** Important! ***
 #  If changing this file you must manually clobber immediately before landing,
 #  (due to bug 837323), using: https://secure.pub.build.mozilla.org/clobberer/
 #
-Bug 851908 - The WebIDL build system still has some problems.
+Bug 844654 changed all the Makefiles.
deleted file mode 100644
--- a/accessible/Makefile.in
+++ /dev/null
@@ -1,16 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-DEPTH   = @DEPTH@
-topsrcdir = @top_srcdir@
-srcdir    = @srcdir@
-VPATH   = @srcdir@
-
-include $(DEPTH)/config/autoconf.mk
-
-MODULE	= accessibility
-
-include $(topsrcdir)/config/rules.mk
-
--- a/accessible/build/Makefile.in
+++ b/accessible/build/Makefile.in
@@ -5,17 +5,16 @@
 
 DEPTH		= @DEPTH@
 topsrcdir	= @top_srcdir@
 srcdir	= @srcdir@
 VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
-MODULE		= accessibility
 LIBRARY_NAME	= accessibility
 EXPORT_LIBRARY = 1
 SHORT_LIBNAME	= access
 IS_COMPONENT	= 1
 MODULE_NAME	= nsAccessibilityModule
 GRE_MODULE	= 1
 LIBXUL_LIBRARY	= 1
 
--- a/accessible/build/moz.build
+++ b/accessible/build/moz.build
@@ -1,5 +1,7 @@
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+MODULE = 'accessibility'
+
--- a/accessible/moz.build
+++ b/accessible/moz.build
@@ -1,7 +1,10 @@
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 DIRS += ['public', 'src', 'build']
 TEST_DIRS += ['tests']
+
+MODULE = 'accessibility'
+
--- a/accessible/public/Makefile.in
+++ b/accessible/public/Makefile.in
@@ -5,17 +5,16 @@
 
 DEPTH   = @DEPTH@
 topsrcdir = @top_srcdir@
 srcdir    = @srcdir@
 VPATH   = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
-MODULE    = accessibility
 GRE_MODULE	= 1
 
 EXPORTS		= \
       nsIAccessibilityService.h \
       $(NULL)
 
 include $(topsrcdir)/config/rules.mk
 
--- a/accessible/public/ia2/Makefile.in
+++ b/accessible/public/ia2/Makefile.in
@@ -3,17 +3,16 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 DEPTH     = @DEPTH@
 topsrcdir = @top_srcdir@
 srcdir    = @srcdir@
 VPATH     = @srcdir@
 
 LIBRARY_NAME  = IA2Marshal
-MODULE        = accessibility
 GRE_MODULE    = 1
 DEFFILE       = $(win_srcdir)/IA2Marshal.def
 
 IA2DIR        = $(topsrcdir)/other-licenses/ia2
 
 include $(DEPTH)/config/autoconf.mk
 
 DEFINES       += -DREGISTER_PROXY_DLL
--- a/accessible/public/ia2/moz.build
+++ b/accessible/public/ia2/moz.build
@@ -1,5 +1,7 @@
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+MODULE = 'accessibility'
+
--- a/accessible/public/moz.build
+++ b/accessible/public/moz.build
@@ -31,8 +31,10 @@ XPIDL_SOURCES += [
     'nsIAccessibleStates.idl',
     'nsIAccessibleTable.idl',
     'nsIAccessibleText.idl',
     'nsIAccessibleTypes.idl',
     'nsIAccessibleValue.idl',
     'nsIXBLAccessible.idl',
 ]
 
+MODULE = 'accessibility'
+
--- a/accessible/public/msaa/Makefile.in
+++ b/accessible/public/msaa/Makefile.in
@@ -3,17 +3,16 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 DEPTH		= @DEPTH@
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 
 LIBRARY_NAME	= AccessibleMarshal
-MODULE    = accessibility
 GRE_MODULE   = 1
 DEFFILE = $(win_srcdir)/AccessibleMarshal.def
 
 include $(DEPTH)/config/autoconf.mk
 
 DEFINES += -DREGISTER_PROXY_DLL
 
 GARBAGE += $(MIDL_GENERATED_FILES) done_gen dlldata.c
--- a/accessible/public/msaa/moz.build
+++ b/accessible/public/msaa/moz.build
@@ -1,5 +1,7 @@
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+MODULE = 'accessibility'
+
--- a/accessible/src/atk/Makefile.in
+++ b/accessible/src/atk/Makefile.in
@@ -4,17 +4,16 @@
 
 DEPTH = @DEPTH@
 topsrcdir = @top_srcdir@
 srcdir = @srcdir@
 VPATH = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
-MODULE = accessibility
 LIBRARY_NAME = accessibility_toolkit_s
 EXPORT_LIBRARY = ..
 LIBXUL_LIBRARY = 1
 
 
 CPPSRCS = \
   AccessibleWrap.cpp \
   ApplicationAccessibleWrap.cpp \
--- a/accessible/src/atk/moz.build
+++ b/accessible/src/atk/moz.build
@@ -1,5 +1,7 @@
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+MODULE = 'accessibility'
+
--- a/accessible/src/base/Makefile.in
+++ b/accessible/src/base/Makefile.in
@@ -4,17 +4,16 @@
 
 DEPTH = @DEPTH@
 topsrcdir = @top_srcdir@
 srcdir = @srcdir@
 VPATH = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
-MODULE = accessibility
 LIBRARY_NAME = accessibility_base_s
 LIBXUL_LIBRARY = 1
 
 
 CPPSRCS = \
   AccCollector.cpp \
   AccEvent.cpp \
   AccGroupInfo.cpp \
--- a/accessible/src/base/moz.build
+++ b/accessible/src/base/moz.build
@@ -1,5 +1,7 @@
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+MODULE = 'accessibility'
+
--- a/accessible/src/generic/Makefile.in
+++ b/accessible/src/generic/Makefile.in
@@ -4,17 +4,16 @@
 
 DEPTH = @DEPTH@
 topsrcdir = @top_srcdir@
 srcdir = @srcdir@
 VPATH = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
-MODULE = accessibility
 LIBRARY_NAME = accessibility_generic_s
 LIBXUL_LIBRARY = 1
 
 
 CPPSRCS = \
   Accessible.cpp \
   ApplicationAccessible.cpp \
   ARIAGridAccessible.cpp \
--- a/accessible/src/generic/RootAccessible.h
+++ b/accessible/src/generic/RootAccessible.h
@@ -4,17 +4,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_a11y_RootAccessible_h__
 #define mozilla_a11y_RootAccessible_h__
 
 #include "HyperTextAccessible.h"
 #include "DocAccessibleWrap.h"
 
-#include "nsHashtable.h"
 #include "nsIDocument.h"
 #include "nsIDOMEventListener.h"
 
 namespace mozilla {
 namespace a11y {
 
 class RootAccessible : public DocAccessibleWrap,
                        public nsIDOMEventListener
--- a/accessible/src/generic/moz.build
+++ b/accessible/src/generic/moz.build
@@ -1,5 +1,7 @@
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+MODULE = 'accessibility'
+
--- a/accessible/src/html/Makefile.in
+++ b/accessible/src/html/Makefile.in
@@ -5,17 +5,16 @@
 
 DEPTH = @DEPTH@
 topsrcdir = @top_srcdir@
 srcdir = @srcdir@
 VPATH = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
-MODULE = accessibility
 LIBRARY_NAME = accessibility_html_s
 LIBXUL_LIBRARY = 1
 
 
 
 CPPSRCS = \
   HTMLCanvasAccessible.cpp \
   HTMLElementAccessibles.cpp \
--- a/accessible/src/html/moz.build
+++ b/accessible/src/html/moz.build
@@ -1,5 +1,7 @@
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+MODULE = 'accessibility'
+
--- a/accessible/src/jsat/moz.build
+++ b/accessible/src/jsat/moz.build
@@ -1,5 +1,7 @@
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+MODULE = 'alerts'
+
--- a/accessible/src/mac/Makefile.in
+++ b/accessible/src/mac/Makefile.in
@@ -4,17 +4,16 @@
 
 DEPTH = @DEPTH@
 topsrcdir = @top_srcdir@
 srcdir = @srcdir@
 VPATH = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
-MODULE = accessibility
 LIBRARY_NAME = accessibility_toolkit_s
 EXPORT_LIBRARY = ..
 LIBXUL_LIBRARY = 1
 
 CMMSRCS = \
           AccessibleWrap.mm \
           DocAccessibleWrap.mm \
           mozAccessible.mm \
--- a/accessible/src/mac/moz.build
+++ b/accessible/src/mac/moz.build
@@ -1,5 +1,7 @@
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+MODULE = 'accessibility'
+
--- a/accessible/src/other/Makefile.in
+++ b/accessible/src/other/Makefile.in
@@ -4,17 +4,16 @@
 
 DEPTH = @DEPTH@
 topsrcdir = @top_srcdir@
 srcdir = @srcdir@
 VPATH = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
-MODULE = accessibility
 LIBRARY_NAME = accessibility_toolkit_s
 EXPORT_LIBRARY = ..
 LIBXUL_LIBRARY = 1
 
 
 CPPSRCS = \
   AccessibleWrap.cpp \
   Platform.cpp \
--- a/accessible/src/other/moz.build
+++ b/accessible/src/other/moz.build
@@ -1,5 +1,7 @@
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+MODULE = 'accessibility'
+
--- a/accessible/src/windows/ia2/Makefile.in
+++ b/accessible/src/windows/ia2/Makefile.in
@@ -4,17 +4,16 @@
 
 DEPTH = @DEPTH@
 topsrcdir = @top_srcdir@
 srcdir = @srcdir@
 VPATH = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
-MODULE = accessibility
 LIBRARY_NAME = accessibility_toolkit_ia2_s
 EXPORT_LIBRARY = 1
 LIBXUL_LIBRARY = 1
 
 
 CPPSRCS += \
   ia2AccessibleAction.cpp \
   ia2AccessibleComponent.cpp \
--- a/accessible/src/windows/ia2/moz.build
+++ b/accessible/src/windows/ia2/moz.build
@@ -1,5 +1,7 @@
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+MODULE = 'accessibility'
+
--- a/accessible/src/windows/msaa/Makefile.in
+++ b/accessible/src/windows/msaa/Makefile.in
@@ -4,17 +4,16 @@
 
 DEPTH = @DEPTH@
 topsrcdir = @top_srcdir@
 srcdir = @srcdir@
 VPATH = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
-MODULE = accessibility
 LIBRARY_NAME = accessibility_toolkit_msaa_s
 EXPORT_LIBRARY = 1
 LIBXUL_LIBRARY = 1
 
 
 CPPSRCS = \
   AccessibleWrap.cpp \
   ApplicationAccessibleWrap.cpp \
--- a/accessible/src/windows/msaa/moz.build
+++ b/accessible/src/windows/msaa/moz.build
@@ -1,5 +1,7 @@
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+MODULE = 'accessibility'
+
--- a/accessible/src/windows/sdn/Makefile.in
+++ b/accessible/src/windows/sdn/Makefile.in
@@ -4,17 +4,16 @@
 
 DEPTH = @DEPTH@
 topsrcdir = @top_srcdir@
 srcdir = @srcdir@
 VPATH = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
-MODULE = accessibility
 LIBRARY_NAME = accessibility_toolkit_sdn_s
 EXPORT_LIBRARY = 1
 LIBXUL_LIBRARY = 1
 # The midl generated code include Windows headers which defines min and max
 # macros which conflicts with std::min/max.  Suppress the macros:
 OS_CXXFLAGS += -DNOMINMAX
 
 CPPSRCS += \
--- a/accessible/src/windows/sdn/moz.build
+++ b/accessible/src/windows/sdn/moz.build
@@ -1,5 +1,7 @@
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+MODULE = 'accessibility'
+
--- a/accessible/src/windows/uia/Makefile.in
+++ b/accessible/src/windows/uia/Makefile.in
@@ -4,17 +4,16 @@
 
 DEPTH = @DEPTH@
 topsrcdir = @top_srcdir@
 srcdir = @srcdir@
 VPATH = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
-MODULE = accessibility
 LIBRARY_NAME = accessibility_toolkit_uia_s
 EXPORT_LIBRARY = ..
 LIBXUL_LIBRARY = 1
 # The midl generated code include Windows headers which defines min and max
 # macros which conflicts with std::min/max.  Suppress the macros:
 OS_CXXFLAGS += -DNOMINMAX
 
 
--- a/accessible/src/windows/uia/moz.build
+++ b/accessible/src/windows/uia/moz.build
@@ -1,5 +1,7 @@
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+MODULE = 'accessibility'
+
--- a/accessible/src/xpcom/Makefile.in
+++ b/accessible/src/xpcom/Makefile.in
@@ -5,17 +5,16 @@
 
 DEPTH = @DEPTH@
 topsrcdir = @top_srcdir@
 srcdir = @srcdir@
 VPATH = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
-MODULE = accessibility
 LIBRARY_NAME = accessibility_xpcom_s
 LIBXUL_LIBRARY = 1
 
 EXPORTS := xpcAccEvents.h
 
 CPPSRCS = \
   xpcAccEvents.cpp \
   nsAccessibleRelation.cpp \
--- a/accessible/src/xpcom/moz.build
+++ b/accessible/src/xpcom/moz.build
@@ -1,5 +1,7 @@
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+MODULE = 'accessibility'
+
--- a/accessible/src/xul/Makefile.in
+++ b/accessible/src/xul/Makefile.in
@@ -5,17 +5,16 @@
 
 DEPTH = @DEPTH@
 topsrcdir = @top_srcdir@
 srcdir = @srcdir@
 VPATH = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
-MODULE = accessibility
 LIBRARY_NAME = accessibility_xul_s
 LIBXUL_LIBRARY = 1
 
 
 
 CPPSRCS = \
   XULAlertAccessible.cpp \
   XULColorPickerAccessible.cpp \
--- a/accessible/src/xul/moz.build
+++ b/accessible/src/xul/moz.build
@@ -1,5 +1,7 @@
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+MODULE = 'accessibility'
+
deleted file mode 100644
--- a/accessible/tests/Makefile.in
+++ /dev/null
@@ -1,16 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-DEPTH   = @DEPTH@
-topsrcdir = @top_srcdir@
-srcdir    = @srcdir@
-VPATH   = @srcdir@
-
-include $(DEPTH)/config/autoconf.mk
-
-MODULE	= test_accessibility
-
-include $(topsrcdir)/config/rules.mk
-
--- a/accessible/tests/mochitest/actions/moz.build
+++ b/accessible/tests/mochitest/actions/moz.build
@@ -1,5 +1,7 @@
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+MODULE = 'alerts'
+
--- a/accessible/tests/moz.build
+++ b/accessible/tests/moz.build
@@ -1,6 +1,9 @@
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 DIRS += ['mochitest']
+
+MODULE = 'test_accessibility'
+
--- a/addon-sdk/source/doc/module-source/sdk/core/promise.md
+++ b/addon-sdk/source/doc/module-source/sdk/core/promise.md
@@ -216,16 +216,43 @@ This technique is so powerful that it ca
 functions provided by other promise libraries. For example grouping promises
 to observe single resolution of all of them is as simple as this:
 
     var group = promised(Array);
     var abc = group(aAsync, bAsync, cAsync).then(function(items) {
       return items[0] + items[1] + items[2];
     });
 
+## all
+
+The `all` function is provided to consume an array of promises and return 
+a promise that will be accepted upon the acceptance of all the promises
+in the initial array. This can be used to perform an action that requires
+values from several promises, like getting user information and server
+status, for example:
+
+    const { all } = require('sdk/core/promise');
+    all([getUser, getServerStatus]).then(function (result) {
+      return result[0] + result[1]
+    });
+
+If one of the promises in the array is rejected, the rejection handler 
+handles the first failed promise and remaining promises remain unfulfilled.
+
+    const { all } = require('sdk/core/promise');
+    all([aAsync, failAsync, bAsync]).then(function (result) {
+      // success function will not be called
+      return result;
+    }, function (reason) {
+      // rejection handler called because `failAsync` promise
+      // was rejected with its reason propagated
+      return reason;
+    });
+
+
 # Making promises
 
 Everything above assumes you get a promise from somewhere else. This
 is the common case, but every once in a while, you will need to create a
 promise from scratch. Add-on SDK's `promise` module provides API for doing
 that.
 
 ## defer
new file mode 100644
--- /dev/null
+++ b/addon-sdk/source/lib/method/.travis.yml
@@ -0,0 +1,5 @@
+language: node_js
+node_js:
+  - 0.4
+  - 0.5
+  - 0.6
new file mode 100644
--- /dev/null
+++ b/addon-sdk/source/lib/method/History.md
@@ -0,0 +1,55 @@
+# Changes
+
+## 1.0.2 / 2012-12-26
+
+  - Delegate to polymorphic methods from `.define` and `.implement` so, they
+    can be overidden.
+
+## 1.0.1 / 2012-11-11
+
+  - Fix issues with different `Error` types as they all inherit from
+    `Error`.
+
+## 1.0.0 / 2012-11-09
+
+  - Add browser test integration.
+  - Fix cross-browser incompatibilities & test failures.
+  - Add support for host objects.
+  - Add optional `hint` argument for method to ease debugging.
+  - Remove default implementation at definition time.
+
+## 0.1.1 / 2012-10-15
+
+ - Fix regression causing custom type implementation to be stored on objects.
+
+## 0.1.0 / 2012-10-15
+
+ - Remove dependency on name module.
+ - Implement fallback for engines that do not support ES5.
+ - Add support for built-in type extensions without extending their prototypes.
+ - Make API for default definitions more intuitive.
+   Skipping type argument now defines default:
+
+      isFoo.define(function(value) {
+        return false
+      })
+
+ - Make exposed `define` and `implement` polymorphic.
+ - Removed dev dependency on swank-js.
+ - Primitive types `string, number, boolean` no longer inherit method
+   implementations from `Object`.
+
+## 0.0.3 / 2012-07-17
+
+  - Remove module boilerplate
+
+## 0.0.2 / 2012-06-26
+
+  - Name changes to make it less conflicting with other library conventions.
+  - Expose function version of `define` & `implement` methods.
+  - Expose `Null` and `Undefined` object holding implementations for an
+    associated types.
+
+## 0.0.1 / 2012-06-25
+
+  - Initial release
new file mode 100644
--- /dev/null
+++ b/addon-sdk/source/lib/method/License.md
@@ -0,0 +1,18 @@
+Copyright 2012 Irakli Gozalishvili. All rights reserved.
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to
+deal in the Software without restriction, including without limitation the
+rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+IN THE SOFTWARE.
new file mode 100644
--- /dev/null
+++ b/addon-sdk/source/lib/method/Readme.md
@@ -0,0 +1,117 @@
+# method
+
+[![Build Status](https://secure.travis-ci.org/Gozala/method.png)](http://travis-ci.org/Gozala/method)
+
+Library provides an API for defining polymorphic methods that dispatch on the
+first argument type. This provides a powerful way for decouple abstraction
+interface definition from an actual implementation per type, without risks
+of interference with other libraries.
+
+### Motivation
+
+  - Provide a high-performance, dynamic polymorphism construct as an
+    alternative to existing object methods that does not provides any
+    mechanics for guarding against name conflicts.
+  - Allow independent extension of types, and implementations of methods
+    on types, by different parties.
+
+## Install
+
+    npm install method
+
+## Use
+
+```js
+var method = require("method")
+
+// Define `isWatchable` method that can be implemented for any type.
+var isWatchable = method("isWatchable")
+
+// If you call it on any object it will
+// throw as nothing implements that method yet.
+//isWatchable({}) // => Exception: method is not implemented
+
+// If you define private method on `Object.prototype`
+// all objects will inherit it.
+Object.prototype[isWatchable] = function() {
+  return false;
+}
+
+isWatchable({}) // => false
+
+
+// Although `isWatchable` property above will be enumerable and there for
+// may damage some assumbtions made by other libraries. There for it"s
+// recomended to use built-in helpers methods that will define extension
+// without breaking assumbtions made by other libraries:
+
+isWatchable.define(Object, function() { return false })
+
+
+// There are primitive types in JS that won"t inherit methods from Object:
+isWatchable(null) // => Exception: method is not implemented
+
+// One could either implement methods for such types:
+isWatchable.define(null, function() { return false })
+isWatchable.define(undefined, function() { return false })
+
+// Or simply define default implementation:
+isWatchable.define(function() { return false })
+
+// Alternatively default implementation may be provided at creation:
+isWatchable = method(function() { return false })
+
+// Method dispatches on an first argument type. That allows us to create
+// new types with an alternative implementations:
+function Watchable() {}
+isWatchable.define(Watchable, function() { return true })
+
+// This will make all `Watchable` instances watchable!
+isWatchable(new Watchable()) // => true
+
+// Arbitrary objects can also be extended to implement given method. For example
+// any object can simply made watchable:
+function watchable(object) {
+  return isWatchable.implement(objct, function() { return true })
+}
+
+isWatchable(watchable({})) // => true
+
+// Full protocols can be defined with such methods:
+var observers = "observers@" + module.filename
+var watchers = method("watchers")
+var watch = method("watch")
+var unwatch = method("unwatch")
+
+watchers.define(Watchable, function(target) {
+  return target[observers] || (target[observers] = [])
+})
+
+watch.define(Watchable, function(target, watcher) {
+  var observers = watchers(target)
+  if (observers.indexOf(watcher) < 0) observers.push(watcher)
+  return target
+})
+unwatch.define(Watchable, function(target, watcher) {
+  var observers = watchers(target)
+  var index = observers.indexOf(watcher)
+  if (observers.indexOf(watcher) >= 0) observers.unshift(watcher)
+  return target
+})
+
+// Define type Port that inherits form Watchable
+
+function Port() {}
+Port.prototype = Object.create(Watchable.prototype)
+
+var emit = method("emit")
+emit.define(Port, function(port, message) {
+  watchers(port).slice().forEach(function(watcher) {
+    watcher(message)
+  })
+})
+
+var p = new Port()
+watch(p, console.log)
+emit(p, "hello world") // => info: "hello world"
+```
new file mode 100644
--- /dev/null
+++ b/addon-sdk/source/lib/method/core.js
@@ -0,0 +1,225 @@
+"use strict";
+
+var defineProperty = Object.defineProperty || function(object, name, property) {
+  object[name] = property.value
+  return object
+}
+
+// Shortcut for `Object.prototype.toString` for faster access.
+var typefy = Object.prototype.toString
+
+// Map to for jumping from typeof(value) to associated type prefix used
+// as a hash in the map of builtin implementations.
+var types = { "function": "Object", "object": "Object" }
+
+// Array is used to save method implementations for the host objects in order
+// to avoid extending them with non-primitive values that could cause leaks.
+var host = []
+// Hash map is used to save method implementations for builtin types in order
+// to avoid extending their prototypes. This also allows to share method
+// implementations for types across diff contexts / frames / compartments.
+var builtin = {}
+
+function Primitive() {}
+function ObjectType() {}
+ObjectType.prototype = new Primitive()
+function ErrorType() {}
+ErrorType.prototype = new ObjectType()
+
+var Default = builtin.Default = Primitive.prototype
+var Null = builtin.Null = new Primitive()
+var Void = builtin.Void = new Primitive()
+builtin.String = new Primitive()
+builtin.Number = new Primitive()
+builtin.Boolean = new Primitive()
+
+builtin.Object = ObjectType.prototype
+builtin.Error = ErrorType.prototype
+
+builtin.EvalError = new ErrorType()
+builtin.InternalError = new ErrorType()
+builtin.RangeError = new ErrorType()
+builtin.ReferenceError = new ErrorType()
+builtin.StopIteration = new ErrorType()
+builtin.SyntaxError = new ErrorType()
+builtin.TypeError = new ErrorType()
+builtin.URIError = new ErrorType()
+
+
+function Method(hint) {
+  /**
+  Private Method is a callable private name that dispatches on the first
+  arguments same named Method:
+
+      method(object, ...rest) => object[method](...rest)
+
+  Optionally hint string may be provided that will be used in generated names
+  to ease debugging.
+
+  ## Example
+
+      var foo = Method()
+
+      // Implementation for any types
+      foo.define(function(value, arg1, arg2) {
+        // ...
+      })
+
+      // Implementation for a specific type
+      foo.define(BarType, function(bar, arg1, arg2) {
+        // ...
+      })
+  **/
+
+  // Create an internal unique name if `hint` is provided it is used to
+  // prefix name to ease debugging.
+  var name = (hint || "") + "#" + Math.random().toString(32).substr(2)
+
+  function dispatch(value) {
+    // Method dispatches on type of the first argument.
+    // If first argument is `null` or `void` associated implementation is
+    // looked up in the `builtin` hash where implementations for built-ins
+    // are stored.
+    var type = null
+    var method = value === null ? Null[name] :
+                 value === void(0) ? Void[name] :
+                 // Otherwise attempt to use method with a generated private
+                 // `name` that is supposedly in the prototype chain of the
+                 // `target`.
+                 value[name] ||
+                 // Otherwise assume it's one of the built-in type instances,
+                 // in which case implementation is stored in a `builtin` hash.
+                 // Attempt to find a implementation for the given built-in
+                 // via constructor name and method name.
+                 ((type = builtin[(value.constructor || "").name]) &&
+                  type[name]) ||
+                 // Otherwise assume it's a host object. For host objects
+                 // actual method implementations are stored in the `host`
+                 // array and only index for the implementation is stored
+                 // in the host object's prototype chain. This avoids memory
+                 // leaks that otherwise could happen when saving JS objects
+                 // on host object.
+                 host[value["!" + name]] ||
+                 // Otherwise attempt to lookup implementation for builtins by
+                 // a type of the value. This basically makes sure that all
+                 // non primitive values will delegate to an `Object`.
+                 ((type = builtin[types[typeof(value)]]) && type[name])
+
+
+    // If method implementation for the type is still not found then
+    // just fallback for default implementation.
+    method = method || Default[name]
+
+
+    // If implementation is still not found (which also means there is no
+    // default) just throw an error with a descriptive message.
+    if (!method) throw TypeError("Type does not implements method: " + name)
+
+    // If implementation was found then just delegate.
+    return method.apply(method, arguments)
+  }
+
+  // Make `toString` of the dispatch return a private name, this enables
+  // method definition without sugar:
+  //
+  //    var method = Method()
+  //    object[method] = function() { /***/ }
+  dispatch.toString = function toString() { return name }
+
+  // Copy utility methods for convenient API.
+  dispatch.implement = implementMethod
+  dispatch.define = defineMethod
+
+  return dispatch
+}
+
+// Create method shortcuts form functions.
+var defineMethod = function defineMethod(Type, lambda) {
+  return define(this, Type, lambda)
+}
+var implementMethod = function implementMethod(object, lambda) {
+  return implement(this, object, lambda)
+}
+
+// Define `implement` and `define` polymorphic methods to allow definitions
+// and implementations through them.
+var implement = Method("implement")
+var define = Method("define")
+
+
+function _implement(method, object, lambda) {
+  /**
+  Implements `Method` for the given `object` with a provided `implementation`.
+  Calling `Method` with `object` as a first argument will dispatch on provided
+  implementation.
+  **/
+  return defineProperty(object, method.toString(), {
+    enumerable: false,
+    configurable: false,
+    writable: false,
+    value: lambda
+  })
+}
+
+function _define(method, Type, lambda) {
+  /**
+  Defines `Method` for the given `Type` with a provided `implementation`.
+  Calling `Method` with a first argument of this `Type` will dispatch on
+  provided `implementation`. If `Type` is a `Method` default implementation
+  is defined. If `Type` is a `null` or `undefined` `Method` is implemented
+  for that value type.
+  **/
+
+  // Attempt to guess a type via `Object.prototype.toString.call` hack.
+  var type = Type && typefy.call(Type.prototype)
+
+  // If only two arguments are passed then `Type` is actually an implementation
+  // for a default type.
+  if (!lambda) Default[method] = Type
+  // If `Type` is `null` or `void` store implementation accordingly.
+  else if (Type === null) Null[method] = lambda
+  else if (Type === void(0)) Void[method] = lambda
+  // If `type` hack indicates built-in type and type has a name us it to
+  // store a implementation into associated hash. If hash for this type does
+  // not exists yet create one.
+  else if (type !== "[object Object]" && Type.name) {
+    var Bulitin = builtin[Type.name] || (builtin[Type.name] = new ObjectType())
+    Bulitin[method] = lambda
+  }
+  // If `type` hack indicates an object, that may be either object or any
+  // JS defined "Class". If name of the constructor is `Object`, assume it's
+  // built-in `Object` and store implementation accordingly.
+  else if (Type.name === "Object")
+    builtin.Object[method] = lambda
+  // Host objects are pain!!! Every browser does some crazy stuff for them
+  // So far all browser seem to not implement `call` method for host object
+  // constructors. If that is a case here, assume it's a host object and
+  // store implementation in a `host` array and store `index` in the array
+  // in a `Type.prototype` itself. This avoids memory leaks that could be
+  // caused by storing JS objects on a host objects.
+  else if (Type.call === void(0)) {
+    var index = host.indexOf(lambda)
+    if (index < 0) index = host.push(lambda) - 1
+    // Prefix private name with `!` so it can be dispatched from the method
+    // without type checks.
+    implement("!" + method, Type.prototype, index)
+  }
+  // If Got that far `Type` is user defined JS `Class`. Define private name
+  // as hidden property on it's prototype.
+  else
+    implement(method, Type.prototype, lambda)
+}
+
+// And provided implementations for a polymorphic equivalents.
+_define(define, _define)
+_define(implement, _implement)
+
+// Define exports on `Method` as it's only thing being exported.
+Method.implement = implement
+Method.define = define
+Method.Method = Method
+Method.method = Method
+Method.builtin = builtin
+Method.host = host
+
+module.exports = Method
new file mode 100644
--- /dev/null
+++ b/addon-sdk/source/lib/method/package.json
@@ -0,0 +1,41 @@
+{
+  "name": "method",
+  "id": "method",
+  "version": "1.0.2",
+  "description": "Functional polymorphic method dispatch",
+  "keywords": [
+    "method",
+    "dispatch",
+    "protocol",
+    "polymorphism",
+    "type dispatch"
+  ],
+  "author": "Irakli Gozalishvili <rfobic@gmail.com> (http://jeditoolkit.com)",
+  "homepage": "https://github.com/Gozala/method",
+  "main": "./core.js",
+  "repository": {
+    "type": "git",
+    "url": "https://github.com/Gozala/method.git",
+    "web": "https://github.com/Gozala/method"
+  },
+  "bugs": {
+    "url": "http://github.com/Gozala/method/issues/"
+  },
+  "devDependencies": {
+    "test": "~0.x.0",
+    "repl-utils": "~2.0.1",
+    "phantomify": "~0.1.0"
+  },
+  "scripts": {
+    "test": "npm run test-node && npm run test-browser",
+    "test-browser": "node ./node_modules/phantomify/bin/cmd.js ./test/browser.js",
+    "test-node": "node ./test/common.js",
+    "repl": "node node_modules/repl-utils"
+  },
+  "licenses": [
+    {
+      "type": "MIT",
+      "url": "https://github.com/Gozala/method/License.md"
+    }
+  ]
+}
new file mode 100644
--- /dev/null
+++ b/addon-sdk/source/lib/method/test/browser.js
@@ -0,0 +1,20 @@
+"use strict";
+
+exports["test common"] = require("./common")
+
+var Method = require("../core")
+
+exports["test host objects"] = function(assert) {
+  var isElement = Method("is-element")
+  isElement.define(function() { return false })
+
+  isElement.define(Element, function() { return true })
+
+  assert.notDeepEqual(typeof(Element.prototype[isElement]), "number",
+                     "Host object's prototype is extended with a number value")
+
+  assert.ok(!isElement({}), "object is not an Element")
+  assert.ok(document.createElement("div"), "Element is an element")
+}
+
+require("test").run(exports)
new file mode 100644
--- /dev/null
+++ b/addon-sdk/source/lib/method/test/common.js
@@ -0,0 +1,272 @@
+"use strict";
+
+var Method = require("../core")
+
+function type(value) {
+  return Object.prototype.toString.call(value).
+    split(" ").
+    pop().
+    split("]").
+    shift().
+    toLowerCase()
+}
+
+var values = [
+  null,                   // 0
+  undefined,              // 1
+  Infinity,               // 2
+  NaN,                    // 3
+  5,                      // 4
+  {},                     // 5
+  Object.create({}),      // 6
+  Object.create(null),    // 7
+  [],                     // 8
+  /foo/,                  // 9
+  new Date(),             // 10
+  Function,               // 11
+  function() {},          // 12
+  true,                   // 13
+  false,                  // 14
+  "string"                // 15
+]
+
+function True() { return true }
+function False() { return false }
+
+var trues = values.map(True)
+var falses = values.map(False)
+
+exports["test throws if not implemented"] = function(assert) {
+  var method = Method("nope")
+
+  assert.throws(function() {
+    method({})
+  }, /not implement/i, "method throws if not implemented")
+
+  assert.throws(function() {
+    method(null)
+  }, /not implement/i, "method throws on null")
+}
+
+exports["test all types inherit from default"] = function(assert) {
+  var isImplemented = Method("isImplemented")
+  isImplemented.define(function() { return true })
+
+  values.forEach(function(value) {
+    assert.ok(isImplemented(value),
+              type(value) + " inherits deafult implementation")
+  })
+}
+
+exports["test default can be implemented later"] = function(assert) {
+  var isImplemented = Method("isImplemented")
+  isImplemented.define(function() {
+    return true
+  })
+
+  values.forEach(function(value) {
+    assert.ok(isImplemented(value),
+              type(value) + " inherits deafult implementation")
+  })
+}
+
+exports["test dispatch not-implemented"] = function(assert) {
+  var isDefault = Method("isDefault")
+  values.forEach(function(value) {
+    assert.throws(function() {
+      isDefault(value)
+    }, /not implement/, type(value) + " throws if not implemented")
+  })
+}
+
+exports["test dispatch default"] = function(assert) {
+  var isDefault = Method("isDefault")
+
+  // Implement default
+  isDefault.define(True)
+  assert.deepEqual(values.map(isDefault), trues,
+                   "all implementation inherit from default")
+
+}
+
+exports["test dispatch null"] = function(assert) {
+  var isNull = Method("isNull")
+
+  // Implement default
+  isNull.define(False)
+  isNull.define(null, True)
+  assert.deepEqual(values.map(isNull),
+                   [ true ].
+                   concat(falses.slice(1)),
+                   "only null gets methods defined for null")
+}
+
+exports["test dispatch undefined"] = function(assert) {
+  var isUndefined = Method("isUndefined")
+
+  // Implement default
+  isUndefined.define(False)
+  isUndefined.define(undefined, True)
+  assert.deepEqual(values.map(isUndefined),
+                   [ false, true ].
+                   concat(falses.slice(2)),
+                   "only undefined gets methods defined for undefined")
+}
+
+exports["test dispatch object"] = function(assert) {
+  var isObject = Method("isObject")
+
+  // Implement default
+  isObject.define(False)
+  isObject.define(Object, True)
+  assert.deepEqual(values.map(isObject),
+                   [ false, false, false, false, false ].
+                   concat(trues.slice(5, 13)).
+                   concat([false, false, false]),
+                   "all values except primitives inherit Object methods")
+
+}
+
+exports["test dispatch number"] = function(assert) {
+  var isNumber = Method("isNumber")
+  isNumber.define(False)
+  isNumber.define(Number, True)
+
+  assert.deepEqual(values.map(isNumber),
+                  falses.slice(0, 2).
+                  concat(true, true, true).
+                  concat(falses.slice(5)),
+                  "all numbers inherit from Number method")
+}
+
+exports["test dispatch string"] = function(assert) {
+  var isString = Method("isString")
+  isString.define(False)
+  isString.define(String, True)
+
+  assert.deepEqual(values.map(isString),
+                  falses.slice(0, 15).
+                  concat(true),
+                  "all strings inherit from String method")
+}
+
+exports["test dispatch function"] = function(assert) {
+  var isFunction = Method("isFunction")
+  isFunction.define(False)
+  isFunction.define(Function, True)
+
+  assert.deepEqual(values.map(isFunction),
+                  falses.slice(0, 11).
+                  concat(true, true).
+                  concat(falses.slice(13)),
+                  "all functions inherit from Function method")
+}
+
+exports["test dispatch date"] = function(assert) {
+  var isDate = Method("isDate")
+  isDate.define(False)
+  isDate.define(Date, True)
+
+  assert.deepEqual(values.map(isDate),
+                  falses.slice(0, 10).
+                  concat(true).
+                  concat(falses.slice(11)),
+                  "all dates inherit from Date method")
+}
+
+exports["test dispatch RegExp"] = function(assert) {
+  var isRegExp = Method("isRegExp")
+  isRegExp.define(False)
+  isRegExp.define(RegExp, True)
+
+  assert.deepEqual(values.map(isRegExp),
+                  falses.slice(0, 9).
+                  concat(true).
+                  concat(falses.slice(10)),
+                  "all regexps inherit from RegExp method")
+}
+
+exports["test redefine for descendant"] = function(assert) {
+  var isFoo = Method("isFoo")
+  var ancestor = {}
+  isFoo.implement(ancestor, function() { return true })
+  var descendant = Object.create(ancestor)
+  isFoo.implement(descendant, function() { return false })
+
+  assert.ok(isFoo(ancestor), "defined on ancestor")
+  assert.ok(!isFoo(descendant), "overrided for descendant")
+}
+
+exports["test on custom types"] = function(assert) {
+  function Bar() {}
+  var isBar = Method("isBar")
+
+  isBar.define(function() { return false })
+  isBar.define(Bar, function() { return true })
+
+  assert.ok(!isBar({}), "object is get's default implementation")
+  assert.ok(isBar(new Bar()), "Foo type objects get own implementation")
+
+  var isObject = Method("isObject")
+  isObject.define(function() { return false })
+  isObject.define(Object, function() { return true })
+
+  assert.ok(isObject(new Bar()), "foo inherits implementation from object")
+
+
+  isObject.define(Bar, function() { return false })
+
+  assert.ok(!isObject(new Bar()),
+            "implementation inherited form object can be overrided")
+}
+
+
+exports["test error types"] = function(assert) {
+  var isError = Method("isError")
+  isError.define(function() { return false })
+  isError.define(Error, function() { return true })
+
+  assert.ok(isError(Error("boom")), "error is error")
+  assert.ok(isError(TypeError("boom")), "type error is an error")
+  assert.ok(isError(EvalError("boom")), "eval error is an error")
+  assert.ok(isError(RangeError("boom")), "range error is an error")
+  assert.ok(isError(ReferenceError("boom")), "reference error is an error")
+  assert.ok(isError(SyntaxError("boom")), "syntax error is an error")
+  assert.ok(isError(URIError("boom")), "URI error is an error")
+}
+
+exports["test override define polymorphic method"] = function(assert) {
+  var define = Method.define
+  var implement = Method.implement
+
+  var fn = Method("fn")
+  var methods = {}
+  implement(define, fn, function(method, label, implementation) {
+    methods[label] = implementation
+  })
+
+  function foo() {}
+
+  define(fn, "foo-case", foo)
+
+  assert.equal(methods["foo-case"], foo, "define set property")
+}
+
+exports["test override define via method API"] = function(assert) {
+  var define = Method.define
+  var implement = Method.implement
+
+  var fn = Method("fn")
+  var methods = {}
+  define.implement(fn, function(method, label, implementation) {
+    methods[label] = implementation
+  })
+
+  function foo() {}
+
+  define(fn, "foo-case", foo)
+
+  assert.equal(methods["foo-case"], foo, "define set property")
+}
+
+require("test").run(exports)
--- a/addon-sdk/source/lib/sdk/addon/runner.js
+++ b/addon-sdk/source/lib/sdk/addon/runner.js
@@ -71,29 +71,34 @@ function wait(reason, options) {
 
 function startup(reason, options) {
   if (reason === 'startup')
     return wait(reason, options);
 
   // Inject globals ASAP in order to have console API working ASAP
   Object.defineProperties(options.loader.globals, descriptor(globals));
 
+  // NOTE: Module is intentionally required only now because it relies
+  // on existence of hidden window, which does not exists until startup.
+  let { ready } = require('../addon/window');
   // Load localization manifest and .properties files.
   // Run the addon even in case of error (best effort approach)
   require('../l10n/loader').
     load(rootURI).
     then(null, function failure(error) {
       console.info("Error while loading localization: " + error.message);
     }).
     then(function onLocalizationReady(data) {
       // Exports data to a pseudo module so that api-utils/l10n/core
       // can get access to it
       definePseudo(options.loader, '@l10n/data', data ? data : null);
+      return ready;
+    }).then(function() {
       run(options);
-    });
+    }).then(null, console.exception);
 }
 
 function run(options) {
   try {
     // Try initializing HTML localization before running main module. Just print
     // an exception in case of error, instead of preventing addon to be run.
     try {
       // Do not enable HTML localization while running test as it is hard to
new file mode 100644
--- /dev/null
+++ b/addon-sdk/source/lib/sdk/addon/window.js
@@ -0,0 +1,57 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+"use strict";
+
+module.metadata = {
+  "stability": "experimental"
+};
+
+const { Ci, Cc } = require("chrome");
+const { make: makeWindow, getHiddenWindow } = require("../window/utils");
+const { create: makeFrame, getDocShell } = require("../frame/utils");
+const { defer } = require("../core/promise");
+const { when: unload } = require("../system/unload");
+
+let addonPrincipal = Cc["@mozilla.org/systemprincipal;1"].
+                     createInstance(Ci.nsIPrincipal);
+
+// Once Bug 565388 is fixed and shipped we'll be able to make invisible,
+// permanent docShells. Meanwhile we create hidden top level window and
+// use it's docShell.
+let frame = makeFrame(getHiddenWindow().document, {
+  nodeName: "iframe",
+  namespaceURI: "http://www.w3.org/1999/xhtml",
+  allowJavascript: true,
+  allowPlugins: true
+})
+let docShell = getDocShell(frame);
+let eventTarget = docShell.chromeEventHandler;
+
+// We need to grant docShell system principals in order to load XUL document
+// from data URI into it.
+docShell.createAboutBlankContentViewer(addonPrincipal);
+
+// Get a reference to the DOM window of the given docShell and load
+// such document into that would allow us to create XUL iframes, that
+// are necessary for hidden frames etc..
+let window = docShell.contentViewer.DOMDocument.defaultView;
+window.location = "data:application/vnd.mozilla.xul+xml;charset=utf-8,<window/>";
+
+// Create a promise that is delivered once add-on window is interactive,
+// used by add-on runner to defer add-on loading until window is ready.
+let { promise, resolve } = defer();
+eventTarget.addEventListener("DOMContentLoaded", function handler(event) {
+  eventTarget.removeEventListener("DOMContentLoaded", handler, false);
+  resolve();
+}, false);
+
+
+
+exports.ready = promise;
+exports.window = window;
+
+// Still close window on unload to claim memory back early.
+unload(function() { window.close() });
--- a/addon-sdk/source/lib/sdk/content/symbiont.js
+++ b/addon-sdk/source/lib/sdk/content/symbiont.js
@@ -10,16 +10,17 @@ module.metadata = {
 };
 
 const { Worker } = require('./worker');
 const { Loader } = require('./loader');
 const hiddenFrames = require('../frame/hidden-frame');
 const observers = require('../deprecated/observer-service');
 const unload = require('../system/unload');
 const { getDocShell } = require("../frame/utils");
+const { ignoreWindow } = require('../private-browsing/utils');
 
 const assetsURI = require('../self').data.url();
 
 /**
  * This trait is layered on top of `Worker` and in contrast to symbiont
  * Worker constructor requires `content` option that represents content
  * that will be loaded in the provided frame, if frame is not provided
  * Worker will create hidden one.
@@ -102,16 +103,17 @@ const Symbiont = Worker.resolve({
    * Listener to the `'frameReady"` event (emitted when `iframe` is ready).
    * Removes listener, sets right permissions to the frame and loads content.
    */
   _initFrame: function _initFrame(frame) {
     if (this._loadListener)
       this._unregisterListener();
     
     this._frame = frame;
+
     getDocShell(frame).allowJavascript = this.allow.script;
     frame.setAttribute("src", this._contentURL);
 
     // Inject `addon` object in document if we load a document from
     // one of our addon folder and if no content script are defined. bug 612726
     let isDataResource =
       typeof this._contentURL == "string" &&
       this._contentURL.indexOf(assetsURI) == 0;
@@ -137,18 +139,22 @@ const Symbiont = Worker.resolve({
     }
     
     let self = this;
     
     if ('start' == this.contentScriptWhen) {
       this._loadEvent = 'start';
       observers.add('document-element-inserted', 
         this._loadListener = function onStart(doc) {
-          
           let window = doc.defaultView;
+
+          if (ignoreWindow(window)) {
+            return;
+          }
+
           if (window && window == frame.contentWindow) {
             self._unregisterListener();
             self._onInit();
           }
           
         });
       return;
     }
--- a/addon-sdk/source/lib/sdk/core/heritage.js
+++ b/addon-sdk/source/lib/sdk/core/heritage.js
@@ -93,17 +93,17 @@ var mix = function(source) {
 };
 exports.mix = mix;
 
 /**
  * Returns a frozen object with that inherits from the given `prototype` and
  * implements all own properties of the given `properties` object.
  */
 function extend(prototype, properties) {
-  return freeze(create(prototype, getOwnPropertyDescriptors(properties)));
+  return create(prototype, getOwnPropertyDescriptors(properties));
 }
 exports.extend = extend;
 
 /**
  * Returns a constructor function with a proper `prototype` setup. Returned
  * constructor's `prototype` inherits from a given `options.extends` or
  * `Class.prototype` if omitted and implements all the properties of the
  * given `option`. If `options.implemens` array is passed, it's elements
--- a/addon-sdk/source/lib/sdk/core/promise.js
+++ b/addon-sdk/source/lib/sdk/core/promise.js
@@ -50,34 +50,16 @@ function fulfilled(value) {
  * with a given `reason`. Note the result is not a complete promise
  * implementation, as its method `then` does not returns anything.
  */
 function rejected(reason) {
   return { then: function then(fulfill, reject) { reject(reason); } };
 }
 
 /**
- * Internal utility: Decorates given `f` function, so that on exception promise
- * rejected with thrown error is returned.
- */
-function attempt(f) {
-  return function effort(input) {
-    try {
-      return f(input);
-    }
-    catch(error) {
-      if (exports._reportErrors && typeof(console) === 'object') {
-        console.error(error)
-      }
-      return rejected(error)
-    }
-  };
-}
-
-/**
  * Internal utility: Returns `true` if given `value` is a promise. Value is
  * assumed to be a promise if it implements method `then`.
  */
 function isPromise(value) {
   return value && typeof(value.then) === 'function';
 }
 
 /**
@@ -125,42 +107,57 @@ function defer(prototype) {
 
   prototype = (prototype || prototype === null) ? prototype : Object.prototype
 
   // Create an object implementing promise API.
   var promise = Object.create(prototype, {
     then: { value: function then(onFulfill, onError) {
       var deferred = defer(prototype);
 
-      // Decorate `onFulfill` / `onError` handlers with `attempt`, that
-      // way if wrapped handler throws exception decorator will catch and
-      // return promise rejected with it, which will cause rejection of
-      // `deferred.promise`. If handler is missing, substitute it with an
-      // utility function that takes one argument and returns promise
-      // fulfilled / rejected with it. This takes care of propagation
-      // through the rest of the promise chain.
-      onFulfill = onFulfill ? attempt(onFulfill) : fulfilled;
-      onError = onError ? attempt(onError) : rejected;
+      function resolve(value) {
+        // If `onFulfill` handler is provided resolve `deferred.promise` with
+        // result of invoking it with a resolution value. If handler is not
+        // provided propagate value through.
+        try {
+          deferred.resolve(onFulfill ? onFulfill(value) : value);
+        }
+        // `onFulfill` may throw exception in which case resulting promise
+        // is rejected with thrown exception.
+        catch(error) {
+          if (exports._reportErrors && typeof(console) === 'object')
+            console.error(error);
+          // Note: Following is equivalent of `deferred.reject(error)`,
+          // we use this shortcut to reduce a stack.
+          deferred.resolve(rejected(error));
+        }
+      }
 
-      // Create a pair of observers that invoke given handlers & propagate
-      // results to `deferred.promise`.
-      function resolveDeferred(value) { deferred.resolve(onFulfill(value)); }
-      function rejectDeferred(reason) { deferred.resolve(onError(reason)); }
+      function reject(reason) {
+        try {
+          if (onError) deferred.resolve(onError(reason));
+          else deferred.resolve(rejected(reason));
+        }
+        catch(error) {
+          if (exports._reportErrors && typeof(console) === 'object')
+            console.error(error)
+          deferred.resolve(rejected(error));
+        }
+      }
 
       // If enclosed promise (`this.promise`) observers queue is still alive
       // enqueue a new observer pair into it. Note that this does not
       // necessary means that promise is pending, it may already be resolved,
       // but we still have to queue observers to guarantee an order of
       // propagation.
       if (observers) {
-        observers.push({ resolve: resolveDeferred, reject: rejectDeferred });
+        observers.push({ resolve: resolve, reject: reject });
       }
       // Otherwise just forward observer pair right to a `result` promise.
       else {
-        result.then(resolveDeferred, rejectDeferred);
+        result.then(resolve, reject);
       }
 
       return deferred.promise;
     }}
   })
 
   var deferred = {
     promise: promise,
@@ -284,9 +281,12 @@ var promised = (function() {
         reduce(promisedConcat, resolve([], prototype)).
         // finally map that to promise of `f.apply(this, args...)`
         then(execute)
     }
   }
 })()
 exports.promised = promised;
 
+var all = promised(Array);
+exports.all = all;
+
 });
--- a/addon-sdk/source/lib/sdk/deprecated/unit-test.js
+++ b/addon-sdk/source/lib/sdk/deprecated/unit-test.js
@@ -104,16 +104,18 @@ TestRunner.prototype = {
   expectFail: function(callback) {
     this.expectFailure = true;
     callback();
     this.expectFailure = false;
   },
 
   exception: function exception(e) {
     this._logTestFailed("exception");
+    if (cfxArgs.parseable)
+      this.console.print("TEST-UNEXPECTED-FAIL | " + this.test.name + " | " + e + "\n");
     this.console.exception(e);
     this.failed++;
     this.test.failed++;
   },
 
   assertMatches: function assertMatches(string, regexp, message) {
     if (regexp.test(string)) {
       if (!message)
--- a/addon-sdk/source/lib/sdk/frame/hidden-frame.js
+++ b/addon-sdk/source/lib/sdk/frame/hidden-frame.js
@@ -12,33 +12,20 @@ module.metadata = {
 
 const { Cc, Ci } = require("chrome");
 const errors = require("../deprecated/errors");
 const { Class } = require("../core/heritage");
 const { List, addListItem, removeListItem } = require("../util/list");
 const { EventTarget } = require("../event/target");
 const { emit } = require("../event/core");
 const { create: makeFrame } = require("./utils");
-const { defer, resolve } = require("../core/promise");
+const { defer } = require("../core/promise");
 const { when: unload } = require("../system/unload");
 const { validateOptions, getTypeOf } = require("../deprecated/api-utils");
-
-
-let appShellService = Cc["@mozilla.org/appshell/appShellService;1"].
-                        getService(Ci.nsIAppShellService);
-
-let hiddenWindow = appShellService.hiddenDOMWindow;
-
-if (!hiddenWindow) {
-  throw new Error([
-    "The hidden-frame module needs an app that supports a hidden window. ",
-    "We would like it to support other applications, however. Please see ",
-    "https://bugzilla.mozilla.org/show_bug.cgi?id=546740 for more information."
-  ].join(""));
-}
+const { window } = require("../addon/window");
 
 // This cache is used to access friend properties between functions
 // without exposing them on the public API.
 let cache = [];
 let elements = new WeakMap();
 
 function contentLoaded(target) {
   var deferred = defer();
@@ -48,43 +35,16 @@ function contentLoaded(target) {
     if (event.target === target || event.target === target.contentDocument) {
       target.removeEventListener("DOMContentLoaded", DOMContentLoaded, false);
       deferred.resolve(target);
     }
   }, false);
   return deferred.promise;
 }
 
-function makeHostFrame() {
-  // Check if we can use the hidden window itself to host our iframes.
-  // If it's not a suitable host, the hostFrame will be lazily created
-  // by the first HiddenFrame instance.
-  if (hiddenWindow.location.protocol == "chrome:" &&
-      (hiddenWindow.document.contentType == "application/vnd.mozilla.xul+xml" ||
-      hiddenWindow.document.contentType == "application/xhtml+xml")) {
-
-    // Resolve to an object with a shape similar to iframe.
-    return resolve({ contentDocument: hiddenWindow.document });
-  }
-  else {
-    return contentLoaded(makeFrame(hiddenWindow.document, {
-      // Ugly ugly hack. This is the most lightweight "chrome:" file I could
-      // find on the tree.
-      // This hack should be removed by proper platform support on bug 565388
-      uri: "chrome://global/content/mozilla.xhtml",
-      namespaceURI: hiddenWindow.document.documentElement.namespaceURI,
-      nodeName: "iframe",
-      allowJavascript: true,
-      allowPlugins: true,
-      allowAuth: true
-    }));
-  }
-}
-var hostFrame = makeHostFrame();
-
 function FrameOptions(options) {
   options = options || {}
   return validateOptions(options, FrameOptions.validator);
 }
 FrameOptions.validator = {
   onReady: {
     is: ["undefined", "function", "array"],
     ok: function(v) {
@@ -125,27 +85,26 @@ function isFrameCached(frame) {
 function addHidenFrame(frame) {
   if (!(frame instanceof HiddenFrame))
     throw Error("The object to be added must be a HiddenFrame.");
 
   // This instance was already added.
   if (isFrameCached(frame)) return frame;
   else cache.push(frame);
 
-  hostFrame.then(function({ contentDocument }) {
-    let element = makeFrame(contentDocument, {
-      nodeName: "iframe",
-      type: "content",
-      allowJavascript: true,
-      allowPlugins: true,
-      allowAuth: true,
-    });
-    elements.set(frame, element);
-    return contentLoaded(element);
-  }).then(function onFrameReady(element) {
+  let element = makeFrame(window.document, {
+    nodeName: "iframe",
+    type: "content",
+    allowJavascript: true,
+    allowPlugins: true,
+    allowAuth: true,
+  });
+  elements.set(frame, element);
+
+  contentLoaded(element).then(function onFrameReady(element) {
     emit(frame, "ready");
   }, console.exception);
 
   return frame;
 }
 exports.add = addHidenFrame
 
 function removeHiddenFrame(frame) {
@@ -157,15 +116,9 @@ function removeHiddenFrame(frame) {
   // Remove from cache before calling in order to avoid loop
   cache.splice(cache.indexOf(frame), 1);
   emit(frame, "unload")
   let element = frame.element
   if (element) element.parentNode.removeChild(element)
 }
 exports.remove = removeHiddenFrame;
 
-unload(function () {
-  cache.splice(0).forEach(removeHiddenFrame);
-
-  hostFrame.then(function(host) {
-    if (hast.parentNode) frame.parentNode.removeChild(frame);
-  });
-});
+unload(function() cache.splice(0).forEach(removeHiddenFrame));
--- a/addon-sdk/source/lib/sdk/frame/utils.js
+++ b/addon-sdk/source/lib/sdk/frame/utils.js
@@ -38,36 +38,45 @@ exports.getDocShell = getDocShell;
  * @params {Boolean} options.allowJavascript
  *    Whether to allow Javascript execution. Defaults to `false`.
  * @params {Boolean} options.allowPlugins
  *    Whether to allow plugin execution. Defaults to `false`.
  */
 function create(document, options) {
   options = options || {};
   let remote = options.remote || false;
-  let nodeName = options.nodeName || 'browser';
   let namespaceURI = options.namespaceURI || XUL;
+  let isXUL = namespaceURI === XUL;
+  let nodeName = isXUL && options.browser ? 'browser' : 'iframe';
 
   let frame = document.createElementNS(namespaceURI, nodeName);
   // Type="content" is mandatory to enable stuff here:
   // http://mxr.mozilla.org/mozilla-central/source/content/base/src/nsFrameLoader.cpp#1776
   frame.setAttribute('type', options.type || 'content');
   frame.setAttribute('src', options.uri || 'about:blank');
 
+  document.documentElement.appendChild(frame);
+
   // Load in separate process if `options.remote` is `true`.
   // http://mxr.mozilla.org/mozilla-central/source/content/base/src/nsFrameLoader.cpp#1347
   if (remote) {
-    // We remove XBL binding to avoid execution of code that is not going to
-    // work because browser has no docShell attribute in remote mode
-    // (for example)
-    frame.setAttribute('style', '-moz-binding: none;');
-    frame.setAttribute('remote', 'true');
+    if (isXUL) {
+      // We remove XBL binding to avoid execution of code that is not going to
+      // work because browser has no docShell attribute in remote mode
+      // (for example)
+      frame.setAttribute('style', '-moz-binding: none;');
+      frame.setAttribute('remote', 'true');
+    }
+    else {
+      frame.QueryInterface(Ci.nsIMozBrowserFrame);
+      frame.createRemoteFrameLoader(null);
+    }
   }
 
-  document.documentElement.appendChild(frame);
+
 
   // If browser is remote it won't have a `docShell`.
   if (!remote) {
     let docShell = getDocShell(frame);
     docShell.allowAuth = options.allowAuth || false;
     docShell.allowJavascript = options.allowJavascript || false;
     docShell.allowPlugins = options.allowPlugins || false;
   }
--- a/addon-sdk/source/lib/sdk/indexed-db.js
+++ b/addon-sdk/source/lib/sdk/indexed-db.js
@@ -4,17 +4,16 @@
 
 "use strict";
 
 module.metadata = {
   "stability": "experimental"
 };
 
 const { Cc, Ci } = require("chrome");
-const { extend } = require("./core/heritage");
 const { id } = require("./self");
 
 // placeholder, copied from bootstrap.js
 let sanitizeId = function(id){
   let uuidRe =
     /^\{([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\}$/;
 
   let domain = id.
@@ -41,17 +40,17 @@ if (typeof(indexedDB) === "undefined")
 let principaluri = Cc["@mozilla.org/network/io-service;1"].
               getService(Ci.nsIIOService).
               newURI(PSEUDOURI, null, null);
 
 let principal = Cc["@mozilla.org/scriptsecuritymanager;1"].
 	               getService(Ci.nsIScriptSecurityManager).
 	               getCodebasePrincipal(principaluri);
 
-exports.indexedDB = extend({}, {   // freeze the object
+exports.indexedDB = Object.freeze({
   open: indexedDB.openForPrincipal.bind(indexedDB, principal),
   deleteDatabase: indexedDB.deleteForPrincipal.bind(indexedDB, principal),
   cmp: indexedDB.cmp
 });
 
 exports.IDBKeyRange = IDBKeyRange;
 exports.DOMException = Ci.nsIDOMDOMException;
 exports.IDBCursor = Ci.nsIIDBCursor;
--- a/addon-sdk/source/lib/sdk/page-mod.js
+++ b/addon-sdk/source/lib/sdk/page-mod.js
@@ -20,16 +20,17 @@ const { validateOptions : validate } = r
 const { Cc, Ci } = require('chrome');
 const { merge } = require('./util/object');
 const { readURISync } = require('./net/url');
 const { windowIterator } = require('./deprecated/window-utils');
 const { isBrowser, getFrames } = require('./window/utils');
 const { getTabs, getTabContentWindow, getTabForContentWindow,
         getURI: getTabURI } = require('./tabs/utils');
 const { has, hasAny } = require('./util/array');
+const { ignoreWindow } = require('sdk/private-browsing/utils');
 
 const styleSheetService = Cc["@mozilla.org/content/style-sheet-service;1"].
                             getService(Ci.nsIStyleSheetService);
 
 const USER_SHEET = styleSheetService.USER_SHEET;
 
 const io = Cc['@mozilla.org/network/io-service;1'].
               getService(Ci.nsIIOService);
@@ -348,16 +349,22 @@ const PageModManager = Registry.resolve(
     let window = document.defaultView;
     // XML documents don't have windows, and we don't yet support them.
     if (!window)
       return;
     // We apply only on documents in tabs of Firefox
     if (!getTabForContentWindow(window))
       return;
 
+    // When the tab is private, only addons with 'private-browsing' flag in
+    // their package.json can apply content script to private documents
+    if (ignoreWindow(window)) {
+      return;
+    }
+
     for (let rule in RULES)
       if (RULES[rule].test(document.URL))
         this._emit(rule, window);
   },
   off: function off(topic, listener) {
     this.removeListener(topic, listener);
     if (!this._listeners(topic).length)
       delete RULES[topic];
--- a/addon-sdk/source/lib/sdk/panel.js
+++ b/addon-sdk/source/lib/sdk/panel.js
@@ -1,41 +1,42 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
 "use strict";
 
 // The panel module currently supports only Firefox.
 // See: https://bugzilla.mozilla.org/show_bug.cgi?id=jetpack-panel-apps
 module.metadata = {
   "stability": "stable",
   "engines": {
     "Firefox": "*"
   }
 };
 
-const { Cc, Ci } = require("chrome");
-
+const { Ci } = require("chrome");
 const { validateOptions: valid } = require('./deprecated/api-utils');
 const { Symbiont } = require('./content/content');
 const { EventEmitter } = require('./deprecated/events');
-const timer = require('./timers');
+const { setTimeout } = require('./timers');
 const runtime = require('./system/runtime');
-const { getMostRecentBrowserWindow } = require('./window/utils');
 const { getDocShell } = require("./frame/utils");
-
-const windowMediator = Cc['@mozilla.org/appshell/window-mediator;1'].
-                       getService(Ci.nsIWindowMediator);
+const { getWindow } = require('./panel/window');
+const { isPrivateBrowsingSupported } = require('./self');
+const { isWindowPBSupported } = require('./private-browsing/utils');
 
 const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
       ON_SHOW = 'popupshown',
       ON_HIDE = 'popuphidden',
       validNumber = { is: ['number', 'undefined', 'null'] };
 
+if (isPrivateBrowsingSupported && isWindowPBSupported) {
+  throw Error('The panel module cannot be used with per-window private browsing at the moment, see Bug 816257');
+}
+
 /**
  * Emits show and hide events.
  */
 const Panel = Symbiont.resolve({
   constructor: '_init',
   _onInit: '_onSymbiontInit',
   destroy: '_symbiontDestructor',
   _documentUnload: '_workerDocumentUnload'
@@ -110,17 +111,25 @@ const Panel = Symbiont.resolve({
   _height: 240,
 
   /* Public API: Panel.isShowing */
   get isShowing() !!this._xulPanel && this._xulPanel.state == "open",
 
   /* Public API: Panel.show */
   show: function show(anchor) {
     anchor = anchor || null;
-    let document = getWindow(anchor).document;
+    let anchorWindow = getWindow(anchor);
+
+    // If there is no open window, or the anchor is in a private window
+    // then we will not be able to display the panel
+    if (!anchorWindow) {
+      return;
+    }
+
+    let document = anchorWindow.document;
     let xulPanel = this._xulPanel;
     if (!xulPanel) {
       xulPanel = this._xulPanel = document.createElementNS(XUL_NS, 'panel');
       xulPanel.setAttribute("type", "arrow");
 
       // One anonymous node has a big padding that doesn't work well with
       // Jetpack, as we would like to display an iframe that completely fills
       // the panel.
@@ -138,16 +147,17 @@ const Panel = Symbiont.resolve({
       '</bindings>';
       xulPanel.style.MozBinding = 'url("data:text/xml;charset=utf-8,' +
         document.defaultView.encodeURIComponent(binding) + '")';
 
       let frame = document.createElementNS(XUL_NS, 'iframe');
       frame.setAttribute('type', 'content');
       frame.setAttribute('flex', '1');
       frame.setAttribute('transparent', 'transparent');
+
       if (runtime.OS === "Darwin") {
         frame.style.borderRadius = "6px";
         frame.style.padding = "1px";
       }
 
       // Load an empty document in order to have an immediatly loaded iframe,
       // so swapFrameLoaders is going to work without having to wait for load.
       frame.setAttribute("src","data:;charset=utf-8,");
@@ -198,17 +208,17 @@ const Panel = Symbiont.resolve({
     // Resize the iframe instead of using panel.sizeTo
     // because sizeTo doesn't work with arrow panels
     xulPanel.firstChild.style.width = width + "px";
     xulPanel.firstChild.style.height = height + "px";
 
     // Wait for the XBL binding to be constructed
     function waitForBinding() {
       if (!xulPanel.openPopup) {
-        timer.setTimeout(waitForBinding, 50);
+        setTimeout(waitForBinding, 50);
         return;
       }
       xulPanel.openPopup(anchor, position, x, y);
     }
     waitForBinding();
 
     return this._public;
   },
@@ -358,45 +368,8 @@ const Panel = Symbiont.resolve({
       // document
       this._workerCleanup();
       this._initFrame(this._frame);
     }
   }
 });
 exports.Panel = function(options) Panel(options)
 exports.Panel.prototype = Panel.prototype;
-
-function getWindow(anchor) {
-  let window;
-
-  if (anchor) {
-    let anchorWindow = anchor.ownerDocument.defaultView.top;
-    let anchorDocument = anchorWindow.document;
-
-    let enumerator = windowMediator.getEnumerator("navigator:browser");
-    while (enumerator.hasMoreElements()) {
-      let enumWindow = enumerator.getNext();
-
-      // Check if the anchor is in this browser window.
-      if (enumWindow == anchorWindow) {
-        window = anchorWindow;
-        break;
-      }
-
-      // Check if the anchor is in a browser tab in this browser window.
-      let browser = enumWindow.gBrowser.getBrowserForDocument(anchorDocument);
-      if (browser) {
-        window = enumWindow;
-        break;
-      }
-
-      // Look in other subdocuments (sidebar, etc.)?
-    }
-  }
-
-  // If we didn't find the anchor's window (or we have no anchor),
-  // return the most recent browser window.
-  if (!window)
-    window = getMostRecentBrowserWindow();
-
-  return window;
-}
-
new file mode 100644
--- /dev/null
+++ b/addon-sdk/source/lib/sdk/panel/window.js
@@ -0,0 +1,51 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+'use strict';
+
+const { getMostRecentBrowserWindow, windows: getWindows } = require('../window/utils');
+const { ignoreWindow } = require('../private-browsing/utils');
+const { isPrivateBrowsingSupported } = require('../self');
+
+function getWindow(anchor) {
+  let window;
+  let windows = getWindows("navigator:browser", {
+    includePrivate: isPrivateBrowsingSupported
+  });
+
+  if (anchor) {
+    let anchorWindow = anchor.ownerDocument.defaultView.top;
+    let anchorDocument = anchorWindow.document;
+
+    // loop thru supported windows
+    for each(let enumWindow in windows) {
+      // Check if the anchor is in this browser window.
+      if (enumWindow == anchorWindow) {
+        window = anchorWindow;
+        break;
+      }
+
+      // Check if the anchor is in a browser tab in this browser window.
+      let browser = enumWindow.gBrowser.getBrowserForDocument(anchorDocument);
+      if (browser) {
+        window = enumWindow;
+        break;
+      }
+
+      // Look in other subdocuments (sidebar, etc.)?
+    }
+  }
+
+  // If we didn't find the anchor's window (or we have no anchor),
+  // return the most recent browser window.
+  if (!window)
+    window = getMostRecentBrowserWindow();
+
+  // if the window is not supported, then it should be ignored
+  if (ignoreWindow(window)) {
+  	return null;
+  }
+
+  return window;
+}
+exports.getWindow = getWindow;
--- a/addon-sdk/source/lib/sdk/private-browsing.js
+++ b/addon-sdk/source/lib/sdk/private-browsing.js
@@ -18,17 +18,17 @@ onStateChange('start', function onStart(
   emit(exports, 'start');
 });
 
 onStateChange('stop', function onStop() {
   emit(exports, 'stop');
 });
 
 Object.defineProperty(exports, "isActive", {
-	get: deprecateFunction(getMode, 'require("private-browsing").isActive is deprecated.')
+  get: deprecateFunction(getMode, 'require("private-browsing").isActive is deprecated.')
 });
 
 exports.activate = function activate() setMode(true);
 exports.deactivate = function deactivate() setMode(false);
 
 exports.on = deprecateEvents(on.bind(null, exports));
 exports.once = deprecateEvents(once.bind(null, exports));
 exports.removeListener = deprecateEvents(function removeListener(type, listener) {
@@ -43,16 +43,27 @@ exports.isPrivate = function(thing) {
   // then check if the window is private
   if (!!thing) {
     // if the thing is a window, and the window is private
     // then return true
     if (isWindowPrivate(thing)) {
       return true;
     }
 
+    // does the thing have an associated tab?
+    // page-mod instances do..
+    if (thing.tab) {
+      let tabWindow = getOwnerWindow(thing.tab);
+      if (tabWindow) {
+        let isThingPrivate = isWindowPrivate(tabWindow);
+        if (isThingPrivate)
+          return isThingPrivate;
+      }
+    }
+
     // can we find an associated window?
     let window = getOwnerWindow(thing);
     if (window)
       return isWindowPrivate(window);
   }
 
   // if we get here, and global private browsing
   // is available, and it is true, then return
--- a/addon-sdk/source/lib/sdk/selection.js
+++ b/addon-sdk/source/lib/sdk/selection.js
@@ -13,20 +13,20 @@ module.metadata = {
 
 const { Ci, Cc } = require("chrome"),
     { setTimeout } = require("./timers"),
     { emit, off } = require("./event/core"),
     { Class, obscure } = require("./core/heritage"),
     { EventTarget } = require("./event/target"),
     { ns } = require("./core/namespace"),
     { when: unload } = require("./system/unload"),
+    { ignoreWindow } = require('./private-browsing/utils'),
     { getTabs, getTabContentWindow, getTabForContentWindow,
       getAllTabContentWindows } = require('./tabs/utils'),
-    { getMostRecentBrowserWindow,
-      windows, getFocusedWindow, getFocusedElement } = require("./window/utils"),
+    winUtils = require("./window/utils"),
     events = require("./system/events");
 
 // The selection types
 const HTML = 0x01,
       TEXT = 0x02,
       DOM  = 0x03; // internal use only
 
 // A more developer-friendly message than the caught exception when is not
@@ -96,32 +96,62 @@ const selectionListener = {
  * Empty selections are skipped - see `safeGetRange` for further details.
  *
  * If discontiguous selections are in a text field, only the first one
  * is returned because the text field selection APIs doesn't support
  * multiple selections.
  */
 function iterator() {
     let selection = getSelection(DOM);
-    let count = selection.rangeCount || (getElementWithSelection() ? 1 : 0);
+    let count = 0;
+
+    if (selection)
+      count = selection.rangeCount || (getElementWithSelection() ? 1 : 0);
 
     for (let i = 0; i < count; i++) {
       let sel = Selection(i);
 
       if (sel.text)
         yield Selection(i);
     }
 }
 
 const selectionIterator = obscure({
   __iterator__: iterator, // for...in; for each...in
   iterator: iterator // for....of
 });
 
 /**
+ * Returns the most recent focused window.
+ * if private browsing window is most recent and not supported,
+ * then ignore it and return `null`, because the focused window
+ * can't be targeted.
+ */
+function getFocusedWindow() {
+  let window = winUtils.getFocusedWindow();
+
+  return ignoreWindow(window) ? null : window;
+}
+
+/**
+ * Returns the focused element in the most recent focused window
+ * if private browsing window is most recent and not supported,
+ * then ignore it and return `null`, because the focused element
+ * can't be targeted.
+ */
+function getFocusedElement() {
+  let element = winUtils.getFocusedElement();
+
+  if (!element || ignoreWindow(element.ownerDocument.defaultView))
+    return null;
+
+  return element;
+}
+
+/**
  * Returns the current selection from most recent content window. Depending on
  * the specified |type|, the value returned can be a string of text, stringified
  * HTML, or a DOM selection object as described at
  * https://developer.mozilla.org/en/DOM/Selection.
  *
  * @param type
  *        Specifies the return type of the selection. Valid values are the one
  *        of the constants HTML, TEXT, or DOM.
@@ -343,20 +373,21 @@ function removeSelectionListener(window)
   window.removeEventListener("select", selectionListener.onSelect, true);
 
   delete selections(window).selection;
 };
 
 function onContent(event) {
   let window = event.subject.defaultView;
 
-  // We are not interested in documents without valid defaultView (e.g. XML), or
-  // not in a tab (e.g. Panel).
-   if (window && getTabForContentWindow(window))
+  // We are not interested in documents without valid defaultView (e.g. XML)
+  // that aren't in a tab (e.g. Panel); or in private windows
+   if (window && getTabForContentWindow(window) && !ignoreWindow(window)) {
     addSelectionListener(window);
+  }
 }
 
 // Adds Selection listener to new documents
 // Note that strong reference is needed for documents that are loading slowly or
 // where the server didn't close the connection (e.g. "comet").
 events.on("document-element-inserted", onContent, true);
 
 // Adds Selection listeners to existing documents
--- a/addon-sdk/source/lib/sdk/tabs/tab-firefox.js
+++ b/addon-sdk/source/lib/sdk/tabs/tab-firefox.js
@@ -58,17 +58,20 @@ const TabTrait = Trait.compose(EventEmit
     // Since we will have to identify tabs by a DOM elements facade function
     // is used as constructor that collects all the instances and makes sure
     // that they more then one wrapper is not created per tab.
     return this;
   },
   destroy: function destroy() {
     this._removeAllListeners();
     if (this._tab) {
-      this._browser.removeEventListener(EVENTS.ready.dom, this._onReady, true);
+      let browser = this._browser;
+      // The tab may already be removed from DOM -or- not yet added
+      if (browser)
+        browser.removeEventListener(EVENTS.ready.dom, this._onReady, true);
       this._tab = null;
       TABS.splice(TABS.indexOf(this), 1);
     }
   },
 
   /**
    * Internal listener that emits public event 'ready' when the page of this
    * tab is loaded.
@@ -216,20 +219,25 @@ const TabTrait = Trait.compose(EventEmit
     this._window.gBrowser.reloadTab(this._tab);
   }
 });
 
 function getChromeTab(tab) {
   return getOwnerWindow(viewNS(tab).tab);
 }
 
-function Tab(options) {
+function Tab(options, existingOnly) {
   let chromeTab = options.tab;
   for each (let tab in TABS) {
     if (chromeTab == tab._tab)
       return tab._public;
   }
+  // If called asked to return only existing wrapper,
+  // we should return null here as no matching Tab object has been found
+  if (existingOnly)
+    return null;
+
   let tab = TabTrait(options);
   TABS.push(tab);
   return tab._public;
 }
 Tab.prototype = TabTrait.prototype;
 exports.Tab = Tab;
--- a/addon-sdk/source/lib/sdk/test/assert.js
+++ b/addon-sdk/source/lib/sdk/test/assert.js
@@ -55,18 +55,24 @@ AssertionError.prototype = Object.create
       ].join(" ");
     }
     return value;
   }}
 });
 exports.AssertionError = AssertionError;
 
 function Assert(logger) {
-  return Object.create(Assert.prototype, { _log: { value: logger }});
+  let assert = Object.create(Assert.prototype, { _log: { value: logger }});
+
+  assert.fail = assert.fail.bind(assert);
+  assert.pass = assert.pass.bind(assert);
+
+  return assert;
 }
+
 Assert.prototype = {
   fail: function fail(e) {
     if (!e || typeof(e) !== 'object') {
       this._log.fail(e);
       return;
     }
     let message = e.message;
     try {
--- a/addon-sdk/source/lib/sdk/test/loader.js
+++ b/addon-sdk/source/lib/sdk/test/loader.js
@@ -1,22 +1,26 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 const { Loader, resolveURI, Require,
         unload, override, descriptor  } = require('../loader/cuddlefish');
+const addonWindow = require('../addon/window');
 const { PlainTextConsole } = require("sdk/console/plain-text");
 
 function CustomLoader(module, globals, packaging) {
   let options = packaging || require("@loader/options");
   options = override(options, {
-    globals: override(require('../system/globals'), globals || {})
+    globals: override(require('../system/globals'), globals || {}),
+    modules: override(options.modules || {}, {
+      'sdk/addon/window': addonWindow
+     })
   });
 
   let loader = Loader(options);
   return Object.create(loader, descriptor({
     require: Require(loader, module),
     sandbox: function(id) {
       let requirement = loader.resolve(id, module.id);
       let uri = resolveURI(requirement, loader.mapping);
--- a/addon-sdk/source/lib/sdk/window/utils.js
+++ b/addon-sdk/source/lib/sdk/window/utils.js
@@ -49,16 +49,21 @@ function isWindowPrivate(win) {
 }
 exports.isWindowPrivate = isWindowPrivate;
 
 function getMostRecentBrowserWindow() {
   return getMostRecentWindow(BROWSER);
 }
 exports.getMostRecentBrowserWindow = getMostRecentBrowserWindow;
 
+function getHiddenWindow() {
+  return appShellService.hiddenDOMWindow;
+}
+exports.getHiddenWindow = getHiddenWindow;
+
 function getMostRecentWindow(type) {
   return WM.getMostRecentWindow(type);
 }
 exports.getMostRecentWindow = getMostRecentWindow;
 
 /**
  * Returns the ID of the window's current inner window.
  */
@@ -84,16 +89,22 @@ function getXULWindow(window) {
   return window.QueryInterface(Ci.nsIInterfaceRequestor).
     getInterface(Ci.nsIWebNavigation).
     QueryInterface(Ci.nsIDocShellTreeItem).
     treeOwner.QueryInterface(Ci.nsIInterfaceRequestor).
     getInterface(Ci.nsIXULWindow);
 };
 exports.getXULWindow = getXULWindow;
 
+function getDOMWindow(xulWindow) {
+  return xulWindow.QueryInterface(Ci.nsIInterfaceRequestor).
+    getInterface(Ci.nsIDOMWindow);
+}
+exports.getDOMWindow = getDOMWindow;
+
 /**
  * Returns `nsIBaseWindow` for the given `nsIDOMWindow`.
  */
 function getBaseWindow(window) {
   return window.QueryInterface(Ci.nsIInterfaceRequestor).
     getInterface(Ci.nsIWebNavigation).
     QueryInterface(Ci.nsIDocShell).
     QueryInterface(Ci.nsIDocShellTreeItem).
@@ -158,39 +169,41 @@ function serializeFeatures(options) {
  *    Optional name that is assigned to the window.
  * @params {Object} options.features
  *    Map of key, values like: `{ width: 10, height: 15, chrome: true, private: true }`.
  */
 function open(uri, options) {
   options = options || {};
   let newWindow = windowWatcher.
     openWindow(options.parent || null,
-               uri,
+               uri || URI_BROWSER,
                options.name || null,
                serializeFeatures(options.features || {}),
                options.args || null);
 
   return newWindow;
 }
+
+
 exports.open = open;
 
 function onFocus(window) {
-  let deferred = defer();
+  let { resolve, promise } = defer();
 
   if (isFocused(window)) {
-    deferred.resolve(window);
+    resolve(window);
   }
   else {
     window.addEventListener("focus", function focusListener() {
       window.removeEventListener("focus", focusListener, true);
-      deferred.resolve(window);
+      resolve(window);
     }, true);
   }
 
-  return deferred.promise;
+  return promise;
 }
 exports.onFocus = onFocus;
 
 function isFocused(window) {
   const FM = Cc["@mozilla.org/focus-manager;1"].
                 getService(Ci.nsIFocusManager);
 
   let childTargetWindow = {};
@@ -200,26 +213,27 @@ function isFocused(window) {
   let focusedChildWindow = {};
   if (FM.activeWindow) {
     FM.getFocusedElementForWindow(FM.activeWindow, true, focusedChildWindow);
     focusedChildWindow = focusedChildWindow.value;
   }
 
   return (focusedChildWindow === childTargetWindow);
 }
+exports.isFocused = isFocused;
 
 /**
  * Opens a top level window and returns it's `nsIDOMWindow` representation.
  * Same as `open` but with more features
  * @param {Object} options
  *
  */
 function openDialog(options) {
   options = options || {};
-  
+
   let features = options.features || FEATURES;
   if (!!options.private &&
       !array.has(features.toLowerCase().split(','), 'private')) {
     features = features.split(',').concat('private').join(',');
   }
 
   let browser = getMostRecentBrowserWindow();
 
@@ -290,26 +304,28 @@ function isXULBrowser(window) {
   return !!(isBrowser(window) && window.XULBrowserWindow);
 }
 exports.isXULBrowser = isXULBrowser;
 
 /**
  * Returns the most recent focused window
  */
 function getFocusedWindow() {
-  let window = getMostRecentBrowserWindow();
+  let window = WM.getMostRecentWindow(BROWSER);
+
   return window ? window.document.commandDispatcher.focusedWindow : null;
 }
 exports.getFocusedWindow = getFocusedWindow;
 
 /**
  * Returns the focused element in the most recent focused window
  */
 function getFocusedElement() {
-  let window = getMostRecentBrowserWindow();
+  let window = WM.getMostRecentWindow(BROWSER);
+
   return window ? window.document.commandDispatcher.focusedElement : null;
 }
 exports.getFocusedElement = getFocusedElement;
 
 function getFrames(window) {
   return Array.slice(window.frames).reduce(function(frames, frame) {
     return frames.concat(frame, getFrames(frame))
   }, [])
--- a/addon-sdk/source/lib/sdk/windows/tabs-firefox.js
+++ b/addon-sdk/source/lib/sdk/windows/tabs-firefox.js
@@ -93,18 +93,25 @@ const WindowTabTracker = Trait.compose({
   _onTabEvent: function _onTabEvent(type, tab) {
     // Accept only tabs for the watched window, and ignore private tabs
     // if addon doesn't have private permission
     if (this._window === getOwnerWindow(tab) && !ignoreWindow(this._window)) {
       let options = this._tabOptions.shift() || {};
       options.tab = tab;
       options.window = this._public;
 
-      // creating tab wrapper and adding listener to "ready" events.
-      let wrappedTab = Tab(options);
+      // Ignore zombie tabs on open that have already been removed
+      if (type == "open" && !tab.linkedBrowser)
+        return;
+
+      // Create a tab wrapper on open event, otherwise, just fetch existing
+      // tab object
+      let wrappedTab = Tab(options, type !== "open");
+      if (!wrappedTab)
+        return;
 
       // Setting up an event listener for ready events.
       if (type === "open")
         wrappedTab.on("ready", this._onTabReady);
 
       this._emitEvent(type, wrappedTab);
     }
   },
--- a/addon-sdk/source/python-lib/cuddlefish/__init__.py
+++ b/addon-sdk/source/python-lib/cuddlefish/__init__.py
@@ -138,18 +138,18 @@ parser_groups = (
                                       type="json",
                                       metavar=None,
                                       default="{}",
                                       cmds=['run', 'xpi'])),
         (("", "--parseable",), dict(dest="parseable",
                                     help="display test output in a parseable format",
                                     action="store_true",
                                     default=False,
-                                    cmds=['test', 'testex', 'testpkgs',
-                                          'testall'])),
+                                    cmds=['run', 'test', 'testex', 'testpkgs',
+                                          'testaddons', 'testall'])),
         ]
      ),
 
     ("Experimental Command-Specific Options", [
         (("-a", "--app",), dict(dest="app",
                                 help=("app to run: firefox (default), fennec, "
                                       "fennec-on-device, xulrunner or "
                                       "thunderbird"),
@@ -655,26 +655,26 @@ def run(arguments=sys.argv[1:], target_c
 
         target_cfg_json = os.path.join(options.pkgdir, 'package.json')
         target_cfg = packaging.get_config_in_dir(options.pkgdir)
 
     # At this point, we're either building an XPI or running Jetpack code in
     # a Mozilla application (which includes running tests).
 
     use_main = False
-    inherited_options = ['verbose', 'enable_e10s']
+    inherited_options = ['verbose', 'enable_e10s', 'parseable']
     enforce_timeouts = False
 
     if command == "xpi":
         use_main = True
     elif command == "test":
         if 'tests' not in target_cfg:
             target_cfg['tests'] = []
         inherited_options.extend(['iterations', 'filter', 'profileMemory',
-                                  'stopOnError', 'parseable'])
+                                  'stopOnError'])
         enforce_timeouts = True
     elif command == "run":
         use_main = True
     else:
         assert 0, "shouldn't get here"
 
     if use_main and 'main' not in target_cfg:
         # If the user supplies a template dir, then the main
--- a/addon-sdk/source/test/addons/private-browsing-supported/main.js
+++ b/addon-sdk/source/test/addons/private-browsing-supported/main.js
@@ -29,24 +29,24 @@ exports.testGetOwnerWindow = function(as
   assert.ok(chromeWindow instanceof Ci.nsIDOMWindow, 'associated window is found');
 
   tabs.open({
     url: 'about:blank',
     isPrivate: true,
     onOpen: function(tab) {
       // test that getOwnerWindow works as expected
       if (is('Fennec')) {
-        assert.notStrictEqual(chromeWindow, getOwnerWindow(tab)); 
-        assert.ok(getOwnerWindow(tab) instanceof Ci.nsIDOMWindow); 
+        assert.notStrictEqual(chromeWindow, getOwnerWindow(tab));
+        assert.ok(getOwnerWindow(tab) instanceof Ci.nsIDOMWindow);
       }
       else {
         if (isWindowPBSupported) {
           assert.notStrictEqual(chromeWindow,
                                 getOwnerWindow(tab),
-                                'associated window is not the same for window and window\'s tab'); 
+                                'associated window is not the same for window and window\'s tab');
         }
         else {
           assert.strictEqual(chromeWindow,
                             getOwnerWindow(tab),
                             'associated window is the same for window and window\'s tab');
         }
       }
 
@@ -159,12 +159,17 @@ if (!is('Fennec')) {
         assert.equal(isPrivate(window), false, 'isPrivate for a window is false when it should be');
         assert.equal(isPrivate(window.tabs[0]), false, 'isPrivate for a tab is false when it should be');
         window.close(done);
       }
     })
   }
 }
 
-merge(module.exports, require('./windows'));
-merge(module.exports, require('./tabs'));
+merge(module.exports,
+  require('./test-windows'),
+  require('./test-tabs'),
+  require('./test-page-mod'),
+  require('./test-selection'),
+  require('./test-panel')
+);
 
 require('sdk/test/runner').runTestsFromModule(module);
deleted file mode 100644
--- a/addon-sdk/source/test/addons/private-browsing-supported/tabs.js
+++ /dev/null
@@ -1,30 +0,0 @@
-const tabs = require('sdk/tabs');
-const { is } = require('sdk/system/xul-app');
-const { isPrivate } = require('sdk/private-browsing');
-const pbUtils = require('sdk/private-browsing/utils');
-const { getOwnerWindow } = require('sdk/private-browsing/window/utils');
-
-exports.testPrivateTabsAreListed = function (assert, done) {
-  let originalTabCount = tabs.length;
-
-  tabs.open({
-    url: 'about:blank',
-    isPrivate: true,
-    onOpen: function(tab) {
-      let win = getOwnerWindow(tab);
-      // PWPB case
-      if (pbUtils.isWindowPBSupported || pbUtils.isTabPBSupported) {
-        assert.ok(isPrivate(tab), "tab is private");
-        assert.equal(tabs.length, originalTabCount + 1,
-                     'New private window\'s tab are visible in tabs list');
-      }
-      else {
-      // Global case, openDialog didn't opened a private window/tab
-        assert.ok(!isPrivate(tab), "tab isn't private");
-        assert.equal(tabs.length, originalTabCount + 1,
-                     'New non-private window\'s tab is visible in tabs list');
-      }
-      tab.close(done);
-    }
-  });
-}
new file mode 100644
--- /dev/null
+++ b/addon-sdk/source/test/addons/private-browsing-supported/test-page-mod.js
@@ -0,0 +1,111 @@
+const { getMostRecentBrowserWindow } = require('sdk/window/utils');
+const { PageMod } = require("sdk/page-mod");
+const { getActiveTab, setTabURL, openTab, closeTab } = require('sdk/tabs/utils');
+const xulApp = require('sdk/system/xul-app');
+const windowHelpers = require('sdk/window/helpers');
+const { defer } = require("sdk/core/promise");
+const { isPrivate } = require('sdk/private-browsing');
+const { isTabPBSupported, isWindowPBSupported } = require('sdk/private-browsing/utils');
+
+function openWebpage(url, enablePrivate) {
+  let { promise, resolve, reject } = defer();
+
+  if (xulApp.is("Fennec")) {
+    let chromeWindow = getMostRecentBrowserWindow();
+    let rawTab = openTab(chromeWindow, url, {
+      isPrivate: enablePrivate
+    });
+
+    resolve(function() {
+      closeTab(rawTab)
+    });
+
+    return promise;
+  }
+  else {
+    windowHelpers.open("", {
+      features: {
+        toolbar: true,
+        private: enablePrivate
+      }
+    }).then(function(chromeWindow) {
+      if (isPrivate(chromeWindow) !== !!enablePrivate)
+        reject(new Error("Window should have Private set to " + !!enablePrivate));
+
+      let tab = getActiveTab(chromeWindow);
+      setTabURL(tab, url);
+
+      resolve(function(){
+        windowHelpers.close(chromeWindow);
+      });
+    });
+
+    return promise;
+  }
+}
+
+exports["test page-mod on private tab"] = function (assert, done) {
+  // Only set private mode when explicitely supported.
+  // (fennec 19 has some intermediate PB support where isTabPBSupported
+  // will be false, but isPrivate(worker.tab) will be true if we open a private
+  // tab)
+  let setPrivate = isTabPBSupported || isWindowPBSupported;
+
+  let id = Date.now().toString(36);
+  let frameUri = "data:text/html;charset=utf-8," + id;
+  let uri = "data:text/html;charset=utf-8," +
+            encodeURIComponent(id + "<iframe src='" + frameUri + "'><iframe>");
+
+  let count = 0;
+
+  openWebpage(uri, setPrivate).then(function(close) {
+    PageMod({
+      include: [uri, frameUri],
+
+      onAttach: function(worker) {
+        assert.ok(worker.tab.url == uri || worker.tab.url == frameUri,
+                  "Got a worker attached to the private window tab");
+
+        if (setPrivate) {
+          assert.ok(isPrivate(worker), "The worker is really private");
+          assert.ok(isPrivate(worker.tab), "The document is really private");
+        }
+        else {
+          assert.ok(!isPrivate(worker),
+                    "private browsing isn't supported, " +
+                    "so that the worker isn't private");
+          assert.ok(!isPrivate(worker.tab),
+                    "private browsing isn't supported, " +
+                    "so that the document isn't private");
+        }
+
+        if (++count == 2) {
+          this.destroy();
+          close();
+          done();
+        }
+      }
+    });
+  }).then(null, assert.fail);
+};
+
+exports["test page-mod on non-private tab"] = function (assert, done) {
+  let id = Date.now().toString(36);
+  let url = "data:text/html;charset=utf-8," + encodeURIComponent(id);
+
+  openWebpage(url, false).then(function(close){
+    PageMod({
+      include: url,
+      onAttach: function(worker) {
+        assert.equal(worker.tab.url, url,
+                     "Got a worker attached to the private window tab");
+        assert.ok(!isPrivate(worker), "The worker is really non-private");
+        assert.ok(!isPrivate(worker.tab), "The document is really non-private");
+
+        this.destroy();
+        close();
+        done();
+      }
+    });
+  }).then(null, assert.fail);
+}
new file mode 100644
--- /dev/null
+++ b/addon-sdk/source/test/addons/private-browsing-supported/test-panel.js
@@ -0,0 +1,16 @@
+'use strict';
+
+const { isWindowPBSupported } = require('sdk/private-browsing/utils');
+
+if (isWindowPBSupported) {
+  exports.testRequirePanel = function (assert) {
+    try {
+  	  require('panel');
+    }
+    catch(e) {
+  	  assert.ok(e.message.match(/Bug 816257/), 'Bug 816257 is mentioned');
+      return;
+    }
+    assert.fail('the panel module should throw an error');
+  }
+}
new file mode 100644
--- /dev/null
+++ b/addon-sdk/source/test/addons/private-browsing-supported/test-selection.js
@@ -0,0 +1,458 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+const HTML = "<html>\
+  <body>\
+    <div>foo</div>\
+    <div>and</div>\
+    <textarea>noodles</textarea>\
+  </body>\
+</html>";
+
+const URL = "data:text/html;charset=utf-8," + encodeURIComponent(HTML);
+
+const FRAME_HTML = "<iframe src='" + URL + "'><iframe>";
+const FRAME_URL = "data:text/html;charset=utf-8," + encodeURIComponent(FRAME_HTML);
+
+const { defer } = require("sdk/core/promise");
+const { browserWindows } = require("sdk/windows");
+const tabs = require("sdk/tabs");
+const { setTabURL, getActiveTab, getTabContentWindow, closeTab, getTabs,
+  getTabTitle } = require("sdk/tabs/utils");
+const { getMostRecentBrowserWindow, isFocused } = require("sdk/window/utils");
+const { open: openNewWindow, close: closeWindow, focus } = require("sdk/window/helpers");
+const { Loader } = require("sdk/test/loader");
+const { merge } = require("sdk/util/object");
+const { isPrivate } = require("sdk/private-browsing");
+
+// General purpose utility functions
+
+/**
+ * Opens the url given and return a promise, that will be resolved with the
+ * content window when the document is ready.
+ *
+ * I believe this approach could be useful in most of our unit test, that
+ * requires to open a tab and need to access to its content.
+ */
+function open(url, options) {
+  let { promise, resolve } = defer();
+
+  if (options && typeof(options) === "object") {
+    openNewWindow("", {
+      features: merge({ toolbar: true }, options)
+    }).then(function(chromeWindow) {
+      if (isPrivate(chromeWindow) !== !!options.private)
+        throw new Error("Window should have Private set to " + !!options.private);
+
+      let tab = getActiveTab(chromeWindow);
+
+      tab.addEventListener("load", function ready(event) {
+        let { document } = getTabContentWindow(this);
+
+        if (document.readyState === "complete" && document.URL === url) {
+          this.removeEventListener(event.type, ready);
+
+          if (options.title)
+            document.title = options.title;
+
+          resolve(document.defaultView);
+        }
+      })
+
+      setTabURL(tab, url);
+    });
+
+    return promise;
+  };
+
+  tabs.open({
+    url: url,
+    onReady: function(tab) {
+      // Unfortunately there is no way to get a XUL Tab from SDK Tab on Firefox,
+      // only on Fennec. We should implement `tabNS` also on Firefox in order
+      // to have that.
+
+      // Here we assuming that the most recent browser window is the one we're
+      // doing the test, and the active tab is the one we just opened.
+      let window = getTabContentWindow(getActiveTab(getMostRecentBrowserWindow()));
+
+      resolve(window);
+    }
+  });
+
+  return promise;
+};
+
+/**
+ * Close the Active Tab
+ */
+function close(window) {
+  let { promise, resolve } = defer();
+
+  if (window && typeof(window.close) === "function") {
+    closeWindow(window).then(function() resolve());
+  }
+  else {
+    // Here we assuming that the most recent browser window is the one we're
+    // doing the test, and the active tab is the one we just opened.
+    closeTab(getActiveTab(getMostRecentBrowserWindow()));
+    resolve();
+  }
+
+  return promise;
+}
+
+/**
+ * Reload the window given and return a promise, that will be resolved with the
+ * content window after a small delay.
+ */
+function reload(window) {
+  let { promise, resolve } = defer();
+
+  // Here we assuming that the most recent browser window is the one we're
+  // doing the test, and the active tab is the one we just opened.
+  let tab = tabs.activeTab;
+
+  tab.once("ready", function () {
+    resolve(window);
+  });
+
+  window.location.reload(true);
+
+  return promise;
+}
+
+// Selection's unit test utility function
+
+/**
+ * Select the first div in the page, adding the range to the selection.
+ */
+function selectFirstDiv(window) {
+  let div = window.document.querySelector("div");
+  let selection = window.getSelection();
+  let range = window.document.createRange();
+
+  if (selection.rangeCount > 0)
+    selection.removeAllRanges();
+
+  range.selectNode(div);
+  selection.addRange(range);
+
+  return window;
+}
+
+/**
+ * Select all divs in the page, adding the ranges to the selection.
+ */
+function selectAllDivs(window) {
+  let divs = window.document.getElementsByTagName("div");
+  let selection = window.getSelection();
+
+  if (selection.rangeCount > 0)
+    selection.removeAllRanges();
+
+  for (let i = 0; i < divs.length; i++) {
+    let range = window.document.createRange();
+
+    range.selectNode(divs[i]);
+    selection.addRange(range);
+  }
+
+  return window;
+}
+
+/**
+ * Select the textarea content
+ */
+function selectTextarea(window) {
+  let selection = window.getSelection();
+  let textarea = window.document.querySelector("textarea");
+
+  if (selection.rangeCount > 0)
+    selection.removeAllRanges();
+
+  textarea.setSelectionRange(0, textarea.value.length);
+  textarea.focus();
+
+  return window;
+}
+
+/**
+ * Select the content of the first div
+ */
+function selectContentFirstDiv(window) {
+  let div = window.document.querySelector("div");
+  let selection = window.getSelection();
+  let range = window.document.createRange();
+
+  if (selection.rangeCount > 0)
+    selection.removeAllRanges();
+
+  range.selectNodeContents(div);
+  selection.addRange(range);
+
+  return window;
+}
+
+/**
+ * Dispatch the selection event for the selection listener added by
+ * `nsISelectionPrivate.addSelectionListener`
+ */
+function dispatchSelectionEvent(window) {
+  // We modify the selection in order to dispatch the selection's event, by
+  // contract the selection by one character. So if the text selected is "foo"
+  // will be "fo".
+  window.getSelection().modify("extend", "backward", "character");
+
+  return window;
+}
+
+/**
+ * Dispatch the selection event for the selection listener added by
+ * `window.onselect` / `window.addEventListener`
+ */
+function dispatchOnSelectEvent(window) {
+  let { document } = window;
+  let textarea = document.querySelector("textarea");
+  let event = document.createEvent("UIEvents");
+
+  event.initUIEvent("select", true, true, window, 1);
+
+  textarea.dispatchEvent(event);
+
+  return window;
+}
+
+// Test cases
+
+exports["test PWPB Selection Listener"] = function(assert, done) {
+  let loader = Loader(module);
+  let selection = loader.require("sdk/selection");
+
+  open(URL, {private: true, title: "PWPB Selection Listener"}).
+    then(function(window) {
+      selection.once("select", function() {
+        assert.equal(browserWindows.length, 2, "there should be only two windows open.");
+        assert.equal(getTabs().length, 2, "there should be only two tabs open: '" +
+                     getTabs().map(function(tab) getTabTitle(tab)).join("', '") +
+                     "'."
+        );
+
+        // window should be focused, but force the focus anyhow.. see bug 841823
+        focus(window).then(function() {
+          // check state of window
+          assert.ok(isFocused(window), "the window is focused");
+          assert.ok(isPrivate(window), "the window should be a private window");
+
+          assert.equal(selection.text, "fo");
+
+          close(window).
+            then(loader.unload).
+            then(done, assert.fail);
+        });
+      });
+      return window;
+    }).
+    then(selectContentFirstDiv).
+    then(dispatchSelectionEvent).
+    then(null, assert.fail);
+};
+
+exports["test PWPB Textarea OnSelect Listener"] = function(assert, done) {
+  let loader = Loader(module);
+  let selection = loader.require("sdk/selection");
+
+  open(URL, {private: true, title: "PWPB OnSelect Listener"}).
+    then(function(window) {
+      selection.once("select", function() {
+        assert.equal(browserWindows.length, 2, "there should be only two windows open.");
+        assert.equal(getTabs().length, 2, "there should be only two tabs open: '" +
+                     getTabs().map(function(tab) getTabTitle(tab)).join("', '") +
+                     "'."
+        );
+
+        // window should be focused, but force the focus anyhow.. see bug 841823
+        focus(window).then(function() {
+          assert.equal(selection.text, "noodles");
+
+          close(window).
+            then(loader.unload).
+            then(done, assert.fail);
+        });
+      });
+      return window;
+    }).
+    then(selectTextarea).
+    then(dispatchOnSelectEvent).
+    then(null, assert.fail);
+};
+
+exports["test PWPB Single DOM Selection"] = function(assert, done) {
+  let loader = Loader(module);
+  let selection = loader.require("sdk/selection");
+
+  open(URL, {private: true, title: "PWPB Single DOM Selection"}).
+    then(selectFirstDiv).
+    then(focus).then(function() {
+      assert.equal(selection.isContiguous, true,
+        "selection.isContiguous with single DOM Selection works.");
+
+      assert.equal(selection.text, "foo",
+        "selection.text with single DOM Selection works.");
+
+      assert.equal(selection.html, "<div>foo</div>",
+        "selection.html with single DOM Selection works.");
+
+      let selectionCount = 0;
+      for each (let sel in selection) {
+        selectionCount++;
+
+        assert.equal(sel.text, "foo",
+          "iterable selection.text with single DOM Selection works.");
+
+        assert.equal(sel.html, "<div>foo</div>",
+          "iterable selection.html with single DOM Selection works.");
+      }
+
+      assert.equal(selectionCount, 1,
+        "One iterable selection");
+    }).then(close).then(loader.unload).then(done, assert.fail);
+}
+
+exports["test PWPB Textarea Selection"] = function(assert, done) {
+  let loader = Loader(module);
+  let selection = loader.require("sdk/selection");
+
+  open(URL, {private: true, title: "PWPB Textarea Listener"}).
+    then(selectTextarea).
+    then(focus).
+    then(function() {
+
+      assert.equal(selection.isContiguous, true,
+        "selection.isContiguous with Textarea Selection works.");
+
+      assert.equal(selection.text, "noodles",
+        "selection.text with Textarea Selection works.");
+
+      assert.strictEqual(selection.html, null,
+        "selection.html with Textarea Selection works.");
+
+      let selectionCount = 0;
+      for each (let sel in selection) {
+        selectionCount++;
+
+        assert.equal(sel.text, "noodles",
+          "iterable selection.text with Textarea Selection works.");
+
+        assert.strictEqual(sel.html, null,
+          "iterable selection.html with Textarea Selection works.");
+      }
+
+      assert.equal(selectionCount, 1,
+        "One iterable selection");
+
+    }).then(close).then(loader.unload).then(done, assert.fail);
+};
+
+exports["test PWPB Set HTML in Multiple DOM Selection"] = function(assert, done) {
+  let loader = Loader(module);
+  let selection = loader.require("sdk/selection");
+
+  open(URL, {private: true, title: "PWPB Set HTML in Multiple DOM Selection"}).
+    then(selectAllDivs).
+    then(focus).
+    then(function() {
+      let html = "<span>b<b>a</b>r</span>";
+
+      let expectedText = ["bar", "and"];
+      let expectedHTML = [html, "<div>and</div>"];
+
+      selection.html = html;
+
+      assert.equal(selection.text, expectedText[0],
+        "set selection.text with DOM Selection works.");
+
+      assert.equal(selection.html, expectedHTML[0],
+        "selection.html with DOM Selection works.");
+
+      let selectionCount = 0;
+      for each (let sel in selection) {
+
+        assert.equal(sel.text, expectedText[selectionCount],
+          "iterable selection.text with multiple DOM Selection works.");
+
+        assert.equal(sel.html, expectedHTML[selectionCount],
+          "iterable selection.html with multiple DOM Selection works.");
+
+        selectionCount++;
+      }
+
+      assert.equal(selectionCount, 2,
+        "Two iterable selections");
+    }).then(close).then(loader.unload).then(done, assert.fail);
+};
+
+exports["test PWPB Set Text in Textarea Selection"] = function(assert, done) {
+  let loader = Loader(module);
+  let selection = loader.require("sdk/selection");
+
+  open(URL, {private: true, title: "test PWPB Set Text in Textarea Selection"}).
+    then(selectTextarea).
+    then(focus).
+    then(function() {
+
+      let text = "bar";
+
+      selection.text = text;
+
+      assert.equal(selection.text, text,
+        "set selection.text with Textarea Selection works.");
+
+      assert.strictEqual(selection.html, null,
+        "selection.html with Textarea Selection works.");
+
+      let selectionCount = 0;
+      for each (let sel in selection) {
+        selectionCount++;
+
+        assert.equal(sel.text, text,
+          "iterable selection.text with Textarea Selection works.");
+
+        assert.strictEqual(sel.html, null,
+          "iterable selection.html with Textarea Selection works.");
+      }
+
+      assert.equal(selectionCount, 1,
+        "One iterable selection");
+
+    }).then(close).then(loader.unload).then(done, assert.fail);
+};
+
+// If the platform doesn't support the PBPW, we're replacing PBPW tests
+if (!require("sdk/private-browsing/utils").isWindowPBSupported) {
+  module.exports = {
+    "test PBPW Unsupported": function Unsupported (assert) {
+      assert.pass("Private Window Per Browsing is not supported on this platform.");
+    }
+  }
+}
+
+// If the module doesn't support the app we're being run in, require() will
+// throw.  In that case, remove all tests above from exports, and add one dummy
+// test that passes.
+try {
+  require("sdk/selection");
+}
+catch (err) {
+  if (!/^Unsupported Application/.test(err.message))
+    throw err;
+
+  module.exports = {
+    "test Unsupported Application": function Unsupported (assert) {
+      assert.pass(err.message);
+    }
+  }
+}
new file mode 100644
--- /dev/null
+++ b/addon-sdk/source/test/addons/private-browsing-supported/test-tabs.js
@@ -0,0 +1,32 @@
+'use strict';
+
+const tabs = require('sdk/tabs');
+const { is } = require('sdk/system/xul-app');
+const { isPrivate } = require('sdk/private-browsing');
+const pbUtils = require('sdk/private-browsing/utils');
+const { getOwnerWindow } = require('sdk/private-browsing/window/utils');
+
+exports.testPrivateTabsAreListed = function (assert, done) {
+  let originalTabCount = tabs.length;
+
+  tabs.open({
+    url: 'about:blank',
+    isPrivate: true,
+    onOpen: function(tab) {
+      let win = getOwnerWindow(tab);
+      // PWPB case
+      if (pbUtils.isWindowPBSupported || pbUtils.isTabPBSupported) {
+        assert.ok(isPrivate(tab), "tab is private");
+        assert.equal(tabs.length, originalTabCount + 1,
+                     'New private window\'s tab are visible in tabs list');
+      }
+      else {
+      // Global case, openDialog didn't opened a private window/tab
+        assert.ok(!isPrivate(tab), "tab isn't private");
+        assert.equal(tabs.length, originalTabCount + 1,
+                     'New non-private window\'s tab is visible in tabs list');
+      }
+      tab.close(done);
+    }
+  });
+}
new file mode 100644
--- /dev/null
+++ b/addon-sdk/source/test/addons/private-browsing-supported/test-windows.js
@@ -0,0 +1,255 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+'use strict';
+
+const { Cc, Ci } = require('chrome');
+const { isPrivate } = require('sdk/private-browsing');
+const { isWindowPBSupported } = require('sdk/private-browsing/utils');
+const { onFocus, getMostRecentWindow, getWindowTitle,
+        getFrames, windows, open: openWindow, isWindowPrivate } = require('sdk/window/utils');
+const { open, close, focus, promise } = require('sdk/window/helpers');
+const { browserWindows } = require("sdk/windows");
+const winUtils = require("sdk/deprecated/window-utils");
+const { fromIterator: toArray } = require('sdk/util/array');
+const tabs = require('sdk/tabs');
+
+const WM = Cc['@mozilla.org/appshell/window-mediator;1'].getService(Ci.nsIWindowMediator);
+
+const BROWSER = 'chrome://browser/content/browser.xul';
+
+function makeEmptyBrowserWindow(options) {
+  options = options || {};
+  return open(BROWSER, {
+    features: {
+      chrome: true,
+      private: !!options.private
+    }
+  });
+}
+
+exports.testWindowTrackerIgnoresPrivateWindows = function(assert, done) {
+  var myNonPrivateWindow, myPrivateWindow;
+  var finished = false;
+  var privateWindow;
+  var privateWindowClosed = false;
+  var privateWindowOpened = false;
+
+  let wt = winUtils.WindowTracker({
+    onTrack: function(window) {
+      if (window === myPrivateWindow) {
+        assert.equal(isPrivate(window), isWindowPBSupported);
+        privateWindowOpened = true;
+      }
+    },
+    onUntrack: function(window) {
+      if (window === myPrivateWindow && isWindowPBSupported) {
+        privateWindowClosed = true;
+      }
+
+      if (window === myNonPrivateWindow) {
+        assert.equal(privateWindowClosed, isWindowPBSupported);
+        assert.ok(privateWindowOpened);
+        wt.unload();
+        done();
+      }
+    }
+  });
+
+  // make a new private window
+  myPrivateWindow = openWindow(BROWSER, {
+  	features: {
+      private: true
+    }
+  });
+  promise(myPrivateWindow, 'load').then(function(window) {
+    assert.equal(isPrivate(window), isWindowPBSupported, 'private window isPrivate');
+    assert.equal(isWindowPrivate(window), isWindowPBSupported);
+    assert.ok(getFrames(window).length > 1, 'there are frames for private window');
+    assert.equal(getWindowTitle(window), window.document.title,
+                 'getWindowTitle works');
+
+    close(myPrivateWindow).then(function() {
+      assert.pass('private window was closed');
+      makeEmptyBrowserWindow().then(function(window) {
+        myNonPrivateWindow = window;
+        assert.notDeepEqual(myPrivateWindow, myNonPrivateWindow);
+        assert.pass('opened new window');
+        close(myNonPrivateWindow).then(function() {
+          assert.pass('non private window was closed');
+        })
+      });
+    });
+  });
+};
+
+// Test setting activeWIndow and onFocus for private windows
+exports.testSettingActiveWindowDoesNotIgnorePrivateWindow = function(assert, done) {
+  let browserWindow = WM.getMostRecentWindow("navigator:browser");
+  let testSteps;
+
+  assert.equal(winUtils.activeBrowserWindow, browserWindow,
+               "Browser window is the active browser window.");
+  assert.ok(!isPrivate(browserWindow), "Browser window is not private.");
+
+  // make a new private window
+  makeEmptyBrowserWindow({
+    private: true
+  }).then(focus).then(function(window) {
+    let continueAfterFocus = function(window) onFocus(window).then(nextTest);
+
+    // PWPB case
+    if (isWindowPBSupported) {
+      assert.ok(isPrivate(window), "window is private");
+      assert.notDeepEqual(winUtils.activeBrowserWindow, browserWindow);
+    }
+    // Global case
+    else {
+      assert.ok(!isPrivate(window), "window is not private");
+    }
+
+    assert.strictEqual(winUtils.activeBrowserWindow, window,
+                 "Correct active browser window pb supported");
+    assert.notStrictEqual(browserWindow, window,
+                 "The window is not the old browser window");
+
+    testSteps = [
+      function() {
+        // test setting a non private window
+        continueAfterFocus(winUtils.activeWindow = browserWindow);
+      },
+      function() {
+        assert.strictEqual(winUtils.activeWindow, browserWindow,
+                           "Correct active window [1]");
+        assert.strictEqual(winUtils.activeBrowserWindow, browserWindow,
+                           "Correct active browser window [1]");
+
+        // test focus(window)
+        focus(window).then(nextTest);
+      },
+      function(w) {
+        assert.strictEqual(w, window, 'require("sdk/window/helpers").focus on window works');
+        assert.strictEqual(winUtils.activeBrowserWindow, window,
+                           "Correct active browser window [2]");
+        assert.strictEqual(winUtils.activeWindow, window,
+                           "Correct active window [2]");
+
+        // test setting a private window
+        continueAfterFocus(winUtils.activeWindow = window);
+      },
+      function() {
+        assert.deepEqual(winUtils.activeBrowserWindow, window,
+                         "Correct active browser window [3]");
+        assert.deepEqual(winUtils.activeWindow, window,
+                         "Correct active window [3]");
+
+        // just to get back to original state
+        continueAfterFocus(winUtils.activeWindow = browserWindow);
+      },
+      function() {
+        assert.deepEqual(winUtils.activeBrowserWindow, browserWindow,
+                         "Correct active browser window when pb mode is supported [4]");
+        assert.deepEqual(winUtils.activeWindow, browserWindow,
+                         "Correct active window when pb mode is supported [4]");
+
+        close(window).then(done);
+      }
+    ];
+
+    function nextTest() {
+      let args = arguments;
+      if (testSteps.length) {
+        require('sdk/timers').setTimeout(function() {
+          (testSteps.shift()).apply(null, args);
+        }, 0);
+      }
+    }
+    nextTest();
+  });
+};
+
+exports.testActiveWindowDoesNotIgnorePrivateWindow = function(assert, done) {
+  // make a new private window
+  makeEmptyBrowserWindow({
+    private: true
+  }).then(focus).then(function(window) {
+    // PWPB case
+    if (isWindowPBSupported) {
+      assert.equal(isPrivate(winUtils.activeWindow), true,
+                   "active window is private");
+      assert.equal(isPrivate(winUtils.activeBrowserWindow), true,
+                   "active browser window is private");
+      assert.ok(isWindowPrivate(window), "window is private");
+      assert.ok(isPrivate(window), "window is private");
+
+      // pb mode is supported
+      assert.ok(
+        isWindowPrivate(winUtils.activeWindow),
+        "active window is private when pb mode is supported");
+      assert.ok(
+        isWindowPrivate(winUtils.activeBrowserWindow),
+        "active browser window is private when pb mode is supported");
+      assert.ok(isPrivate(winUtils.activeWindow),
+                "active window is private when pb mode is supported");
+      assert.ok(isPrivate(winUtils.activeBrowserWindow),
+        "active browser window is private when pb mode is supported");
+    }
+    // Global case
+    else {
+      assert.equal(isPrivate(winUtils.activeWindow), false,
+                   "active window is not private");
+      assert.equal(isPrivate(winUtils.activeBrowserWindow), false,
+                   "active browser window is not private");
+      assert.equal(isWindowPrivate(window), false, "window is not private");
+      assert.equal(isPrivate(window), false, "window is not private");
+    }
+
+    close(window).then(done);
+  });
+}
+
+exports.testWindowIteratorIgnoresPrivateWindows = function(assert, done) {
+  // make a new private window
+  makeEmptyBrowserWindow({
+    private: true
+  }).then(focus).then(function(window) {
+    assert.equal(isWindowPrivate(window), isWindowPBSupported);
+    assert.ok(toArray(winUtils.windowIterator()).indexOf(window) > -1,
+              "window is in windowIterator()");
+
+    close(window).then(done);
+  });
+};
+
+// test that it is not possible to find a private window in
+// windows module's iterator
+exports.testWindowIteratorPrivateDefault = function(assert, done) {
+  // there should only be one window open here, if not give us the
+  // the urls
+  if (browserWindows.length > 1) {
+    for each (let tab in tabs) {
+      assert.fail("TAB URL: " + tab.url);
+    }
+  }
+  else {
+    assert.equal(browserWindows.length, 1, 'only one window open');
+  }
+
+  open('chrome://browser/content/browser.xul', {
+    features: {
+      private: true,
+      chrome: true
+    }
+  }).then(focus).then(function(window) {
+    // test that there is a private window opened
+    assert.equal(isPrivate(window), isWindowPBSupported, 'there is a private window open');
+    assert.equal(isPrivate(winUtils.activeWindow), isWindowPBSupported);
+    assert.equal(isPrivate(getMostRecentWindow()), isWindowPBSupported);
+    assert.equal(isPrivate(browserWindows.activeWindow), isWindowPBSupported);
+
+    assert.equal(browserWindows.length, 2, '2 windows open');
+    assert.equal(windows(null, { includePrivate: true }).length, 2);
+
+    close(window).then(done);
+  });
+};
deleted file mode 100644
--- a/addon-sdk/source/test/addons/private-browsing-supported/windows.js
+++ /dev/null
@@ -1,245 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-'use strict';
-
-const { Cc, Ci } = require('chrome');
-const { isPrivate } = require('sdk/private-browsing');
-const { isWindowPBSupported } = require('sdk/private-browsing/utils');
-const { onFocus, getMostRecentWindow, getWindowTitle,
-        getFrames, windows, open: openWindow, isWindowPrivate } = require('sdk/window/utils');
-const { open, close, focus, promise } = require('sdk/window/helpers');
-const { browserWindows } = require("sdk/windows");
-const winUtils = require("sdk/deprecated/window-utils");
-const { fromIterator: toArray } = require('sdk/util/array');
-
-const WM = Cc['@mozilla.org/appshell/window-mediator;1'].getService(Ci.nsIWindowMediator);
-
-const BROWSER = 'chrome://browser/content/browser.xul';
-
-function makeEmptyBrowserWindow(options) {
-  options = options || {};
-  return open(BROWSER, {
-    features: {
-      chrome: true,
-      private: !!options.private
-    }
-  });
-}
-
-exports.testWindowTrackerIgnoresPrivateWindows = function(assert, done) {
-  var myNonPrivateWindow, myPrivateWindow;
-  var finished = false;
-  var privateWindow;
-  var privateWindowClosed = false;
-  var privateWindowOpened = false;
-
-  let wt = winUtils.WindowTracker({
-    onTrack: function(window) {
-      if (window === myPrivateWindow) {
-        assert.equal(isPrivate(window), isWindowPBSupported);
-        privateWindowOpened = true;
-      }
-    },
-    onUntrack: function(window) {
-      if (window === myPrivateWindow && isWindowPBSupported) {
-        privateWindowClosed = true;
-      }
-
-      if (window === myNonPrivateWindow) {
-        assert.equal(privateWindowClosed, isWindowPBSupported);
-        assert.ok(privateWindowOpened);
-        wt.unload();
-        done();
-      }
-    }
-  });
-
-  // make a new private window
-  myPrivateWindow = openWindow(BROWSER, {
-  	features: {
-      private: true
-    }
-  });
-  promise(myPrivateWindow, 'load').then(function(window) {
-    assert.equal(isPrivate(window), isWindowPBSupported, 'private window isPrivate');
-    assert.equal(isWindowPrivate(window), isWindowPBSupported);
-    assert.ok(getFrames(window).length > 1, 'there are frames for private window');
-    assert.equal(getWindowTitle(window), window.document.title,
-                 'getWindowTitle works');
-
-    close(myPrivateWindow).then(function() {
-      assert.pass('private window was closed');
-      makeEmptyBrowserWindow().then(function(window) {
-        myNonPrivateWindow = window;
-        assert.notDeepEqual(myPrivateWindow, myNonPrivateWindow);
-        assert.pass('opened new window');
-        close(myNonPrivateWindow).then(function() {
-          assert.pass('non private window was closed');
-        })
-      });
-    });
-  });
-};
-
-// Test setting activeWIndow and onFocus for private windows
-exports.testSettingActiveWindowDoesNotIgnorePrivateWindow = function(assert, done) {
-  let browserWindow = WM.getMostRecentWindow("navigator:browser");
-  let testSteps;
-
-  assert.equal(winUtils.activeBrowserWindow, browserWindow,
-               "Browser window is the active browser window.");
-  assert.ok(!isPrivate(browserWindow), "Browser window is not private.");
-
-  // make a new private window
-  makeEmptyBrowserWindow({
-    private: true
-  }).then(focus).then(function(window) {
-    let continueAfterFocus = function(window) onFocus(window).then(nextTest);
-
-    // PWPB case
-    if (isWindowPBSupported) {
-      assert.ok(isPrivate(window), "window is private");
-      assert.notDeepEqual(winUtils.activeBrowserWindow, browserWindow);
-    }
-    // Global case
-    else {
-      assert.ok(!isPrivate(window), "window is not private");
-    }
-
-    assert.strictEqual(winUtils.activeBrowserWindow, window,
-                 "Correct active browser window pb supported");
-    assert.notStrictEqual(browserWindow, window,
-                 "The window is not the old browser window");
-
-    testSteps = [
-      function() {
-        // test setting a non private window
-        continueAfterFocus(winUtils.activeWindow = browserWindow);
-      },
-      function() {
-        assert.strictEqual(winUtils.activeWindow, browserWindow,
-                           "Correct active window [1]");
-        assert.strictEqual(winUtils.activeBrowserWindow, browserWindow,
-                           "Correct active browser window [1]");
-
-        // test focus(window)
-        focus(window).then(nextTest);
-      },
-      function(w) {
-        assert.strictEqual(w, window, 'require("sdk/window/helpers").focus on window works');
-        assert.strictEqual(winUtils.activeBrowserWindow, window,
-                           "Correct active browser window [2]");
-        assert.strictEqual(winUtils.activeWindow, window,
-                           "Correct active window [2]");
-
-        // test setting a private window
-        continueAfterFocus(winUtils.activeWindow = window);
-      },
-      function() {
-        assert.deepEqual(winUtils.activeBrowserWindow, window,
-                         "Correct active browser window [3]");
-        assert.deepEqual(winUtils.activeWindow, window,
-                         "Correct active window [3]");
-
-        // just to get back to original state
-        continueAfterFocus(winUtils.activeWindow = browserWindow);
-      },
-      function() {
-        assert.deepEqual(winUtils.activeBrowserWindow, browserWindow,
-                         "Correct active browser window when pb mode is supported [4]");
-        assert.deepEqual(winUtils.activeWindow, browserWindow,
-                         "Correct active window when pb mode is supported [4]");
-
-        close(window).then(done);
-      }
-    ];
-
-    function nextTest() {
-      let args = arguments;
-      if (testSteps.length) {
-        require('sdk/timers').setTimeout(function() {
-          (testSteps.shift()).apply(null, args);
-        }, 0);
-      }
-    }
-    nextTest();
-  });
-};
-
-exports.testActiveWindowDoesNotIgnorePrivateWindow = function(assert, done) {
-  // make a new private window
-  makeEmptyBrowserWindow({
-    private: true
-  }).then(function(window) {
-    // PWPB case
-    if (isWindowPBSupported) {
-      assert.equal(isPrivate(winUtils.activeWindow), true,
-                   "active window is private");
-      assert.equal(isPrivate(winUtils.activeBrowserWindow), true,
-                   "active browser window is private");
-      assert.ok(isWindowPrivate(window), "window is private");
-      assert.ok(isPrivate(window), "window is private");
-
-      // pb mode is supported
-      assert.ok(
-        isWindowPrivate(winUtils.activeWindow),
-        "active window is private when pb mode is supported");
-      assert.ok(
-        isWindowPrivate(winUtils.activeBrowserWindow),
-        "active browser window is private when pb mode is supported");
-      assert.ok(isPrivate(winUtils.activeWindow),
-                "active window is private when pb mode is supported");
-      assert.ok(isPrivate(winUtils.activeBrowserWindow),
-        "active browser window is private when pb mode is supported");
-    }
-    // Global case
-    else {
-      assert.equal(isPrivate(winUtils.activeWindow), false,
-                   "active window is not private");
-      assert.equal(isPrivate(winUtils.activeBrowserWindow), false,
-                   "active browser window is not private");
-      assert.equal(isWindowPrivate(window), false, "window is not private");
-      assert.equal(isPrivate(window), false, "window is not private");
-    }
-
-    close(window).then(done);
-  });
-}
-
-exports.testWindowIteratorIgnoresPrivateWindows = function(assert, done) {
-  // make a new private window
-  makeEmptyBrowserWindow({
-    private: true
-  }).then(function(window) {
-    assert.equal(isWindowPrivate(window), isWindowPBSupported);
-    assert.ok(toArray(winUtils.windowIterator()).indexOf(window) > -1,
-              "window is in windowIterator()");
-
-    close(window).then(done);
-  });
-};
-
-// test that it is not possible to find a private window in
-// windows module's iterator
-exports.testWindowIteratorPrivateDefault = function(assert, done) {
-  assert.equal(browserWindows.length, 1, 'only one window open');
-
-  open('chrome://browser/content/browser.xul', {
-    features: {
-      private: true,
-      chrome: true
-    }
-  }).then(function(window) {
-    // test that there is a private window opened
-    assert.equal(isPrivate(window), isWindowPBSupported, 'there is a private window open');
-    assert.equal(isPrivate(winUtils.activeWindow), isWindowPBSupported);
-    assert.equal(isPrivate(getMostRecentWindow()), isWindowPBSupported);
-    assert.equal(isPrivate(browserWindows.activeWindow), isWindowPBSupported);
-
-    assert.equal(browserWindows.length, 2, '2 windows open');
-    assert.equal(windows(null, { includePrivate: true }).length, 2);
-
-    close(window).then(done);
-  });
-};
--- a/addon-sdk/source/test/private-browsing/tabs.js
+++ b/addon-sdk/source/test/private-browsing/tabs.js
@@ -7,17 +7,17 @@ const { getOwnerWindow } = require('sdk/
 
 exports.testIsPrivateOnTab = function(test) {
   let window = browserWindows.activeWindow;
   let chromeWindow = getOwnerWindow(window);
   test.assert(chromeWindow instanceof Ci.nsIDOMWindow, 'associated window is found');
   test.assert(!pb.isPrivate(chromeWindow), 'the top level window is not private');
 
   let rawTab = openTab(chromeWindow, 'data:text/html,<h1>Hi!</h1>', {
-  	isPrivate: true
+    isPrivate: true
   });
 
   // test that the tab is private
   test.assert(rawTab.browser.docShell.QueryInterface(Ci.nsILoadContext).usePrivateBrowsing);
   test.assert(pb.isPrivate(rawTab.browser.contentWindow));
   test.assert(pb.isPrivate(rawTab.browser));
 
   closeTab(rawTab);
--- a/addon-sdk/source/test/test-cuddlefish.js
+++ b/addon-sdk/source/test/test-cuddlefish.js
@@ -8,19 +8,17 @@ const { Loader, Require, unload, overrid
 const packaging = require('@loader/options');
 
 exports['test loader'] = function(assert) {
   var prints = [];
   function print(message) {
     prints.push(message);
   }
 
-  let options = JSON.parse(JSON.stringify(packaging));
-
-  let loader = Loader(override(options, {
+  let loader = Loader(override(packaging, {
     globals: {
       print: print,
       foo: 1
     }
   }));
   let require = Require(loader, module);
 
   var fixture = require('./loader/fixture');
--- a/addon-sdk/source/test/test-heritage.js
+++ b/addon-sdk/source/test/test-heritage.js
@@ -74,63 +74,16 @@ exports['test inheritance'] = function(a
   assert.ok(Descendant() instanceof Descendant,
             'instantiates correctly');
   assert.ok(Descendant() instanceof Ancestor,
             'Inherits for passed `extends`');
   assert.equal(Descendant().method(), 'hello descendant',
                'propreties inherited');
 };
 
-exports['test prototype immutability'] = function(assert) {
-  let Foo = Class({
-    name: 'hello',
-    rename: function rename(name) {
-      this.name = name;
-    }
-  });
-
-  /* Disable until release with Bug 674195 fix is shipped
-  assert.ok(Object.isFrozen(Foo), 'Foo is frozen');
-  assert.ok(Object.isFrozen(Foo.prototype), 'Foo prototype is frozen');
-  assert.ok(Object.isFrozen(Object.getPrototypeOf(Foo.prototype)),
-            'Class.prototype is frozen');
-  assert.equal(Object.getPrototypeOf(Object.getPrototypeOf(Foo.prototype)),
-               null, 'prototype of Class.prototype is null');
-  */
-
-  assert.throws(function() {
-    var override = function() {};
-    Foo.prototype.extend = override;
-    if (Foo.prototype.extend !== override)
-      throw Error('Property was not set');
-  }, 'Can not change prototype properties');
-
-  assert.throws(function() {
-    Foo.prototype.foo = 'bar';
-    if (Foo.prototype.foo !== 'bar')
-      throw Error('Property was not set');
-  }, 'Can not add prototype properties');
-
-  assert.throws(function() {
-    delete Foo.prototype.name;
-    if ('name' in Foo.prototype)
-      throw Error('Property was not deleted');
-  }, 'Can not remove prototype properties');
-
-  var Bar = Class({
-    extends: Foo,
-    rename: function rename() {
-      return this.name;
-    }
-  });
-
-  assert.equal(Bar().rename(), 'hello',
-               'properties may be overided on decedents');
-};
-
 exports['test immunity against __proto__'] = function(assert) {
   let Foo = Class({ name: 'foo', hacked: false });
 
   let Bar = Class({ extends: Foo, name: 'bar' });
 
   assert.throws(function() {
     Foo.prototype.__proto__ = { hacked: true };
     if (Foo() instanceof Base && !Foo().hacked)
@@ -139,45 +92,16 @@ exports['test immunity against __proto__
 
   assert.throws(function() {
     Foo.prototype.__proto__ = { hacked: true };
     if (Bar() instanceof Foo && !Bar().hacked)
       throw Error('can not change prototype chain');
   }, 'prototype chain of decedants immune to __proto__ hacks');
 };
 
-exports['test instance mutability'] = function(assert) {
-  let Foo = Class({
-    name: 'foo',
-    initialize: function initialize(number) {
-      this.number = number;
-    }
-  });
-
-  let f1 = Foo();
-
-  assert.throws(function() {
-    f1.initialize = 'f1';
-    if (f1.name !== 'f1')
-      throw Error('Property was not set');
-  }, 'can not change prototype properties');
-
-  f1.alias = 'f1';
-  assert.equal(f1.alias, 'f1', 'instance is mutable');
-
-  delete f1.alias;
-  assert.ok(!('alias' in f1), 'own properties are deletable');
-
-  f1.initialize(1);
-  assert.equal(f1.number, 1, 'method can mutate instances own properties');
-
-  f1.name = 'bar';
-  assert.equal(f1.name, 'bar', 'data properties are mutable on instance');
-};
-
 exports['test super'] = function(assert) {
   var Foo = Class({
     initialize: function initialize(options) {
       this.name = options.name;
     }
   });
 
   var Bar = Class({
--- a/addon-sdk/source/test/test-page-mod.js
+++ b/addon-sdk/source/test/test-page-mod.js
@@ -1,24 +1,28 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 "use strict";
 
-const pageMod = require("sdk/page-mod");
+const { PageMod } = require("sdk/page-mod");
 const testPageMod = require("./pagemod-test-helpers").testPageMod;
 const { Loader } = require('sdk/test/loader');
 const tabs = require("sdk/tabs");
 const timer = require("sdk/timers");
 const { Cc, Ci } = require("chrome");
-const { open, getFrames, getMostRecentBrowserWindow } = require('sdk/window/utils');
+const { open, openDialog, getFrames, getMostRecentBrowserWindow } = require('sdk/window/utils');
 const windowUtils = require('sdk/deprecated/window-utils');
-const { getTabContentWindow, getActiveTab, openTab, closeTab } = require('sdk/tabs/utils');
-const { is } = require('sdk/system/xul-app');
+const windowHelpers = require('sdk/window/helpers');
+const { getTabContentWindow, getActiveTab, setTabURL, openTab, closeTab } = require('sdk/tabs/utils');
+const xulApp = require("sdk/system/xul-app");
 const { data } = require('sdk/self');
+const { isPrivate } = require('sdk/private-browsing');
+const { isTabPBSupported, isWindowPBSupported } = require('sdk/private-browsing/utils');
+const promise = require("sdk/core/promise");
 
 /* XXX This can be used to delay closing the test Firefox instance for interactive
  * testing or visual inspection. This test is registered first so that it runs
  * the last. */
 exports.delay = function(test) {
   if (false) {
     test.waitUntilDone(60000);
     timer.setTimeout(function() {test.done();}, 4000);
@@ -131,17 +135,17 @@ exports.testPageModIncludes = function(t
             done();
           });
     }
     );
 };
 
 exports.testPageModErrorHandling = function(test) {
   test.assertRaises(function() {
-      new pageMod.PageMod();
+      new PageMod();
     },
     'pattern is undefined',
     "PageMod() throws when 'include' option is not specified.");
 };
 
 /* Tests for internal functions. */
 exports.testCommunication1 = function(test) {
   let workerDone = false,
@@ -334,17 +338,16 @@ exports.testHistory = function(test) {
     }
   );
 };
 
 exports.testRelatedTab = function(test) {
   test.waitUntilDone();
 
   let tab;
-  let { PageMod } = require("sdk/page-mod");
   let pageMod = new PageMod({
     include: "about:*",
     onAttach: function(worker) {
       test.assert(!!worker.tab, "Worker.tab exists");
       test.assertEqual(tab, worker.tab, "Worker.tab is valid");
       pageMod.destroy();
       tab.close(function() {
         test.done();
@@ -543,17 +546,17 @@ exports.testAttachToTabsOnly = function(
     let hiddenFrames = require('sdk/frame/hidden-frame');
     let hiddenFrame = hiddenFrames.add(hiddenFrames.HiddenFrame({
       onReady: function () {
         let element = this.element;
         element.addEventListener('DOMContentLoaded', function onload() {
           element.removeEventListener('DOMContentLoaded', onload, false);
           hiddenFrames.remove(hiddenFrame);
 
-          if (!is("Fennec")) {
+          if (!xulApp.is("Fennec")) {
             openToplevelWindow();
           }
           else {
             openBrowserIframe(); 
           }
         }, false);
         element.setAttribute('src', 'data:text/html;charset=utf-8,foo');
       }
@@ -950,17 +953,17 @@ exports.testExistingOnFrames = function(
   let window = getTabContentWindow(tab);
 
   function wait4Iframes() {
     if (window.document.readyState != "complete" ||
         getFrames(window).length != 2) {
       return;
     }
 
-    let pagemodOnExisting = pageMod.PageMod({
+    let pagemodOnExisting = PageMod({
       include: ["*", "data:*"],
       attachTo: ["existing", "frame"],
       contentScriptWhen: 'ready',
       onAttach: function(worker) {
         // need to ignore urls that are not part of the test, because other
         // tests are not closing their tabs when they complete..
         if (urls.indexOf(worker.url) == -1)
           return;
@@ -985,17 +988,17 @@ exports.testExistingOnFrames = function(
             pagemodOffExisting.destroy();
             closeTab(tab);
             test.done();
           }, 0);
         }
       }
     });
 
-    let pagemodOffExisting = pageMod.PageMod({
+    let pagemodOffExisting = PageMod({
       include: ["*", "data:*"],
       attachTo: ["frame"],
       contentScriptWhen: 'ready',
       onAttach: function(mod) {
         test.fail('pagemodOffExisting page-mod should not have been attached');
       }
     });
   }
@@ -1046,8 +1049,67 @@ exports.testEvents = function(test) {
       test.assert(
         win.receivedEvent,
         "Content script sent an event and document received it"
       );
       done();
     }
   );
 };
+
+function openWebpage(url, enablePrivate) {
+  if (xulApp.is("Fennec")) {
+    let chromeWindow = getMostRecentBrowserWindow();
+    let rawTab = openTab(chromeWindow, url, {
+      isPrivate: enablePrivate
+    });
+    return {
+      close: function () {
+        closeTab(rawTab)
+        // Returns a resolved promise as there is no need to wait
+        return promise.resolve();
+      }
+    };
+  }
+  else {
+    let win = openDialog({
+      private: enablePrivate
+    });
+    win.addEventListener("load", function onLoad() {
+      win.removeEventListener("load", onLoad, false);
+      setTabURL(getActiveTab(win), url);
+    });
+    return {
+      close: function () {
+        return windowHelpers.close(win);
+      }
+    };
+  }
+}
+
+exports["test page-mod on private tab"] = function (test) {
+  test.waitUntilDone();
+  let privateUri = "data:text/html;charset=utf-8," +
+                   "<iframe src=\"data:text/html;charset=utf-8,frame\" />";
+  let nonPrivateUri = "data:text/html;charset=utf-8,non-private";
+
+  let pageMod = new PageMod({
+    include: "data:*",
+    onAttach: function(worker) {
+      if (isTabPBSupported || isWindowPBSupported) {
+        // When PB isn't supported, the page-mod will apply to all document
+        // as all of them will be non-private
+        test.assertEqual(worker.tab.url,
+                         nonPrivateUri,
+                         "page-mod should only attach to the non-private tab");
+      }
+      test.assert(!isPrivate(worker),
+                  "The worker is really non-private");
+      test.assert(!isPrivate(worker.tab),
+                  "The document is really non-private");
+      pageMod.destroy();
+      page1.close().then(page2.close).then(test.done.bind(test));
+    }
+  });
+
+  let page1 = openWebpage(privateUri, true);
+  let page2 = openWebpage(nonPrivateUri, false);
+}
--- a/addon-sdk/source/test/test-panel.js
+++ b/addon-sdk/source/test/test-panel.js
@@ -1,17 +1,36 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+ 'use strict';
 
-let { Cc, Ci } = require("chrome");
+const { Cc, Ci } = require("chrome");
 const { Loader } = require('sdk/test/loader');
 const { LoaderWithHookedConsole } = require("sdk/test/loader");
 const timer = require("sdk/timers");
 const self = require('sdk/self');
+const { open, close, focus } = require('sdk/window/helpers');
+const { isPrivate } = require('sdk/private-browsing');
+const { isWindowPBSupported } = require('sdk/private-browsing/utils');
+const { defer } = require('sdk/core/promise');
+const { getMostRecentBrowserWindow } = require('sdk/window/utils');
+
+const SVG_URL = self.data.url('mofo_logo.SVG');
+
+function makeEmptyPrivateBrowserWindow(options) {
+  options = options || {};
+  return open('chrome://browser/content/browser.xul', {
+    features: {
+      chrome: true,
+      toolbar: true,
+      private: true
+    }
+  });
+}
 
 exports["test Panel"] = function(assert, done) {
   const { Panel } = require('sdk/panel');
 
   let panel = Panel({
     contentURL: "about:buildconfig",
     contentScript: "self.postMessage(1); self.on('message', function() self.postMessage(2));",
     onMessage: function (message) {
@@ -451,18 +470,16 @@ exports["test Content URL Option"] = fun
   }
 
   assert.throws(function () Panel({ contentURL: "foo" }),
                     /The `contentURL` option must be a valid URL./,
                     "Panel throws an exception if contentURL is not a URL.");
 };
 
 exports["test SVG Document"] = function(assert) {
-  let SVG_URL = self.data.url("mofo_logo.SVG");
-
   let panel = require("sdk/panel").Panel({ contentURL: SVG_URL });
 
   panel.show();
   panel.hide();
   panel.destroy();
 
   assert.pass("contentURL accepts a svg document");
   assert.equal(panel.contentURL, SVG_URL,
@@ -505,16 +522,147 @@ exports["test console.log in Panel"] = f
   function onMessage(type, message) {
     assert.equal(type, 'log', 'console.log() works');
     assert.equal(message, text, 'console.log() works');
     panel.destroy();
     done();
   }
 };
 
+if (isWindowPBSupported) {
+  exports.testPanelDoesNotShowInPrivateWindowNoAnchor = function(assert, done) {
+    let loader = Loader(module);
+    let { Panel } = loader.require("sdk/panel");
+    let browserWindow = getMostRecentBrowserWindow();
+
+    assert.equal(isPrivate(browserWindow), false, 'open window is not private');
+
+    let panel = Panel({
+      contentURL: SVG_URL
+    });
+
+    testShowPanel(assert, panel).
+      then(makeEmptyPrivateBrowserWindow).
+      then(focus).
+      then(function(window) {
+        assert.equal(isPrivate(window), true, 'opened window is private');
+        assert.pass('private window was focused');
+        return window;
+      }).
+      then(function(window) {
+        let { promise, resolve } = defer();
+        let showTries = 0;
+        let showCount = 0;
+
+        panel.on('show', function runTests() {
+          showCount++;
+
+          if (showTries == 2) {
+            panel.removeListener('show', runTests);
+            assert.equal(showCount, 1, 'show count is correct - 1');
+            resolve(window);
+          }
+        });
+        showTries++;
+        panel.show();
+        showTries++;
+        panel.show(browserWindow.gBrowser);
+
+        return promise;
+      }).
+      then(function(window) {
+        assert.equal(panel.isShowing, true, 'panel is still showing');
+        panel.hide();
+        assert.equal(panel.isShowing, false, 'panel is hidden');
+        return window;
+      }).
+      then(close).
+      then(function() {
+        assert.pass('private window was closed');
+      }).
+      then(testShowPanel.bind(null, assert, panel)).
+      then(done, assert.fail.bind(assert));
+  }
+
+  exports.testPanelDoesNotShowInPrivateWindowWithAnchor = function(assert, done) {
+    let loader = Loader(module);
+    let { Panel } = loader.require("sdk/panel");
+    let browserWindow = getMostRecentBrowserWindow();
+
+    assert.equal(isPrivate(browserWindow), false, 'open window is not private');
+
+    let panel = Panel({
+      contentURL: SVG_URL
+    });
+
+    testShowPanel(assert, panel).
+      then(makeEmptyPrivateBrowserWindow).
+      then(focus).
+      then(function(window) {
+        assert.equal(isPrivate(window), true, 'opened window is private');
+        assert.pass('private window was focused');
+        return window;
+      }).
+      then(function(window) {
+        let { promise, resolve } = defer();
+        let showTries = 0;
+        let showCount = 0;
+
+        panel.on('show', function runTests() {
+          showCount++;
+
+          if (showTries == 2) {
+            panel.removeListener('show', runTests);
+            assert.equal(showCount, 1, 'show count is correct - 1');
+            resolve(window);
+          }
+        });
+        showTries++;
+        panel.show(window.gBrowser);
+        showTries++;
+        panel.show(browserWindow.gBrowser);
+
+        return promise;
+      }).
+      then(function(window) {
+        assert.equal(panel.isShowing, true, 'panel is still showing');
+        panel.hide();
+        assert.equal(panel.isShowing, false, 'panel is hidden');
+        return window;
+      }).
+      then(close).
+      then(function() {
+        assert.pass('private window was closed');
+      }).
+      then(testShowPanel.bind(null, assert, panel)).
+      then(done, assert.fail.bind(assert));
+  }
+}
+
+function testShowPanel(assert, panel) {
+  let { promise, resolve } = defer();
+
+  assert.ok(!panel.isShowing, 'the panel is not showing [1]');
+
+  panel.once('show', function() {
+    assert.ok(panel.isShowing, 'the panel is showing');
+
+    panel.once('hide', function() {
+      assert.ok(!panel.isShowing, 'the panel is not showing [2]');
+
+      resolve(null);
+    });
+
+    panel.hide();
+  })
+  panel.show();
+
+  return promise;
+}
+
 try {
   require("sdk/panel");
 }
 catch (e) {
   if (!/^Unsupported Application/.test(e.message))
     throw e;
 
   module.exports = {
--- a/addon-sdk/source/test/test-promise.js
+++ b/addon-sdk/source/test/test-promise.js
@@ -1,18 +1,20 @@
 /* vim:set ts=2 sw=2 sts=2 expandtab */
 /*jshint asi: true undef: true es5: true node: true devel: true
          forin: true */
 /*global define: true */
 
 'use strict';
 
 var core = require('sdk/core/promise'),
-    defer = core.defer, resolve = core.resolve, reject = core.reject,
-    promised = core.promised
+    defer = core.defer, resolve = core.resolve, reject = core.reject, all = core.all,
+    promised = core.promised;
+
+var { setTimeout } = require('sdk/timers');
 
 exports['test all observers are notified'] = function(assert, done) {
   var expected = 'Taram pam param!'
   var deferred = defer()
   var pending = 10, i = 0
 
   function resolved(value) {
     assert.equal(value, expected, 'value resolved as expected: #' + pending)
@@ -319,9 +321,73 @@ exports['test arrays should not flatten'
 
   combine(a.promise, b.promise).then(done)
 
 
   a.resolve('Hello')
   b.resolve([ 'my', 'friend' ])
 }
 
+exports['test `all` for all promises'] = function (assert, done) {
+  all([
+    resolve(5), resolve(7), resolve(10)
+  ]).then(function (val) {
+    assert.equal(
+      val[0] === 5 &&
+      val[1] === 7 &&
+      val[2] === 10
+    , true, 'return value contains resolved promises values');
+    done();
+  }, function () {
+    assert.fail('should not call reject function');
+  });
+};
+
+exports['test `all` aborts upon first reject'] = function (assert, done) {
+  all([
+    resolve(5), reject('error'), delayedResolve()
+  ]).then(function (val) {
+    assert.fail('Successful resolve function should not be called');
+  }, function (reason) {
+    assert.equal(reason, 'error', 'should reject the `all` promise');
+    done();
+  });
+
+  function delayedResolve () {
+    var deferred = defer();
+    setTimeout(deferred.resolve, 50);
+    return deferred.promise;
+  }
+};
+
+exports['test `all` with array containing non-promise'] = function (assert, done) {
+  all([
+    resolve(5), resolve(10), 925
+  ]).then(function (val) {
+    assert.equal(val[2], 925, 'non-promises should pass-through value');
+    done();
+  }, function () {
+    assert.fail('should not be rejected');
+  });
+};
+
+exports['test `all` should resolve with an empty array'] = function (assert, done) {
+  all([]).then(function (val) {
+    assert.equal(Array.isArray(val), true, 'should return array in resolved');
+    assert.equal(val.length, 0, 'array should be empty in resolved');
+    done();
+  }, function () {
+    assert.fail('should not be rejected');
+  });
+};
+
+exports['test `all` with multiple rejected'] = function (assert, done) {
+  all([
+    reject('error1'), reject('error2'), reject('error3')
+  ]).then(function (value) {
+    assert.fail('should not be successful');
+  }, function (reason) {
+    assert.equal(reason, 'error1', 'should reject on first promise reject');
+    done();
+  });
+};
+
 require("test").run(exports)
--- a/addon-sdk/source/test/test-selection.js
+++ b/addon-sdk/source/test/test-selection.js
@@ -14,34 +14,63 @@ const HTML = "<html>\
 
 const URL = "data:text/html;charset=utf-8," + encodeURIComponent(HTML);
 
 const FRAME_HTML = "<iframe src='" + URL + "'><iframe>";
 const FRAME_URL = "data:text/html;charset=utf-8," + encodeURIComponent(FRAME_HTML);
 
 const { defer } = require("sdk/core/promise");
 const tabs = require("sdk/tabs");
+const { setTabURL } = require("sdk/tabs/utils");
 const { getActiveTab, getTabContentWindow, closeTab } = require("sdk/tabs/utils")
 const { getMostRecentBrowserWindow } = require("sdk/window/utils");
+const { open: openNewWindow } = require("sdk/window/helpers");
 const { Loader } = require("sdk/test/loader");
 const { setTimeout } = require("sdk/timers");
 const { Cu } = require("chrome");
+const { merge } = require("sdk/util/object");
+const { isPrivate } = require("sdk/private-browsing");
 
 // General purpose utility functions
 
 /**
  * Opens the url given and return a promise, that will be resolved with the
  * content window when the document is ready.
  *
  * I believe this approach could be useful in most of our unit test, that
  * requires to open a tab and need to access to its content.
  */
-function open(url) {
+function open(url, options) {
   let { promise, resolve } = defer();
 
+  if (options && typeof(options) === "object") {
+    openNewWindow("", {
+      features: merge({ toolbar: true }, options)
+    }).then(function(chromeWindow) {
+      if (isPrivate(chromeWindow) !== !!options.private)
+        throw new Error("Window should have Private set to " + !!options.private);
+
+      let tab = getActiveTab(chromeWindow);
+
+      tab.addEventListener("load", function ready(event) {
+        let { document } = getTabContentWindow(this);
+
+        if (document.readyState === "complete" && document.URL === url) {
+          this.removeEventListener(event.type, ready);
+
+          resolve(document.defaultView);
+        }
+      })
+
+      setTabURL(tab, url);
+    });
+
+    return promise;
+  };
+
   tabs.open({
     url: url,
     onReady: function(tab) {
       // Unfortunately there is no way to get a XUL Tab from SDK Tab on Firefox,
       // only on Fennec. We should implement `tabNS` also on Firefox in order
       // to have that.
 
       // Here we assuming that the most recent browser window is the one we're
@@ -53,20 +82,26 @@ function open(url) {
   });
 
   return promise;
 };
 
 /**
  * Close the Active Tab
  */
-function close() {
-  // Here we assuming that the most recent browser window is the one we're
-  // doing the test, and the active tab is the one we just opened.
-  closeTab(getActiveTab(getMostRecentBrowserWindow()));
+function close(window) {
+  if (window && window.top && typeof(window.top).close === "function") {
+    window.top.close();
+  } else {
+    // Here we assuming that the most recent browser window is the one we're
+    // doing the test, and the active tab is the one we just opened.
+    let tab = getActiveTab(getMostRecentBrowserWindow());
+
+    closeTab(tab);
+  }
 }
 
 /**
  * Reload the window given and return a promise, that will be resolved with the
  * content window after a small delay.
  */
 function reload(window) {
   let { promise, resolve } = defer();
@@ -209,30 +244,34 @@ function selectContentFirstDiv(window) {
  * Dispatch the selection event for the selection listener added by
  * `nsISelectionPrivate.addSelectionListener`
  */
 function dispatchSelectionEvent(window) {
   // We modify the selection in order to dispatch the selection's event, by
   // contract the selection by one character. So if the text selected is "foo"
   // will be "fo".
   window.getSelection().modify("extend", "backward", "character");
+
+  return window;
 }
 
 /**
  * Dispatch the selection event for the selection listener added by
  * `window.onselect` / `window.addEventListener`
  */
 function dispatchOnSelectEvent(window) {
   let { document } = window;
   let textarea = document.querySelector("textarea");
   let event = document.createEvent("UIEvents");
 
   event.initUIEvent("select", true, true, window, 1);
 
   textarea.dispatchEvent(event);
+
+  return window;
 }
 
 /**
  * Creates empty ranges and add them to selections
  */
 function createEmptySelections(window) {
   selectAllDivs(window);
 
@@ -261,17 +300,17 @@ exports["test No Selection"] = function(
 
     let selectionCount = 0;
     for each (let sel in selection)
       selectionCount++;
 
     assert.equal(selectionCount, 0,
       "No iterable selections");
 
-  }).then(close).then(loader.unload).then(done);
+  }).then(close).then(loader.unload).then(done, assert.fail);
 };
 
 exports["test Single DOM Selection"] = function(assert, done) {
   let loader = Loader(module);
   let selection = loader.require("sdk/selection");
 
   open(URL).then(selectFirstDiv).then(function() {
 
@@ -293,17 +332,17 @@ exports["test Single DOM Selection"] = f
 
       assert.equal(sel.html, "<div>foo</div>",
         "iterable selection.html with single DOM Selection works.");
     }
 
     assert.equal(selectionCount, 1,
       "One iterable selection");
 
-  }).then(close).then(loader.unload).then(done);
+  }).then(close).then(loader.unload).then(done, assert.fail);
 };
 
 exports["test Multiple DOM Selection"] = function(assert, done) {
   let loader = Loader(module);
   let selection = loader.require("sdk/selection");
 
   open(URL).then(selectAllDivs).then(function() {
     let expectedText = ["foo", "and"];
@@ -327,17 +366,17 @@ exports["test Multiple DOM Selection"] =
         "iterable selection.text with multiple DOM Selection works.");
 
       selectionCount++;
     }
 
     assert.equal(selectionCount, 2,
       "Two iterable selections");
 
-  }).then(close).then(loader.unload).then(done);
+  }).then(close).then(loader.unload).then(done, assert.fail);
 };
 
 exports["test Textarea Selection"] = function(assert, done) {
   let loader = Loader(module);
   let selection = loader.require("sdk/selection");
 
   open(URL).then(selectTextarea).then(function() {
 
@@ -359,17 +398,17 @@ exports["test Textarea Selection"] = fun
 
       assert.strictEqual(sel.html, null,
         "iterable selection.html with Textarea Selection works.");
     }
 
     assert.equal(selectionCount, 1,
       "One iterable selection");
 
-  }).then(close).then(loader.unload).then(done);
+  }).then(close).then(loader.unload).then(done, assert.fail);
 };
 
 exports["test Set Text in Multiple DOM Selection"] = function(assert, done) {
   let loader = Loader(module);
   let selection = loader.require("sdk/selection");
 
   open(URL).then(selectAllDivs).then(function() {
     let expectedText = ["bar", "and"];
@@ -393,17 +432,17 @@ exports["test Set Text in Multiple DOM S
         "iterable selection.html with multiple DOM Selection works.");
 
       selectionCount++;
     }
 
     assert.equal(selectionCount, 2,
       "Two iterable selections");
 
-  }).then(close).then(loader.unload).then(done);
+  }).then(close).then(loader.unload).then(done, assert.fail);
 };
 
 exports["test Set HTML in Multiple DOM Selection"] = function(assert, done) {
   let loader = Loader(module);
   let selection = loader.require("sdk/selection");
 
   open(URL).then(selectAllDivs).then(function() {
     let html = "<span>b<b>a</b>r</span>";
@@ -429,17 +468,17 @@ exports["test Set HTML in Multiple DOM S
         "iterable selection.html with multiple DOM Selection works.");
 
       selectionCount++;
     }
 
     assert.equal(selectionCount, 2,
       "Two iterable selections");
 
-  }).then(close).then(loader.unload).then(done);
+  }).then(close).then(loader.unload).then(done, assert.fail);
 };
 
 exports["test Set HTML as text in Multiple DOM Selection"] = function(assert, done) {
   let loader = Loader(module);
   let selection = loader.require("sdk/selection");
 
   open(URL).then(selectAllDivs).then(function() {
     let text = "<span>b<b>a</b>r</span>";
@@ -466,17 +505,17 @@ exports["test Set HTML as text in Multip
         "iterable selection.html with multiple DOM Selection works.");
 
       selectionCount++;
     }
 
     assert.equal(selectionCount, 2,
       "Two iterable selections");
 
-  }).then(close).then(loader.unload).then(done);
+  }).then(close).then(loader.unload).then(done, assert.fail);
 };
 
 exports["test Set Text in Textarea Selection"] = function(assert, done) {
   let loader = Loader(module);
   let selection = loader.require("sdk/selection");
 
   open(URL).then(selectTextarea).then(function() {
 
@@ -499,17 +538,17 @@ exports["test Set Text in Textarea Selec
 
       assert.strictEqual(sel.html, null,
         "iterable selection.html with Textarea Selection works.");
     }
 
     assert.equal(selectionCount, 1,
       "One iterable selection");
 
-  }).then(close).then(loader.unload).then(done);
+  }).then(close).then(loader.unload).then(done, assert.fail);
 };
 
 exports["test Set HTML in Textarea Selection"] = function(assert, done) {
   let loader = Loader(module);
   let selection = loader.require("sdk/selection");
 
   open(URL).then(selectTextarea).then(function() {
 
@@ -534,17 +573,17 @@ exports["test Set HTML in Textarea Selec
 
       assert.strictEqual(sel.html, null,
         "iterable selection.html with Textarea Selection works.");
     }
 
     assert.equal(selectionCount, 1,
       "One iterable selection");
 
-  }).then(close).then(loader.unload).then(done);
+  }).then(close).then(loader.unload).then(done, assert.fail);
 };
 
 exports["test Empty Selections"] = function(assert, done) {
   let loader = Loader(module);
   let selection = loader.require("sdk/selection");
 
   open(URL).then(createEmptySelections).then(function(){
     assert.equal(selection.isContiguous, false,
@@ -558,17 +597,17 @@ exports["test Empty Selections"] = funct
 
     let selectionCount = 0;
     for each (let sel in selection)
       selectionCount++;
 
     assert.equal(selectionCount, 0,
       "No iterable selections");
 
-  }).then(close).then(loader.unload).then(done);
+  }).then(close).then(loader.unload).then(done, assert.fail);
 }
 
 
 exports["test No Selection Exception"] = function(assert, done) {
   const NO_SELECTION = /It isn't possible to change the selection/;
 
   let loader = Loader(module);
   let selection = loader.require("sdk/selection");
@@ -579,17 +618,17 @@ exports["test No Selection Exception"] =
     assert.throws(function() {
       selection.text = "bar";
     }, NO_SELECTION);
 
     assert.throws(function() {
       selection.html = "bar";
     }, NO_SELECTION);
 
-  }).then(close).then(loader.unload).then(done);
+  }).then(close).then(loader.unload).then(done, assert.fail);
 };
 
 exports["test for...of without selections"] = function(assert, done) {
   let loader = Loader(module);
   let selection = loader.require("sdk/selection");
 
   open(URL).then(function() {
     let selectionCount = 0;
@@ -602,17 +641,17 @@ exports["test for...of without selection
 
   }).then(close).then(loader.unload).then(null, function(error) {
     // iterable are not supported yet in Firefox 16, for example, but
     // they are in Firefox 17.
     if (error.message.indexOf("is not iterable") > -1)
       assert.pass("`iterable` method not supported in this application");
     else
       assert.fail(error);
-  }).then(done);
+  }).then(done, assert.fail);
 }
 
 exports["test for...of with selections"] = function(assert, done) {
   let loader = Loader(module);
   let selection = loader.require("sdk/selection");
 
   open(URL).then(selectAllDivs).then(function(){
     let expectedText = ["foo", "and"];
@@ -635,47 +674,47 @@ exports["test for...of with selections"]
 
   }).then(close).then(loader.unload).then(null, function(error) {
     // iterable are not supported yet in Firefox 16, for example, but
     // they are in Firefox 17.
     if (error.message.indexOf("is not iterable") > -1)
       assert.pass("`iterable` method not supported in this application");
     else
       assert.fail(error);
-  }).then(done)
+  }).then(done, assert.fail)
 }
 
 exports["test Selection Listener"] = function(assert, done) {
   let loader = Loader(module);
   let selection = loader.require("sdk/selection");
 
   selection.once("select", function() {
     assert.equal(selection.text, "fo");
     done();
   });
 
   open(URL).then(selectContentFirstDiv).
     then(dispatchSelectionEvent).
     then(close).
-    then(loader.unload);
+    then(loader.unload, assert.fail);
 };
 
 exports["test Textarea OnSelect Listener"] = function(assert, done) {
   let loader = Loader(module);
   let selection = loader.require("sdk/selection");
 
   selection.once("select", function() {
     assert.equal(selection.text, "noodles");
     done();
   });
 
   open(URL).then(selectTextarea).
     then(dispatchOnSelectEvent).
     then(close).
-    then(loader.unload);
+    then(loader.unload, assert.fail);
 };
 
 exports["test Selection listener removed on unload"] = function(assert, done) {
   let loader = Loader(module);
   let selection = loader.require("sdk/selection");
 
   selection.once("select", function() {
     assert.fail("Shouldn't be never called");
@@ -684,17 +723,17 @@ exports["test Selection listener removed
   loader.unload();
 
   assert.pass();
 
   open(URL).
     then(selectContentFirstDiv).
     then(dispatchSelectionEvent).
     then(close).
-    then(done)
+    then(done, assert.fail);
 };
 
 exports["test Textarea onSelect Listener removed on unload"] = function(assert, done) {
   let loader = Loader(module);
   let selection = loader.require("sdk/selection");
 
   selection.once("select", function() {
     assert.fail("Shouldn't be never called");
@@ -703,17 +742,17 @@ exports["test Textarea onSelect Listener
   loader.unload();
 
   assert.pass();
 
   open(URL).
     then(selectTextarea).
     then(dispatchOnSelectEvent).
     then(close).
-    then(done)
+    then(done, assert.fail);
 };
 
 
 exports["test Selection Listener on existing document"] = function(assert, done) {
   let loader = Loader(module);
 
   open(URL).then(function(window){
     let selection = loader.require("sdk/selection");
@@ -722,17 +761,17 @@ exports["test Selection Listener on exis
       assert.equal(selection.text, "fo");
       done();
     });
 
     return window;
   }).then(selectContentFirstDiv).
     then(dispatchSelectionEvent).
     then(close).
-    then(loader.unload)
+    then(loader.unload, assert.fail);
 };
 
 
 exports["test Textarea OnSelect Listener on existing document"] = function(assert, done) {
   let loader = Loader(module);
 
   open(URL).then(function(window){
     let selection = loader.require("sdk/selection");
@@ -741,51 +780,51 @@ exports["test Textarea OnSelect Listener
       assert.equal(selection.text, "noodles");
       done();
     });
 
     return window;
   }).then(selectTextarea).
     then(dispatchOnSelectEvent).
     then(close).
-    then(loader.unload)
+    then(loader.unload, assert.fail);
 };
 
 exports["test Selection Listener on document reload"] = function(assert, done) {
   let loader = Loader(module);
   let selection = loader.require("sdk/selection");
 
   selection.once("select", function() {
     assert.equal(selection.text, "fo");
     done();
   });
 
   open(URL).
     then(reload).
     then(selectContentFirstDiv).
     then(dispatchSelectionEvent).
     then(close).
-    then(loader.unload);
+    then(loader.unload, assert.fail);
 };
 
 exports["test Textarea OnSelect Listener on document reload"] = function(assert, done) {
   let loader = Loader(module);
   let selection = loader.require("sdk/selection");
 
   selection.once("select", function() {
     assert.equal(selection.text, "noodles");
     done();
   });
 
   open(URL).
     then(reload).
     then(selectTextarea).
     then(dispatchOnSelectEvent).
     then(close).
-    then(loader.unload);
+    then(loader.unload, assert.fail);
 };
 
 exports["test Selection Listener on frame"] = function(assert, done) {
   let loader = Loader(module);
   let selection = loader.require("sdk/selection");
 
   selection.once("select", function() {
     assert.equal(selection.text, "fo");
@@ -793,17 +832,17 @@ exports["test Selection Listener on fram
   });
 
   open(FRAME_URL).
     then(hideAndShowFrame).
     then(getFrameWindow).
     then(selectContentFirstDiv).
     then(dispatchSelectionEvent).
     then(close).
-    then(loader.unload)
+    then(loader.unload, assert.fail);
 };
 
 exports["test Textarea onSelect Listener on frame"] = function(assert, done) {
   let loader = Loader(module);
   let selection = loader.require("sdk/selection");
 
   selection.once("select", function() {
     assert.equal(selection.text, "noodles");
@@ -811,17 +850,114 @@ exports["test Textarea onSelect Listener
   });
 
   open(FRAME_URL).
     then(hideAndShowFrame).
     then(getFrameWindow).
     then(selectTextarea).
     then(dispatchOnSelectEvent).
     then(close).
-    then(loader.unload)
+    then(loader.unload, assert.fail);
+};
+
+
+exports["test PBPW Selection Listener"] = function(assert, done) {
+  let loader = Loader(module);
+  let selection = loader.require("sdk/selection");
+
+  selection.once("select", function() {
+    assert.fail("Shouldn't be never called");
+  });
+
+  assert.pass();
+
+  open(URL, {private: true}).
+    then(selectContentFirstDiv).
+    then(dispatchSelectionEvent).
+    then(close).
+    then(loader.unload).
+    then(done, assert.fail);
+};
+
+exports["test PBPW Textarea OnSelect Listener"] = function(assert, done) {
+  let loader = Loader(module);
+  let selection = loader.require("sdk/selection");
+
+  selection.once("select", function() {
+    assert.fail("Shouldn't be never called");
+  });
+
+  assert.pass();
+
+  open(URL, {private: true}).
+    then(selectTextarea).
+    then(dispatchOnSelectEvent).
+    then(close).
+    then(loader.unload).
+    then(done, assert.fail);
+};
+
+
+exports["test PBPW Single DOM Selection"] = function(assert, done) {
+  let loader = Loader(module);
+  let selection = loader.require("sdk/selection");
+
+  open(URL, {private: true}).then(selectFirstDiv).then(function(window) {
+
+    assert.equal(selection.isContiguous, false,
+      "selection.isContiguous with single DOM Selection in PBPW works.");
+
+    assert.equal(selection.text, null,
+      "selection.text with single DOM Selection in PBPW works.");
+
+    assert.equal(selection.html, null,
+      "selection.html with single DOM Selection in PBPW works.");
+
+    let selectionCount = 0;
+    for each (let sel in selection)
+      selectionCount++;
+
+    assert.equal(selectionCount, 0,
+      "No iterable selection in PBPW");
+
+    return window;
+  }).then(close).then(loader.unload).then(done, assert.fail);
+};
+
+exports["test PBPW Textarea Selection"] = function(assert, done) {
+  let loader = Loader(module);
+  let selection = loader.require("sdk/selection");
+
+  open(URL, {private: true}).then(selectTextarea).then(function(window) {
+
+    assert.equal(selection.isContiguous, false,
+      "selection.isContiguous with Textarea Selection in PBPW works.");
+
+    assert.equal(selection.text, null,
+      "selection.text with Textarea Selection in PBPW works.");
+
+    assert.strictEqual(selection.html, null,
+      "selection.html with Textarea Selection in PBPW works.");
+
+    let selectionCount = 0;
+    for each (let sel in selection) {
+      selectionCount++;
+
+      assert.equal(sel.text, null,
+        "iterable selection.text with Textarea Selection in PBPW works.");
+
+      assert.strictEqual(sel.html, null,
+        "iterable selection.html with Textarea Selection in PBPW works.");
+    }
+
+    assert.equal(selectionCount, 0,
+      "No iterable selection in PBPW");
+
+    return window;
+  }).then(close).then(loader.unload).then(done, assert.fail);
 };
 
 // TODO: test Selection Listener on long-held connection (Bug 661884)
 //
 //  I didn't find a way to do so with httpd, using `processAsync` I'm able to
 //  Keep the connection but not to flush the buffer to the client in two steps,
 //  that is what I need for this test (e.g. flush "Hello" to the client, makes
 //  selection when the connection is still hold, and check that the listener
@@ -830,16 +966,27 @@ exports["test Textarea onSelect Listener
 //  Because this test is needed to the refactoring of context-menu as well, I
 //  believe we will find a proper solution quickly.
 /*
 exports["test Selection Listener on long-held connection"] = function(assert, done) {
 
 };
 */
 
+// If the platform doesn't support the PBPW, we're replacing PBPW tests
+if (!require("sdk/private-browsing/utils").isWindowPBSupported) {
+  Object.keys(module.exports).forEach(function(key) {
+    if (key.indexOf("test PBPW") === 0) {
+      module.exports[key] = function Unsupported (assert) {
+        assert.pass("Private Window Per Browsing is not supported on this platform.");
+      }
+    }
+  });
+}
+
 // If the module doesn't support the app we're being run in, require() will
 // throw.  In that case, remove all tests above from exports, and add one dummy
 // test that passes.
 try {
   require("sdk/selection");
 }
 catch (err) {
   if (!/^Unsupported Application/.test(err.message))
--- a/addon-sdk/source/test/test-tabs-common.js
+++ b/addon-sdk/source/test/test-tabs-common.js
@@ -1,20 +1,21 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 'use strict';
 
-const { Loader } = require('sdk/test/loader');
+const { Loader, LoaderWithHookedConsole } = require("sdk/test/loader");
 const { browserWindows } = require('sdk/windows');
 const tabs = require('sdk/tabs');
 const { isPrivate } = require('sdk/private-browsing');
 const { openDialog } = require('sdk/window/utils');
 const pbUtils = require('sdk/private-browsing/utils');
 const { isWindowPrivate } = require('sdk/window/utils');
+const { setTimeout } = require('sdk/timers');
 
 const URL = 'data:text/html;charset=utf-8,<html><head><title>#title#</title></head></html>';
 
 // TEST: tab count
 exports.testTabCounts = function(test) {
   test.waitUntilDone();
 
   tabs.open({
@@ -347,8 +348,42 @@ exports.testPrivateAreNotListed = functi
 
     win.addEventListener("unload", function onunload() {
       win.removeEventListener('unload', onunload);
       test.done();
     });
     win.close();
   });
 }
+
+// If we close the tab while being in `onOpen` listener,
+// we end up synchronously consuming TabOpen, closing the tab and still
+// synchronously consuming the related TabClose event before the second
+// loader have a change to process the first TabOpen event!
+exports.testImmediateClosing = function (test) {
+  test.waitUntilDone();
+  let { loader, messages } = LoaderWithHookedConsole(module, onMessage);
+  let concurrentTabs = loader.require("sdk/tabs");
+  concurrentTabs.on("open", function () {
+    test.fail("Concurrent loader manager receive a tabs `open` event");
+    // It shouldn't receive such event as the other loader will just open
+    // and destroy the tab without giving a change to other loader to even know
+    // about the existance of this tab.
+  });
+  function onMessage(type, msg) {
+    test.fail("Unexpected mesage on concurrent loader: " + msg);
+  }
+
+  tabs.open({
+    url: 'about:blank',
+    onOpen: function(tab) {
+      tab.close(function () {
+        test.pass("Tab succesfully removed");
+        // Let a chance to the concurrent loader to receive a TabOpen event
+        // on the next event loop turn
+        setTimeout(function () {
+          loader.unload();
+          test.done();
+        }, 0);
+      });
+    }
+  });
+}
--- a/addon-sdk/test/Makefile.in
+++ b/addon-sdk/test/Makefile.in
@@ -3,13 +3,12 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 DEPTH            = @DEPTH@
 topsrcdir        = @top_srcdir@
 srcdir           = @srcdir@
 VPATH            = @srcdir@
 relativesrcdir   = @relativesrcdir@
 
-MODULE           = test_addon_sdk
 XPCSHELL_TESTS = unit
 
 include $(DEPTH)/config/autoconf.mk
 include $(topsrcdir)/config/rules.mk
--- a/addon-sdk/test/moz.build
+++ b/addon-sdk/test/moz.build
@@ -1,5 +1,7 @@
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+MODULE = 'test_addon_sdk'
+
--- a/b2g/app/b2g.js
+++ b/b2g/app/b2g.js
@@ -648,18 +648,14 @@ pref("layers.orientation.sync.timeout", 
 // pressure.
 pref("webgl.can-lose-context-in-foreground", false);
 
 // Allow nsMemoryInfoDumper to create a fifo in the temp directory.  We use
 // this fifo to trigger about:memory dumps, among other things.
 pref("memory_info_dumper.watch_fifo.enabled", true);
 pref("memory_info_dumper.watch_fifo.directory", "/data/local");
 
-// <input type='file'> implementation is not complete. We have to disable the
-// type to web content to help them do feature detection.
-pref("dom.disable_input_file", true);
-
 pref("general.useragent.enable_overrides", true);
 
 pref("b2g.version", @MOZ_B2G_VERSION@);
 
 // Disable console buffering to save memory.
 pref("consoleservice.buffered", false);
--- a/b2g/chrome/content/shell.js
+++ b/b2g/chrome/content/shell.js
@@ -303,16 +303,17 @@ var shell = {
     this.contentBrowser.src = homeURL;
     this.isHomeLoaded = false;
 
     ppmm.addMessageListener("content-handler", this);
     ppmm.addMessageListener("dial-handler", this);
     ppmm.addMessageListener("sms-handler", this);
     ppmm.addMessageListener("mail-handler", this);
     ppmm.addMessageListener("app-notification-send", AlertsHelper);
+    ppmm.addMessageListener("file-picker", this);
   },
 
   stop: function shell_stop() {
     window.removeEventListener('keydown', this, true);
     window.removeEventListener('keypress', this, true);
     window.removeEventListener('keyup', this, true);
     window.removeEventListener('MozApplicationManifest', this);
     window.removeEventListener('mozfullscreenchange', this);
@@ -527,29 +528,44 @@ var shell = {
       manifestURL: msg.manifest,
       isActivity: (msg.type == 'activity'),
       target: msg.target,
       expectingSystemMessage: true
     });
   },
 
   receiveMessage: function shell_receiveMessage(message) {
-    var names = { 'content-handler': 'view',
-                  'dial-handler'   : 'dial',
-                  'mail-handler'   : 'new',
-                  'sms-handler'    : 'new' }
+    var activities = { 'content-handler': { name: 'view', response: null },
+                       'dial-handler':    { name: 'dial', response: null },
+                       'mail-handler':    { name: 'new',  response: null },
+                       'sms-handler':     { name: 'new',  response: null },
+                       'file-picker':     { name: 'pick', response: 'file-picked' } };
 
-    if (!(message.name in names))
+    if (!(message.name in activities))
       return;
 
     let data = message.data;
-    new MozActivity({
-      name: names[message.name],
+    let activity = activities[message.name];
+
+    let a = new MozActivity({
+      name: activity.name,
       data: data
     });
+
+    if (activity.response) {
+      a.onsuccess = function() {
+        let sender = message.target.QueryInterface(Ci.nsIMessageSender);
+        sender.sendAsyncMessage(activity.response, { success: true,
+                                                     result:  a.result });
+      }
+      a.onerror = function() {
+        let sender = message.target.QueryInterface(Ci.nsIMessageSender);
+        sender.sendAsyncMessage(activity.response, { success: false });
+      }
+    }
   }
 };
 
 function nsBrowserAccess() {
 }
 
 nsBrowserAccess.prototype = {
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIBrowserDOMWindow]),
--- a/b2g/components/B2GComponents.manifest
+++ b/b2g/components/B2GComponents.manifest
@@ -60,8 +60,12 @@ contract @mozilla.org/network/protocol;1
 
 # RecoveryService.js
 component {b3caca5d-0bb0-48c6-912b-6be6cbf08832} RecoveryService.js
 contract @mozilla.org/recovery-service;1 {b3caca5d-0bb0-48c6-912b-6be6cbf08832}
 
 # B2GAboutRedirector
 component {920400b1-cf8f-4760-a9c4-441417b15134} B2GAboutRedirector.js
 contract @mozilla.org/network/protocol/about;1?what=certerror {920400b1-cf8f-4760-a9c4-441417b15134}
+
+# FilePicker.js
+component {436ff8f9-0acc-4b11-8ec7-e293efba3141} FilePicker.js
+contract @mozilla.org/filepicker;1 {436ff8f9-0acc-4b11-8ec7-e293efba3141}
new file mode 100644
--- /dev/null
+++ b/b2g/components/FilePicker.js
@@ -0,0 +1,184 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/*
+ * No magic constructor behaviour, as is de rigeur for XPCOM.
+ * If you must perform some initialization, and it could possibly fail (even
+ * due to an out-of-memory condition), you should use an Init method, which
+ * can convey failure appropriately (thrown exception in JS,
+ * NS_FAILED(nsresult) return in C++).
+ *
+ * In JS, you can actually cheat, because a thrown exception will cause the
+ * CreateInstance call to fail in turn, but not all languages are so lucky.
+ * (Though ANSI C++ provides exceptions, they are verboten in Mozilla code
+ * for portability reasons -- and even when you're building completely
+ * platform-specific code, you can't throw across an XPCOM method boundary.)
+ */
+
+const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
+
+// FIXME: improve this list of filters.
+const IMAGE_FILTERS = ['image/gif', 'image/jpeg', 'image/pjpeg',
+                       'image/png', 'image/svg+xml', 'image/tiff',
+                       'image/vnd.microsoft.icon'];
+const VIDEO_FILTERS = ['video/mpeg', 'video/mp4', 'video/ogg',
+                       'video/quicktime', 'video/webm', 'video/x-matroska',
+                       'video/x-ms-wmv', 'video/x-flv'];
+const AUDIO_FILTERS = ['audio/basic', 'audio/L24', 'audio/mp4',
+                       'audio/mpeg', 'audio/ogg', 'audio/vorbis',
+                       'audio/vnd.rn-realaudio', 'audio/vnd.wave',
+                       'audio/webm'];
+
+Cu.import('resource://gre/modules/XPCOMUtils.jsm');
+
+XPCOMUtils.defineLazyServiceGetter(this, 'cpmm',
+                                   '@mozilla.org/childprocessmessagemanager;1',
+                                   'nsIMessageSender');
+
+function FilePicker() {
+}
+
+FilePicker.prototype = {
+  classID: Components.ID('{436ff8f9-0acc-4b11-8ec7-e293efba3141}'),
+  QueryInterface: XPCOMUtils.generateQI([Ci.nsIFilePicker]),
+
+  /* members */
+
+  mParent: undefined,
+  mFilterTypes: [],
+  mFileEnumerator: undefined,
+  mFilePickerShownCallback: undefined,
+
+  /* methods */
+
+  init: function(parent, title, mode) {
+    this.mParent = parent;
+
+    if (mode != Ci.nsIFilePicker.modeOpen &&
+        mode != Ci.nsIFilePicker.modeOpenMultiple) {
+      throw Cr.NS_ERROR_NOT_IMPLEMENTED;
+    }
+  },
+
+  /* readonly attribute nsILocalFile file - not implemented; */
+  /* readonly attribute nsISimpleEnumerator files - not implemented; */
+  /* readonly attribute nsIURI fileURL - not implemented; */
+
+  get domfiles() {
+    return this.mFilesEnumerator;
+  },
+
+  get domfile() {
+    return this.mFilesEnumerator ? this.mFilesEnumerator.mFiles[0] : null;
+  },
+
+  appendFilters: function(filterMask) {
+    this.mFilterTypes = null;
+
+    // Ci.nsIFilePicker.filterHTML is not supported
+    // Ci.nsIFilePicker.filterText is not supported
+
+    if (filterMask & Ci.nsIFilePicker.filterImages) {
+      this.mFilterTypes = IMAGE_FILTERS;
+    }
+
+    // Ci.nsIFilePicker.filterXML is not supported
+    // Ci.nsIFilePicker.filterXUL is not supported
+    // Ci.nsIFilePicker.filterApps is not supported
+    // Ci.nsIFilePicker.filterAllowURLs is not supported
+
+    if (filterMask & Ci.nsIFilePicker.filterVideo) {
+      this.mFilterTypes = VIDEO_FILTERS;
+    }
+
+    if (filterMask & Ci.nsIFilePicker.filterAudio) {
+      this.mFilterTypes = AUDIO_FILTERS;
+    }
+
+    // Ci.nsIFilePicker.filterAll is by default
+  },
+
+  appendFilter: function(title, extensions) {
+    // pick activity doesn't support extensions
+  },
+
+  open: function(aFilePickerShownCallback) {
+    this.mFilePickerShownCallback = aFilePickerShownCallback;
+
+    cpmm.addMessageListener('file-picked', this);
+
+    let detail = {};
+    if (this.mFilterTypes) {
+       detail.type = this.mFilterTypes;
+    }
+
+    cpmm.sendAsyncMessage('file-picker', detail);
+  },
+
+  fireSuccess: function(file) {
+    this.mFilesEnumerator = {
+      QueryInterface: XPCOMUtils.generateQI([Ci.nsISimpleEnumerator]),
+
+      mFiles: [file],
+      mIndex: 0,
+
+      hasMoreElements: function() {
+        return (this.mIndex < this.mFiles.length);
+      },
+
+      getNext: function() {
+        if (this.mIndex >= this.mFiles.length) {
+          throw Components.results.NS_ERROR_FAILURE;
+        }
+        return this.mFiles[this.mIndex++];
+      }
+    };
+
+    if (this.mFilePickerShownCallback) {
+      this.mFilePickerShownCallback.done(Ci.nsIFilePicker.returnOK);
+      this.mFilePickerShownCallback = null;
+    }
+  },
+
+  fireError: function() {
+    if (this.mFilePickerShownCallback) {
+      this.mFilePickerShownCallback.done(Ci.nsIFilePicker.returnCancel);
+      this.mFilePickerShownCallback = null;
+    }
+  },
+
+  receiveMessage: function(message) {
+    if (message.name !== 'file-picked') {
+      return;
+    }
+
+    cpmm.removeMessageListener('file-picked', this);
+
+    let data = message.data;
+    if (!data.success || !data.result.blob) {
+      this.fireError();
+      return;
+    }
+
+    var mimeSvc = Cc["@mozilla.org/mime;1"].getService(Ci.nsIMIMEService);
+    var mimeInfo = mimeSvc.getFromTypeAndExtension(data.result.blob.type, '');
+
+    var name = 'blob';
+    if (mimeInfo) {
+      name += '.' + mimeInfo.primaryExtension;
+    }
+
+    let file = new this.mParent.File(data.result.blob,
+                                     { name: name,
+                                       type: data.result.blob.type });
+    if (file) {
+      this.fireSuccess(file);
+    } else {
+      this.fireError();
+    }
+  }
+};
+
+this.NSGetFactory = XPCOMUtils.generateNSGetFactory([FilePicker]);
--- a/b2g/components/Makefile.in
+++ b/b2g/components/Makefile.in
@@ -4,26 +4,25 @@
 
 DEPTH      = @DEPTH@
 topsrcdir  = @top_srcdir@
 srcdir     = @srcdir@
 VPATH      = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
-MODULE = B2GComponents
-
 EXTRA_PP_COMPONENTS = \
         ActivitiesGlue.js \
         AlertsService.js \
         B2GAboutRedirector.js \
         B2GComponents.manifest \
         ContentHandler.js \
         ContentPermissionPrompt.js \
         DirectoryProvider.js \
+        FilePicker.js \
         MailtoProtocolHandler.js \
         MozKeyboard.js \
         ProcessGlobal.js \
         PaymentGlue.js \
         SmsProtocolHandler.js \
         TelProtocolHandler.js \
         YoutubeProtocolHandler.js \
         RecoveryService.js \
--- a/b2g/components/moz.build
+++ b/b2g/components/moz.build
@@ -4,8 +4,10 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 TEST_DIRS += ['test']
 
 XPIDL_SOURCES += [
     'b2g.idl',
 ]
 
+MODULE = 'B2GComponents'
+
--- a/b2g/components/test/Makefile.in
+++ b/b2g/components/test/Makefile.in
@@ -8,13 +8,11 @@ DEPTH		= @DEPTH@
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 relativesrcdir = @relativesrcdir@
 FAIL_ON_WARNINGS := 1
 
 include $(DEPTH)/config/autoconf.mk
 
-MODULE = B2GComponents
-
 XPCSHELL_TESTS = unit
 
 include $(topsrcdir)/config/rules.mk
--- a/b2g/components/test/moz.build
+++ b/b2g/components/test/moz.build
@@ -1,5 +1,7 @@
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+MODULE = 'B2GComponents'
+
--- a/b2g/confvars.sh
+++ b/b2g/confvars.sh
@@ -36,16 +36,18 @@ fi
 MOZ_USE_NATIVE_POPUP_WINDOWS=1
 
 if test "$LIBXUL_SDK"; then
 MOZ_XULRUNNER=1
 else
 MOZ_XULRUNNER=
 fi
 
+MOZ_MEDIA_NAVIGATOR=1
+
 MOZ_APP_ID={3c2e2abc-06d4-11e1-ac3b-374f68613e61}
 MOZ_EXTENSION_MANAGER=1
 
 MOZ_SYS_MSG=1
 MOZ_TIME_MANAGER=1
 
 MOZ_B2G_CERTDATA=1
 MOZ_PAY=1
--- a/b2g/installer/package-manifest.in
+++ b/b2g/installer/package-manifest.in
@@ -261,21 +261,25 @@
 @BINPATH@/components/necko_dns.xpt
 @BINPATH@/components/necko_file.xpt
 @BINPATH@/components/necko_ftp.xpt
 @BINPATH@/components/necko_http.xpt
 @BINPATH@/components/necko_res.xpt
 @BINPATH@/components/necko_socket.xpt
 @BINPATH@/components/necko_strconv.xpt
 @BINPATH@/components/necko_viewsource.xpt
+@BINPATH@/components/necko_websocket.xpt
 @BINPATH@/components/necko_wifi.xpt
 @BINPATH@/components/necko_wyciwyg.xpt
 @BINPATH@/components/necko.xpt
 @BINPATH@/components/loginmgr.xpt
 @BINPATH@/components/parentalcontrols.xpt
+#ifdef MOZ_WEBRTC
+@BINPATH@/components/peerconnection.xpt
+#endif
 @BINPATH@/components/places.xpt
 @BINPATH@/components/plugin.xpt
 @BINPATH@/components/pref.xpt
 @BINPATH@/components/prefetch.xpt
 @BINPATH@/components/profile.xpt
 #ifdef MOZ_ENABLE_PROFILER_SPS
 @BINPATH@/components/profiler.xpt
 #endif
@@ -367,27 +371,27 @@
 @BINPATH@/components/BrowserPlaces.manifest
 @BINPATH@/components/toolkitsearch.manifest
 @BINPATH@/components/nsTryToClose.manifest
 @BINPATH@/components/nsTryToClose.js
 @BINPATH@/components/passwordmgr.manifest
 @BINPATH@/components/nsLoginInfo.js
 @BINPATH@/components/nsLoginManager.js
 @BINPATH@/components/nsLoginManagerPrompter.js
+#ifdef MOZ_WEBRTC
+@BINPATH@/components/PeerConnection.js
+@BINPATH@/components/PeerConnection.manifest
+#endif
 @BINPATH@/components/SiteSpecificUserAgent.js
 @BINPATH@/components/SiteSpecificUserAgent.manifest
 @BINPATH@/components/storage-Legacy.js
 @BINPATH@/components/storage-mozStorage.js
 @BINPATH@/components/crypto-SDR.js
 @BINPATH@/components/jsconsole-clhandler.manifest
 @BINPATH@/components/jsconsole-clhandler.js
-#ifdef MOZ_GTK2
-@BINPATH@/components/nsFilePicker.manifest
-@BINPATH@/components/nsFilePicker.js
-#endif
 @BINPATH@/components/nsHelperAppDlg.manifest
 @BINPATH@/components/nsHelperAppDlg.js
 @BINPATH@/components/nsDownloadManagerUI.manifest
 @BINPATH@/components/nsDownloadManagerUI.js
 @BINPATH@/components/nsSidebar.manifest
 @BINPATH@/components/nsSidebar.js
 #ifndef MOZ_WIDGET_GONK
 @BINPATH@/components/extensions.manifest
@@ -734,16 +738,17 @@ bin/components/@DLL_PREFIX@nkgnomevfs@DL
 @BINPATH@/components/ContentHandler.js
 @BINPATH@/components/PaymentGlue.js
 @BINPATH@/components/YoutubeProtocolHandler.js
 @BINPATH@/components/RecoveryService.js
 @BINPATH@/components/MailtoProtocolHandler.js
 @BINPATH@/components/SmsProtocolHandler.js
 @BINPATH@/components/TelProtocolHandler.js
 @BINPATH@/components/B2GAboutRedirector.js
+@BINPATH@/components/FilePicker.js
 
 #ifdef XP_MACOSX
 @BINPATH@/@DLL_PREFIX@plugin_child_interpose@DLL_SUFFIX@
 #endif
 
 #ifdef PACKAGE_GAIA
 [gaia]
 @BINPATH@/gaia/*
--- a/browser/base/content/browser-social.js
+++ b/browser/base/content/browser-social.js
@@ -69,16 +69,17 @@ let SocialUI = {
     try {
       switch (topic) {
         case "social:provider-set":
           // Social.provider has changed (possibly to null), update any state
           // which depends on it.
           this._updateActiveUI();
           this._updateMenuItems();
 
+          SocialFlyout.unload();
           SocialChatBar.update();
           SocialSidebar.update();
           SocialShareButton.update();
           SocialToolbar.update();
           SocialMenu.populate();
           break;
         case "social:providers-changed":
           // the list of providers changed - this may impact the "active" UI.
@@ -452,16 +453,17 @@ let SocialFlyout = {
     let panel = this.panel;
     if (!SocialUI.enabled || panel.firstChild)
       return;
     // create and initialize the panel for this window
     let iframe = document.createElement("iframe");
     iframe.setAttribute("type", "content");
     iframe.setAttribute("class", "social-panel-frame");
     iframe.setAttribute("flex", "1");
+    iframe.setAttribute("tooltip", "aHTMLTooltip");
     iframe.setAttribute("origin", Social.provider.origin);
     panel.appendChild(iframe);
   },
 
   setFlyoutErrorMessage: function SF_setFlyoutErrorMessage() {
     let iframe = this.panel.firstChild;
     if (!iframe)
       return;
@@ -892,16 +894,17 @@ var SocialToolbar = {
         notificationFrame = SharedFrame.createFrame(
           notificationFrameId, /* frame name */
           panel, /* parent */
           {
             "type": "content",
             "mozbrowser": "true",
             "class": "social-panel-frame",
             "id": notificationFrameId,
+            "tooltip": "aHTMLTooltip",
 
             // work around bug 793057 - by making the panel roughly the final size
             // we are more likely to have the anchor in the correct position.
             "style": "width: " + PANEL_MIN_WIDTH + "px;",
 
             "origin": Social.provider.origin,
             "src": icon.contentPanel
           }
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -1096,16 +1096,17 @@
     <vbox id="social-sidebar-box"
           class="chromeclass-extrachrome"
           observes="socialSidebarBroadcaster"
           persist="width">
       <browser id="social-sidebar-browser"
                type="content"
                context="contentAreaContextMenu"
                disableglobalhistory="true"
+               tooltip="aHTMLTooltip"
                flex="1"
                style="min-width: 14em; width: 18em; max-width: 36em;"/>
     </vbox>
     <vbox id="browser-border-end" hidden="true" layer="true"/>
   </hbox>
 
   <hbox id="full-screen-warning-container" hidden="true" fadeout="true">
     <hbox style="width: 100%;" pack="center"> <!-- Inner hbox needed due to bug 579776. -->
--- a/browser/base/content/socialchat.xml
+++ b/browser/base/content/socialchat.xml
@@ -11,16 +11,17 @@
                 onclick="document.getBindingParent(this).onTitlebarClick(event);" align="baseline">
         <xul:image class="chat-status-icon" xbl:inherits="src=image"/>
         <xul:label class="chat-title" flex="1" xbl:inherits="value=label" crop="center"/>
         <xul:toolbarbutton class="chat-close-button chat-toolbarbutton"
                            oncommand="document.getBindingParent(this).close();"/>
       </xul:hbox>
       <xul:iframe anonid="iframe" class="chat-frame" flex="1"
                   context="contentAreaContextMenu"
+                  tooltip="aHTMLTooltip"
                   xbl:inherits="src,origin,collapsed=minimized" type="content"/>
     </content>
 
     <implementation implements="nsIDOMEventListener">
       <constructor><![CDATA[
         let Social = Components.utils.import("resource:///modules/Social.jsm", {}).Social;
         Social.setErrorListener(this.iframe, function(iframe) {
           iframe.webNavigation.loadURI("about:socialerror?mode=compactInfo", null, null, null, null);
@@ -156,16 +157,17 @@
     </content>
 
     <implementation implements="nsIDOMEventListener">
       <constructor>
         // to avoid reflows we cache the values for various widths.
         this.cachedWidthOpen = 0;
         this.cachedWidthMinimized = 0;
         this.cachedWidthNub = 0;
+        this._selectedChat = null;
       </constructor>
 
       <field name="innerbox" readonly="true">
         document.getAnonymousElementByAttribute(this, "anonid", "innerbox");
       </field>
 
       <field name="menupopup" readonly="true">
         document.getAnonymousElementByAttribute(this, "anonid", "nubMenu");
--- a/browser/base/content/test/social/browser_social_errorPage.js
+++ b/browser/base/content/test/social/browser_social_errorPage.js
@@ -15,17 +15,17 @@ let origProxyType = Services.prefs.getIn
 
 function goOffline() {
   // Simulate a network outage with offline mode. (Localhost is still
   // accessible in offline mode, so disable the test proxy as well.)
   if (!Services.io.offline)
     BrowserOffline.toggleOfflineStatus();
   Services.prefs.setIntPref('network.proxy.type', 0);
   // LOAD_FLAGS_BYPASS_CACHE isn't good enough. So clear the cache.
-  Services.cache.evictEntries(Services.cache.STORE_ANYWHERE);
+  Services.cache.evictEntries(Components.interfaces.nsICache.STORE_ANYWHERE);
 }
 
 function goOnline(callback) {
   Services.prefs.setIntPref('network.proxy.type', origProxyType);
   if (Services.io.offline)
     BrowserOffline.toggleOfflineStatus();
   if (callback)
     callback();
--- a/browser/base/content/test/social/head.js
+++ b/browser/base/content/test/social/head.js
@@ -85,16 +85,22 @@ function runSocialTestWithProvider(manif
               return;
             info("Failed to clean up provider " + origin + ": " + ex);
           }
         }
       }
       removeProvider(m.origin, callback);
     });
   }
+  function finishSocialTest(cleanup) {
+    // disable social before removing the providers to avoid providers
+    // being activated immediately before we get around to removing it.
+    Services.prefs.clearUserPref("social.enabled");
+    removeAddedProviders(cleanup);
+  }
 
   let providersAdded = 0;
   let firstProvider;
 
   manifests.forEach(function (m) {
     SocialService.addProvider(m, function(provider) {
 
       providersAdded++;
@@ -106,22 +112,16 @@ function runSocialTestWithProvider(manif
       }
 
       // If we've added all the providers we need, call the callback to start
       // the tests (and give it a callback it can call to finish them)
       if (providersAdded == manifests.length) {
         // Set the UI's provider (which enables the feature)
         Social.provider = firstProvider;
 
-        function finishSocialTest(cleanup) {
-          // disable social before removing the providers to avoid providers
-          // being activated immediately before we get around to removing it.
-          Services.prefs.clearUserPref("social.enabled");
-          removeAddedProviders(cleanup);
-        }
         registerCleanupFunction(function () {
           finishSocialTest(true);
         });
         callback(finishSocialTest);
       }
     });
   });
 }
@@ -164,17 +164,17 @@ function runSocialTests(tests, cbPreTest
     });
   }
   runNextTest();
 }
 
 // A fairly large hammer which checks all aspects of the SocialUI for
 // internal consistency.
 function checkSocialUI(win) {
-  let win = win || window;
+  win = win || window;
   let doc = win.document;
   let provider = Social.provider;
   let enabled = win.SocialUI.enabled;
   let active = Social.providers.length > 0 && !win.SocialUI._chromeless &&
                !PrivateBrowsingUtils.isWindowPrivate(win);
 
   function isbool(a, b, msg) {
     is(!!a, !!b, msg);
--- a/browser/components/Makefile.in
+++ b/browser/components/Makefile.in
@@ -4,17 +4,16 @@
 
 DEPTH     = @DEPTH@
 topsrcdir = @top_srcdir@
 srcdir    = @srcdir@
 VPATH     = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
-MODULE = browsercomps
 EXTRA_COMPONENTS = \
   BrowserComponents.manifest \
   $(NULL)
 
 EXTRA_PP_COMPONENTS = \
   nsBrowserContentHandler.js \
   nsBrowserGlue.js \
   $(NULL)
--- a/browser/components/about/Makefile.in
+++ b/browser/components/about/Makefile.in
@@ -4,17 +4,16 @@
 
 DEPTH     = @DEPTH@
 topsrcdir = @top_srcdir@
 srcdir    = @srcdir@
 VPATH     = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
-MODULE = browserabout
 LIBRARY_NAME = browserabout_s
 
 FORCE_STATIC_LIB = 1
 USE_STATIC_LIBS = 1
 
 EXPORTS_NAMESPACES = mozilla/browser
 
 EXPORTS_mozilla/browser = AboutRedirector.h
--- a/browser/components/about/moz.build
+++ b/browser/components/about/moz.build
@@ -1,5 +1,7 @@
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+MODULE = 'browserabout'
+
--- a/browser/components/build/Makefile.in
+++ b/browser/components/build/Makefile.in
@@ -4,17 +4,16 @@
 
 DEPTH=@DEPTH@
 topsrcdir=@top_srcdir@
 srcdir=@srcdir@
 VPATH=@srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
-MODULE = browsercomps
 LIBRARY_NAME = browsercomps
 SHORT_LIBNAME = brwsrcmp
 IS_COMPONENT = 1
 MODULE_NAME = nsBrowserCompsModule
 FORCE_SHARED_LIB = 1
 
 USE_STATIC_LIBS = 1
 
--- a/browser/components/build/moz.build
+++ b/browser/components/build/moz.build
@@ -1,5 +1,7 @@
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+MODULE = 'browsercomps'
+
--- a/browser/components/dirprovider/Makefile.in
+++ b/browser/components/dirprovider/Makefile.in
@@ -4,17 +4,16 @@
 
 DEPTH     = @DEPTH@
 topsrcdir = @top_srcdir@
 srcdir    = @srcdir@
 VPATH     = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
-MODULE = browserdir
 LIBRARY_NAME = browserdir_s
 
 FORCE_STATIC_LIB = 1
 USE_STATIC_LIBS = 1
 
 EXPORTS_NAMESPACES = mozilla/browser
 EXPORTS_mozilla/browser = DirectoryProvider.h
 
--- a/browser/components/dirprovider/moz.build
+++ b/browser/components/dirprovider/moz.build
@@ -1,6 +1,9 @@
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 TEST_DIRS += ['tests']
+
+MODULE = 'browserdir'
+
--- a/browser/components/dirprovider/tests/Makefile.in
+++ b/browser/components/dirprovider/tests/Makefile.in
@@ -5,13 +5,11 @@
 DEPTH          = @DEPTH@
 topsrcdir      = @top_srcdir@
 srcdir         = @srcdir@
 VPATH          = @srcdir@
 relativesrcdir = @relativesrcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
-MODULE = test_browserdir
-
 XPCSHELL_TESTS = unit
 
 include $(topsrcdir)/config/rules.mk
--- a/browser/components/dirprovider/tests/moz.build
+++ b/browser/components/dirprovider/tests/moz.build
@@ -1,5 +1,7 @@
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+MODULE = 'test_browserdir'
+
deleted file mode 100644
--- a/browser/components/feeds/public/Makefile.in
+++ /dev/null
@@ -1,15 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-DEPTH   = @DEPTH@
-topsrcdir = @top_srcdir@
-srcdir    = @srcdir@
-VPATH   = @srcdir@
-
-include $(DEPTH)/config/autoconf.mk
-
-MODULE = browser-feeds
-
-include $(topsrcdir)/config/rules.mk
--- a/browser/components/feeds/public/moz.build
+++ b/browser/components/feeds/public/moz.build
@@ -4,8 +4,10 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 XPIDL_SOURCES += [
     'nsIFeedResultService.idl',
     'nsIFeedWriter.idl',
     'nsIWebContentConverterRegistrar.idl',
 ]
 
+MODULE = 'browser-feeds'
+
--- a/browser/components/feeds/src/Makefile.in
+++ b/browser/components/feeds/src/Makefile.in
@@ -4,17 +4,16 @@
 
 DEPTH		= @DEPTH@
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
-MODULE = browser_feeds
 LIBRARY_NAME = browser_feeds_s
 
 FORCE_STATIC_LIB = 1
 USE_STATIC_LIBS = 1
 
 DEFINES += \
 	-DMOZ_APP_NAME=$(MOZ_APP_NAME) \
 	-DMOZ_MACBUNDLE_NAME=$(MOZ_MACBUNDLE_NAME) \
--- a/browser/components/feeds/src/moz.build
+++ b/browser/components/feeds/src/moz.build
@@ -1,5 +1,7 @@
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+MODULE = 'browser_feeds'
+
--- a/browser/components/feeds/test/Makefile.in
+++ b/browser/components/feeds/test/Makefile.in
@@ -5,17 +5,16 @@
 DEPTH		= @DEPTH@
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 relativesrcdir  = @relativesrcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
-MODULE		= test_browser_feeds
 XPCSHELL_TESTS	= unit
 
 MOCHITEST_FILES =	bug408328-data.xml \
 		bug368464-data.xml \
 		test_bug494328.html \
 		bug494328-data.xml \
 		test_bug589543.html \
 		bug589543-data.xml \
--- a/browser/components/feeds/test/moz.build
+++ b/browser/components/feeds/test/moz.build
@@ -1,6 +1,9 @@
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 DIRS += ['chrome']
+
+MODULE = 'test_browser_feeds'
+
deleted file mode 100644
--- a/browser/components/migration/public/Makefile.in
+++ /dev/null
@@ -1,15 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-DEPTH		= @DEPTH@
-topsrcdir	= @top_srcdir@
-srcdir		= @srcdir@
-VPATH		= @srcdir@
-
-include $(DEPTH)/config/autoconf.mk
-
-MODULE		= migration
-
-include $(topsrcdir)/config/rules.mk
-
--- a/browser/components/migration/public/moz.build
+++ b/browser/components/migration/public/moz.build
@@ -2,8 +2,10 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 XPIDL_SOURCES += [
     'nsIBrowserProfileMigrator.idl',
 ]
 
+MODULE = 'migration'
+
--- a/browser/components/migration/src/Makefile.in
+++ b/browser/components/migration/src/Makefile.in
@@ -4,17 +4,16 @@
 
 DEPTH		= @DEPTH@
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
-MODULE		= migration
 LIBRARY_NAME	= migration_s
 
 FORCE_STATIC_LIB = 1
 USE_STATIC_LIBS = 1
 
 EXTRA_COMPONENTS = \
   ProfileMigrator.js \
   FirefoxProfileMigrator.js \
--- a/browser/components/migration/src/moz.build
+++ b/browser/components/migration/src/moz.build
@@ -1,5 +1,7 @@
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+MODULE = 'migration'
+
--- a/browser/components/moz.build
+++ b/browser/components/moz.build
@@ -28,8 +28,10 @@ DIRS += ['build']
 
 XPIDL_SOURCES += [
     'nsIBrowserGlue.idl',
     'nsIBrowserHandler.idl',
 ]
 
 XPIDL_MODULE = 'browsercompsbase'
 
+MODULE = 'browsercomps'
+
--- a/browser/components/places/tests/Makefile.in
+++ b/browser/components/places/tests/Makefile.in
@@ -6,13 +6,11 @@
 DEPTH		= @DEPTH@
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 relativesrcdir = @relativesrcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
-MODULE		= test_browser_places
-
 XPCSHELL_TESTS = unit
 
 include $(topsrcdir)/config/rules.mk
--- a/browser/components/places/tests/moz.build
+++ b/browser/components/places/tests/moz.build
@@ -1,6 +1,9 @@
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 DIRS += ['browser', 'chrome']
+
+MODULE = 'test_browser_places'
+
--- a/browser/components/preferences/jar.mn
+++ b/browser/components/preferences/jar.mn
@@ -30,16 +30,17 @@ browser.jar:
 *   content/browser/preferences/main.xul
     content/browser/preferences/main.js
 *   content/browser/preferences/permissions.xul
     content/browser/preferences/permissions.js
 *   content/browser/preferences/preferences.xul
     content/browser/preferences/privacy.xul
     content/browser/preferences/privacy.js
     content/browser/preferences/sanitize.xul
+    content/browser/preferences/sanitize.js
     content/browser/preferences/security.xul
     content/browser/preferences/security.js
     content/browser/preferences/selectBookmark.xul
     content/browser/preferences/selectBookmark.js
 #ifdef MOZ_SERVICES_SYNC
     content/browser/preferences/sync.xul
     content/browser/preferences/sync.js
 #endif
new file mode 100644
--- /dev/null
+++ b/browser/components/preferences/sanitize.js
@@ -0,0 +1,27 @@
+/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+XPCOMUtils.defineLazyModuleGetter(this, "DownloadsCommon",
+                                  "resource:///modules/DownloadsCommon.jsm");
+
+let gSanitizeDialog = Object.freeze({
+  /**
+   * Sets up the UI.
+   */
+  init: function ()
+  {
+    let downloadsPref = document.getElementById("privacy.clearOnShutdown.downloads");
+    downloadsPref.disabled = !DownloadsCommon.useToolkitUI;
+    this.onClearHistoryChanged();
+  },
+
+  onClearHistoryChanged: function () {
+    if (DownloadsCommon.useToolkitUI)
+      return;
+    let downloadsPref = document.getElementById("privacy.clearOnShutdown.downloads");
+    let historyPref = document.getElementById("privacy.clearOnShutdown.history");
+    downloadsPref.value = historyPref.value;
+  }
+});
--- a/browser/components/preferences/sanitize.xul
+++ b/browser/components/preferences/sanitize.xul
@@ -15,25 +15,28 @@
   %sanitizeDTD;
 ]>
 
 <prefwindow id="SanitizeDialog" type="child"
             xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
             dlgbuttons="accept,cancel,help"
             ondialoghelp="openPrefsHelp()"
             style="width: &dialog.width;;"
-            title="&sanitizePrefs2.title;">
+            title="&sanitizePrefs2.title;"
+            onload="gSanitizeDialog.init();">
 
   <script type="application/javascript" src="chrome://browser/content/utilityOverlay.js"/>
+  <script type="application/javascript" src="chrome://browser/content/preferences/sanitize.js"/>
 
   <prefpane id="SanitizeDialogPane"
             helpTopic="prefs-clear-private-data">
 
     <preferences>
-      <preference id="privacy.clearOnShutdown.history"               name="privacy.clearOnShutdown.history"               type="bool"/>
+      <preference id="privacy.clearOnShutdown.history"               name="privacy.clearOnShutdown.history"               type="bool"
+                  onchange="return gSanitizeDialog.onClearHistoryChanged();"/>
       <preference id="privacy.clearOnShutdown.formdata"              name="privacy.clearOnShutdown.formdata"              type="bool"/>
       <preference id="privacy.clearOnShutdown.passwords"             name="privacy.clearOnShutdown.passwords"             type="bool"/>
       <preference id="privacy.clearOnShutdown.downloads"             name="privacy.clearOnShutdown.downloads"             type="bool"/>
       <preference id="privacy.clearOnShutdown.cookies"               name="privacy.clearOnShutdown.cookies"               type="bool"/>
       <preference id="privacy.clearOnShutdown.cache"                 name="privacy.clearOnShutdown.cache"                 type="bool"/>
       <preference id="privacy.clearOnShutdown.offlineApps"           name="privacy.clearOnShutdown.offlineApps"           type="bool"/>
       <preference id="privacy.clearOnShutdown.sessions"              name="privacy.clearOnShutdown.sessions"              type="bool"/>
       <preference id="privacy.clearOnShutdown.siteSettings"          name="privacy.clearOnShutdown.siteSettings"          type="bool"/>
deleted file mode 100644
--- a/browser/components/privatebrowsing/Makefile.in
+++ /dev/null
@@ -1,14 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-DEPTH		= @DEPTH@
-topsrcdir	= @top_srcdir@
-srcdir		= @srcdir@
-VPATH		= @srcdir@
-
-include $(DEPTH)/config/autoconf.mk
-
-MODULE = privatebrowsing
-
-include $(topsrcdir)/config/rules.mk
--- a/browser/components/privatebrowsing/moz.build
+++ b/browser/components/privatebrowsing/moz.build
@@ -1,6 +1,9 @@
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 TEST_DIRS += ['test']
+
+MODULE = 'privatebrowsing'
+
deleted file mode 100644
--- a/browser/components/privatebrowsing/test/Makefile.in
+++ /dev/null
@@ -1,15 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-DEPTH		= @DEPTH@
-topsrcdir	= @top_srcdir@
-srcdir		= @srcdir@
-VPATH		= @srcdir@
-relativesrcdir  = @relativesrcdir@
-
-include $(DEPTH)/config/autoconf.mk
-
-MODULE		= test_privatebrowsing
-
-include $(topsrcdir)/config/rules.mk
--- a/browser/components/privatebrowsing/test/browser/Makefile.in
+++ b/browser/components/privatebrowsing/test/browser/Makefile.in
@@ -5,18 +5,16 @@
 DEPTH		= @DEPTH@
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 relativesrcdir  = @relativesrcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
-MODULE		= test_privatebrowsing
-
 MOCHITEST_BROWSER_FILES =  \
 		head.js \
 		browser_privatebrowsing_certexceptionsui.js \
 		browser_privatebrowsing_concurrent.js \
 		browser_privatebrowsing_concurrent_page.html \
 		browser_privatebrowsing_cookieacceptdialog.js \
 		browser_privatebrowsing_cookieacceptdialog.html \
 		browser_privatebrowsing_crh.js \
--- a/browser/components/privatebrowsing/test/browser/moz.build
+++ b/browser/components/privatebrowsing/test/browser/moz.build
@@ -1,5 +1,8 @@
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+
+MODULE = 'test_privatebrowsing'
+
--- a/browser/components/privatebrowsing/test/moz.build
+++ b/browser/components/privatebrowsing/test/moz.build
@@ -1,7 +1,9 @@
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 DIRS += ['browser']
 
+MODULE = 'test_privatebrowsing'
+
deleted file mode 100644
--- a/browser/components/sessionstore/Makefile.in
+++ /dev/null
@@ -1,15 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-DEPTH		= @DEPTH@
-topsrcdir	= @top_srcdir@
-srcdir		= @srcdir@
-VPATH		= @srcdir@
-
-include $(DEPTH)/config/autoconf.mk
-
-MODULE = sessionstore
-
-include $(topsrcdir)/config/rules.mk
--- a/browser/components/sessionstore/moz.build
+++ b/browser/components/sessionstore/moz.build
@@ -6,8 +6,10 @@
 DIRS += ['src']
 TEST_DIRS += ['test']
 
 XPIDL_SOURCES += [
     'nsISessionStartup.idl',
     'nsISessionStore.idl',
 ]
 
+MODULE = 'sessionstore'
+
--- a/browser/components/sessionstore/src/_SessionFile.jsm
+++ b/browser/components/sessionstore/src/_SessionFile.jsm
@@ -37,16 +37,18 @@ Cu.import("resource://gre/modules/common
 XPCOMUtils.defineLazyModuleGetter(this, "TelemetryStopwatch",
   "resource://gre/modules/TelemetryStopwatch.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
   "resource://gre/modules/NetUtil.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "FileUtils",
   "resource://gre/modules/FileUtils.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "Task",
   "resource://gre/modules/Task.jsm");
+XPCOMUtils.defineLazyServiceGetter(this, "Telemetry",
+  "@mozilla.org/base/telemetry;1", "nsITelemetry");
 
 // An encoder to UTF-8.
 XPCOMUtils.defineLazyGetter(this, "gEncoder", function () {
   return new TextEncoder();
 });
 
 this._SessionFile = {
   /**
@@ -212,20 +214,25 @@ let SessionFileInternal = {
         TelemetryStopwatch.cancel("FX_SESSION_RESTORE_WRITE_FILE_MS", refObj);
         Cu.reportError("Could not write session state file " + self.path
                        + ": " + aReason);
       }
     });
   },
 
   createBackupCopy: function ssfi_createBackupCopy() {
+    let backupCopyOptions = {
+      outExecutionDuration: null
+    };
     let self = this;
     return TaskUtils.spawn(function task() {
       try {
-        yield OS.File.copy(self.path, self.backupPath);
+        yield OS.File.copy(self.path, self.backupPath, backupCopyOptions);
+        Telemetry.getHistogramById("FX_SESSION_RESTORE_BACKUP_FILE_MS").add(
+          backupCopyOptions.outExecutionDuration);
       } catch (ex if self._isNoSuchFile(ex)) {
         // Ignore exceptions about non-existent files.
       } catch (ex) {
         Cu.reportError("Could not backup session state file: " + ex);
         throw ex;
       }
     });
   },
deleted file mode 100644
--- a/browser/components/shell/public/Makefile.in
+++ /dev/null
@@ -1,15 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-DEPTH   = @DEPTH@
-topsrcdir = @top_srcdir@
-srcdir    = @srcdir@
-VPATH   = @srcdir@
-
-include $(DEPTH)/config/autoconf.mk
-
-MODULE = shellservice
-
-include $(topsrcdir)/config/rules.mk
--- a/browser/components/shell/public/moz.build
+++ b/browser/components/shell/public/moz.build
@@ -11,8 +11,10 @@ if CONFIG['OS_ARCH'] == 'WINNT':
     XPIDL_SOURCES += [
         'nsIWindowsShellService.idl',
     ]
 elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
     XPIDL_SOURCES += [
         'nsIMacShellService.idl',
     ]
 
+MODULE = 'shellservice'
+
--- a/browser/components/shell/src/Makefile.in
+++ b/browser/components/shell/src/Makefile.in
@@ -5,18 +5,16 @@
 
 DEPTH   = @DEPTH@
 topsrcdir = @top_srcdir@
 srcdir    = @srcdir@
 VPATH   = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
-MODULE = shellservice
-
 FORCE_STATIC_LIB = 1
 USE_STATIC_LIBS = 1
 
 ifeq ($(OS_ARCH),WINNT)
 CPPSRCS = nsWindowsShellService.cpp
 else
 ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
 CPPSRCS = nsMacShellService.cpp
--- a/browser/components/shell/src/moz.build
+++ b/browser/components/shell/src/moz.build
@@ -1,5 +1,7 @@
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+MODULE = 'shellservice'
+
--- a/browser/components/shell/test/Makefile.in
+++ b/browser/components/shell/test/Makefile.in
@@ -5,17 +5,16 @@
 DEPTH		= @DEPTH@
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 relativesrcdir  = @relativesrcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
-MODULE		= test_browser_shell
 XPCSHELL_TESTS	= unit
 
 
 MOCHITEST_BROWSER_FILES = browser_420786.js \
     browser_633221.js \
 	$(NULL)
 
 include $(topsrcdir)/config/rules.mk
--- a/browser/components/shell/test/moz.build
+++ b/browser/components/shell/test/moz.build
@@ -1,5 +1,7 @@
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+MODULE = 'test_browser_shell'
+
deleted file mode 100644
--- a/browser/fuel/public/Makefile.in
+++ /dev/null
@@ -1,14 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-DEPTH     = @DEPTH@
-topsrcdir = @top_srcdir@
-srcdir    = @srcdir@
-VPATH     = @srcdir@
-
-include $(DEPTH)/config/autoconf.mk
-
-MODULE        = fuel
-
-include $(topsrcdir)/config/rules.mk
--- a/browser/fuel/public/moz.build
+++ b/browser/fuel/public/moz.build
@@ -2,8 +2,10 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 XPIDL_SOURCES += [
     'fuelIApplication.idl',
 ]
 
+MODULE = 'fuel'
+
--- a/browser/fuel/src/Makefile.in
+++ b/browser/fuel/src/Makefile.in
@@ -4,14 +4,12 @@
 
 DEPTH     = @DEPTH@
 topsrcdir = @top_srcdir@
 srcdir    = @srcdir@
 VPATH     = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
-MODULE = fuel
-
 EXTRA_COMPONENTS = fuelApplication.manifest
 EXTRA_PP_COMPONENTS = fuelApplication.js
 
 include $(topsrcdir)/config/rules.mk
--- a/browser/fuel/src/moz.build
+++ b/browser/fuel/src/moz.build
@@ -1,5 +1,7 @@
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+MODULE = 'fuel'
+
--- a/browser/metro/base/content/BrowserTouchHandler.js
+++ b/browser/metro/base/content/BrowserTouchHandler.js
@@ -17,28 +17,31 @@ const BrowserTouchHandler = {
     // Messages sent from content.js
     messageManager.addMessageListener("Content:ContextMenu", this);
   },
 
   // Content forwarding the contextmenu command
   onContentContextMenu: function onContentContextMenu(aMessage) {
     // Note, target here is the target of the message manager message,
     // usually the browser.
-    let contextInfo = { name: aMessage.name,
-                        json: aMessage.json,
-                        target: aMessage.target };
     // Touch input selection handling
-    if (!InputSourceHelper.isPrecise && !SelectionHelperUI.isActive &&
-        SelectionHelperUI.canHandle(aMessage)) {
-      SelectionHelperUI.openEditSession(aMessage);
+    if (!InputSourceHelper.isPrecise &&
+        !SelectionHelperUI.isActive &&
+        SelectionHelperUI.canHandleContextMenuMsg(aMessage)) {
+      SelectionHelperUI.openEditSession(aMessage.target,
+                                        aMessage.json.xPos,
+                                        aMessage.json.yPos);
       return;
     }
 
     // Check to see if we have context menu item(s) that apply to what
     // was clicked on.
+    let contextInfo = { name: aMessage.name,
+                        json: aMessage.json,
+                        target: aMessage.target };
     if (ContextMenuUI.showContextMenu(contextInfo)) {
       let event = document.createEvent("Events");
       event.initEvent("CancelTouchSequence", true, false);
       document.dispatchEvent(event);
     } else {
       // Send the MozEdgeUIGesture to input.js to
       // toggle the context ui.
       let event = document.createEvent("Events");
--- a/browser/metro/base/content/ContextCommands.js
+++ b/browser/metro/base/content/ContextCommands.js
@@ -95,34 +95,30 @@ var ContextCommands = {
   pasteAndGo: function cc_pasteAndGo() {
     let target = ContextMenuUI.popupState.target;
     target.editor.selectAll();
     target.editor.paste(Ci.nsIClipboard.kGlobalClipboard);
     BrowserUI.goToURI();
   },
 
   select: function cc_select() {
-    let contextInfo = { name: "",
-                        json: ContextMenuUI.popupState,
-                        target: ContextMenuUI.popupState.target };
-    SelectionHelperUI.openEditSession(contextInfo);
+    SelectionHelperUI.openEditSession(ContextMenuUI.popupState.target,
+                                      ContextMenuUI.popupState.xPos,
+                                      ContextMenuUI.popupState.yPos);
   },
 
   selectAll: function cc_selectAll() {
     let target = ContextMenuUI.popupState.target;
     if (target.localName == "browser") {
       // content
-      let x = ContextMenuUI.popupState.x;
-      let y = ContextMenuUI.popupState.y;
+      let x = ContextMenuUI.popupState.xPos;
+      let y = ContextMenuUI.popupState.yPos;
       let json = {x: x, y: y, command: "select-all" };
       target.messageManager.sendAsyncMessage("Browser:ContextCommand", json);
-      let contextInfo = { name: "",
-                          json: ContextMenuUI.popupState,
-                          target: ContextMenuUI.popupState.target };
-      SelectionHelperUI.attachEditSession(contextInfo);
+      SelectionHelperUI.attachEditSession(target, x, y);
     } else {
       // chrome
       target.editor.selectAll();
       target.focus();
     }
   },
 
   // called on display of the search text menu item
--- a/browser/metro/base/content/helperui/SelectionHelperUI.js
+++ b/browser/metro/base/content/helperui/SelectionHelperUI.js
@@ -186,17 +186,17 @@ Marker.prototype = {
 };
 
 /*
  * SelectionHelperUI
  */
 
 var SelectionHelperUI = {
   _debugEvents: false,
-  _popupState: null,
+  _msgTarget: null,
   _startMark: null,
   _endMark: null,
   _target: null,
   _movement: { active: false, x:0, y: 0 },
   _activeSelectionRect: null,
   _selectionHandlerActive: false,
 
   get startMark() {
@@ -218,101 +218,81 @@ var SelectionHelperUI = {
   },
 
   /*
    * openEditSession
    * 
    * Attempts to select underlying text at a point and begins editing
    * the section.
    */
-  openEditSession: function openEditSession(aMessage) {
-     /*
-     * aMessage - from _onContentContextMenu in ContextMenuHandler
-     *  name: aMessage.name,
-     *  target: aMessage.target
-     *  json:
-     *   types: [],
-     *   label: "",
-     *   linkURL: "",
-     *   linkTitle: "",
-     *   linkProtocol: null,
-     *   mediaURL: "",
-     *   xPos: aEvent.x,
-     *   yPos: aEvent.y
-     */
-
-    this._popupState = aMessage.json;
-    this._popupState._target = aMessage.target;
-
-    this._init();
+  openEditSession: function openEditSession(aContent, aClientX, aClientY) {
+    if (!aContent || this.isActive)
+      return;
+    this._init(aContent);
 
     // Set the track bounds for each marker NIY
-    this.startMark.setTrackBounds(this._popupState.xPos, this._popupState.yPos);
-    this.endMark.setTrackBounds(this._popupState.xPos, this._popupState.yPos);
+    this.startMark.setTrackBounds(aClientX, aClientY);
+    this.endMark.setTrackBounds(aClientX, aClientY);
 
     // Send this over to SelectionHandler in content, they'll message us
     // back with information on the current selection. SelectionStart
     // takes client coordinates.
     this._selectionHandlerActive = false;
     this._sendAsyncMessage("Browser:SelectionStart", {
-      xPos: this._popupState.xPos,
-      yPos: this._popupState.yPos
+      xPos: aClientX,
+      yPos: aClientY
     });
 
     this._setupDebugOptions();
   },
 
   /*
    * attachEditSession
    * 
    * Attaches to existing selection and begins editing.
    */
-  attachEditSession: function attachEditSession(aMessage) {
-    if (aMessage.target == undefined)
+  attachEditSession: function attachEditSession(aContent, aClientX, aClientY) {
+    if (!aContent || this.isActive)
       return;
-    this._popupState = aMessage.json;
-    this._popupState._target = aMessage.target;
-
-    this._init();
+    this._init(aContent);
 
     // Set the track bounds for each marker NIY
-    this.startMark.setTrackBounds(this._popupState.xPos, this._popupState.yPos);
-    this.endMark.setTrackBounds(this._popupState.xPos, this._popupState.yPos);
+    this.startMark.setTrackBounds(aClientX, aClientY);
+    this.endMark.setTrackBounds(aClientX, aClientY);
 
     // Send this over to SelectionHandler in content, they'll message us
     // back with information on the current selection. SelectionAttach
     // takes client coordinates.
     this._selectionHandlerActive = false;
-    this._popupState._target.messageManager.sendAsyncMessage(
-      "Browser:SelectionAttach",
-      { xPos: this._popupState.xPos,
-        yPos: this._popupState.yPos });
+    this._sendAsyncMessage("Browser:SelectionAttach", {
+      xPos: aClientX,
+      yPos: aClientY
+    });
 
     this._setupDebugOptions();
   },
 
   /*
-   * canHandle
+   * canHandleContextMenuMsg
    *
    * Determines if we can handle a ContextMenuHandler message.
    */
-  canHandle: function canHandle(aMessage) {
+  canHandleContextMenuMsg: function canHandleContextMenuMsg(aMessage) {
     if (aMessage.json.types.indexOf("content-text") != -1)
       return true;
     return false;
   },
 
   /*
    * isActive (prop)
    *
    * Determines if an edit session is currently active.
    */
   get isActive() {
-    return (this._popupState != null &&
-            this._popupState._target != null &&
+    return (this._msgTarget &&
             this._selectionHandlerActive);
   },
 
   /*
    * closeEditSession
    *
    * Closes an active edit session and shuts down. Does not clear existing
    * selection regions if they exist.
@@ -332,17 +312,20 @@ var SelectionHelperUI = {
     this._sendAsyncMessage("Browser:SelectionClear");
     this.closeEditSession();
   },
 
   /*
    * Internal
    */
 
-  _init: function _init() {
+  _init: function _init(aMsgTarget) {
+    // store the target message manager
+    this._msgTarget = aMsgTarget;
+
     // SelectionHandler messages
     messageManager.addMessageListener("Content:SelectionRange", this);
     messageManager.addMessageListener("Content:SelectionCopied", this);
     messageManager.addMessageListener("Content:SelectionFail", this);
     messageManager.addMessageListener("Content:SelectionDebugRect", this);
 
     // selection related events
     window.addEventListener("click", this, false);
@@ -394,17 +377,17 @@ var SelectionHelperUI = {
     if (this.startMark != null)
       this.startMark.shutdown();
     if (this.endMark != null)
       this.endMark.shutdown();
 
     delete this._startMark;
     delete this._endMark;
 
-    this._popupState = null;
+    this._msgTarget = null;
     this._activeSelectionRect = null;
     this._selectionHandlerActive = false;
 
     this.overlay.displayDebugLayer = false;
     this.overlay.enabled = false;
   },
 
   /*
@@ -439,22 +422,22 @@ var SelectionHelperUI = {
     }
   },
 
   /*
    * _sendAsyncMessage - helper for sending a message to
    * SelectionHandler.
    */
   _sendAsyncMessage: function _sendAsyncMessage(aMsg, aJson) {
-    if (!this._popupState || !this._popupState._target) {
+    if (!this._msgTarget) {
       if (this._debugEvents)
         Util.dumpLn("SelectionHelperUI sendAsyncMessage could not send", aMsg);
       return;
     }
-    this._popupState._target.messageManager.sendAsyncMessage(aMsg, aJson);
+    this._msgTarget.messageManager.sendAsyncMessage(aMsg, aJson);
   },
 
   _checkForActiveDrag: function _checkForActiveDrag() {
     return (this.startMark.dragging || this.endMark.dragging);
   },
 
   _hitTestSelection: function _hitTestSelection(aEvent) {
     // Ignore if the double tap isn't on our active selection rect.
@@ -641,30 +624,16 @@ var SelectionHelperUI = {
     }
   },
 
   /*
    * Callbacks from markers
    */
 
   _getMarkerBaseMessage: function _getMarkerBaseMessage() {
-  /*
-    This appears to be adjusted for scroll and scale. It should only
-    adjust for scale, content handles scroll offsets.
-    let startPos =
-      this._popupState._target.transformBrowserToClient(this.startMark.xPos,
-                                                        this.startMark.yPos);
-    let endPos =
-      this._popupState._target.transformBrowserToClient(this.endMark.xPos,
-                                                        this.endMark.yPos);
-    return {
-      start: { xPos: startPos.x, yPos: startPos.y },
-      end: { xPos: endPos.x, yPos: endPos.y },
-    };
-    */
     return {
       start: { xPos: this.startMark.xPos, yPos: this.startMark.yPos },
       end: { xPos: this.endMark.xPos, yPos: this.endMark.yPos },
     };
   },
 
   markerDragStart: function markerDragStart(aMarker) {
     let json = this._getMarkerBaseMessage();
--- a/browser/metro/base/content/input.js
+++ b/browser/metro/base/content/input.js
@@ -142,20 +142,18 @@ var TouchModule = {
             this._onTouchEnd(aEvent);
             break;
           case "dblclick":
             // XXX This will get picked up somewhere below us for "double tap to zoom"
             // once we get omtc and the apzc. Currently though dblclick is delivered to
             // content and triggers selection of text, so fire up the SelectionHelperUI
             // once selection is present.
             setTimeout(function () {
-              let contextInfo = { name: "",
-                                  json: { xPos: aEvent.clientX, yPos: aEvent.clientY },
-                                  target: Browser.selectedTab.browser };
-              SelectionHelperUI.attachEditSession(contextInfo);
+              SelectionHelperUI.attachEditSession(Browser.selectedTab.browser,
+                                                  aEvent.clientX, aEvent.clientY);
             }, 50);
             break;
         }
       }
     }
   },
 
   sample: function sample(aTimeStamp) {
--- a/browser/metro/components/Makefile.in
+++ b/browser/metro/components/Makefile.in
@@ -6,18 +6,16 @@ DEPTH      = @DEPTH@
 topsrcdir  = @top_srcdir@
 srcdir     = @srcdir@
 VPATH      = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 include $(topsrcdir)/config/config.mk
 
 # metro/components.manifest
-MODULE = components
-
 EXTRA_PP_COMPONENTS = \
         components.manifest \
         AboutRedirector.js \
         BrowserCLH.js \
         BrowserStartup.js \
         DirectoryProvider.js\
         HelperAppDialog.js \
         Sidebar.js \
--- a/browser/metro/components/moz.build
+++ b/browser/metro/components/moz.build
@@ -3,8 +3,10 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 XPIDL_SOURCES += [
     'LoginManagerPrompter.idl',
     'SessionStore.idl',
 ]
 
+MODULE = 'components'
+
--- a/browser/metro/shell/Makefile.in
+++ b/browser/metro/shell/Makefile.in
@@ -2,18 +2,16 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 DEPTH     = ../../..
 topsrcdir = @top_srcdir@
 srcdir    = @srcdir@
 VPATH     = @srcdir@
 
-MODULE    = metro
-
 include $(DEPTH)/config/autoconf.mk
 
 export::
 	$(NSINSTALL) $(srcdir)/resources.pri $(DIST)/bin
 
 install::
 	$(NSINSTALL) $(srcdir)/resources.pri $(DIST)/bin
 
--- a/browser/metro/shell/moz.build
+++ b/browser/metro/shell/moz.build
@@ -5,8 +5,10 @@
 
 DIRS += [
     'commandexecutehandler',
     'linktool',
 ]
 
 TEST_DIRS += ['testing']
 
+MODULE = 'metro'
+
--- a/build/Makefile.in
+++ b/build/Makefile.in
@@ -7,18 +7,16 @@ DEPTH		= @DEPTH@
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 USE_RCS_MK := 1
 include $(topsrcdir)/config/makefiles/makeutils.mk
 
-MODULE = build
-
 ifdef MOZ_APP_BASENAME
 DIST_FILES = $(srcdir)/application.ini
 
 ifneq (android,$(MOZ_WIDGET_TOOLKIT))
 ifdef MOZ_UPDATER
 DIST_FILES += update-settings.ini
 endif
 endif
--- a/build/mobile/robocop/Makefile.in
+++ b/build/mobile/robocop/Makefile.in
@@ -1,112 +1,117 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 DEPTH       = @DEPTH@
 topsrcdir   = @top_srcdir@
 srcdir      = @srcdir@
 VPATH       = @srcdir@
-TESTPATH    = $(topsrcdir)/mobile/android/base/tests
+
+mobile-tests := mobile/android/base/tests
+TESTPATH     := $(topsrcdir)/$(mobile-tests)
+dir-tests    := $(DEPTH)/$(mobile-tests)
 
 include $(DEPTH)/config/autoconf.mk
 
-MODULE = robocop
-
 ROBOTIUM_PATH = $(srcdir)/robotium-solo-3.6.jar
 
 JAVAFILES = \
   R.java \
+  $(NULL)
+
+RES_FILES = \
+  res/values/strings.xml \
+  $(NULL)
 
 _JAVA_HARNESS = \
   Actions.java \
   Assert.java \
   Driver.java \
   Element.java \
   FennecInstrumentationTestRunner.java \
   FennecNativeActions.java \
   FennecMochitestAssert.java \
   FennecTalosAssert.java \
   FennecNativeDriver.java \
   FennecNativeElement.java \
   RoboCopException.java \
   PaintedSurface.java \
   $(NULL)
 
-_JAVA_TESTS = $(patsubst $(TESTPATH)/%.in,%,$(wildcard $(TESTPATH)/*.java.in))
+# pre-process harness sources
+PP_TARGETS        += java-harness
+java-harness      := $(addprefix $(srcdir)/,$(addsuffix .in,$(_JAVA_HARNESS)))
+java-harness-dep  := $(addprefix $(CURDIR)/,$(_JAVA_HARNESS))
+java-harness_PATH := $(CURDIR)
+
+# pre-process test sources
+PP_TARGETS      += java-tests
+java-tests-src  := $(wildcard $(TESTPATH)/*.java.in)
+java-tests-dep  := $(patsubst $(TESTPATH)/%.java.in,$(dir-tests)/%.java,$(java-tests-src))
+java-tests      := $(java-tests-src)
+java-tests_PATH := $(dir-tests)
 
-_TEST_FILES = \
+PP_TARGETS        += manifest
+manifest          := $(srcdir)/AndroidManifest.xml.in
+manifest_TARGET   := AndroidManifest.xml
+
+
+# Install robocop configs and helper
+INSTALL_TARGETS += robocop
+robocop_TARGET  := libs
+robocop_DEST    := $(CURDIR)
+robocop_FILES   := \
+  $(TESTPATH)/robocop.ini \
+  $(TESTPATH)/robocop_autophone.ini \
+  $(srcdir)/parse_ids.py \
+  $(NULL)
+robocop-deps := $(notdir $(robocop_FILES))
+
+MOCHITEST_ROBOCOP_FILES := \
   $(wildcard $(TESTPATH)/*.html) \
   $(wildcard $(TESTPATH)/*.jpg) \
   $(wildcard $(TESTPATH)/*.sjs) \
   $(NULL)
 
-_ROBOCOP_TOOLS = \
-  $(TESTPATH)/robocop.ini \
-  $(TESTPATH)/robocop_autophone.ini \
-  parse_ids.py \
-  $(NULL)
-
 GARBAGE += \
   AndroidManifest.xml \
-  _JAVA_TESTS \
-  _JAVA_HARNESS \
+  $(java-tests-dep) \
+  $(_JAVA_HARNESS) \
   classes.dex \
   robocop.apk \
   robocop.ap_ \
   robocop-unsigned-unaligned.apk \
   robocop-unaligned.apk \
+  $(robocop-deps) \
   $(NULL)
 
 DEFINES += \
   -DANDROID_PACKAGE_NAME=$(ANDROID_PACKAGE_NAME) \
   $(NULL)
 
-GARBAGE_DIRS += res
-
 JAVA_CLASSPATH = $(ANDROID_SDK)/android.jar:$(ROBOTIUM_PATH)
 
 include $(topsrcdir)/config/rules.mk
 
 # Override rules.mk java flags with the android specific ones
 include $(topsrcdir)/config/android-common.mk
 
-$(_JAVA_HARNESS): % : %.in
-	$(PYTHON) $(topsrcdir)/config/Preprocessor.py $(DEFINES) $< > $@
-
-AndroidManifest.xml: % : %.in
-	$(PYTHON) $(topsrcdir)/config/Preprocessor.py $(DEFINES) $< > $@
-
-$(_JAVA_TESTS): % : $(TESTPATH)/%.in
-	$(NSINSTALL) -D $(DEPTH)/mobile/android/base/tests
-	$(PYTHON) $(topsrcdir)/config/Preprocessor.py $(DEFINES) $< > $(DEPTH)/mobile/android/base/tests/$@
+GENERATED_DIRS_tools = classes $(dir-tests)
 
-$(_ROBOCOP_TOOLS):
-	cp $(TESTPATH)/robocop.ini robocop.ini
-	cp $(TESTPATH)/robocop_autophone.ini robocop_autophone.ini
-
-libs:: $(_TEST_FILES)
-	$(NSINSTALL) -D $(DEPTH)/_tests/testing/mochitest/tests/robocop
-	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/robocop/
-
-tools:: robocop.apk
+tools:: $(robocop-deps) robocop.apk
 
 classes.dex: robocop.ap_
-classes.dex: $(_ROBOCOP_TOOLS)
-classes.dex: $(_JAVA_HARNESS)
-classes.dex: $(_JAVA_TESTS)
-	$(NSINSTALL) -D classes
-	$(JAVAC) $(JAVAC_FLAGS) -d classes $(JAVAFILES) $(_JAVA_HARNESS) $(addprefix $(DEPTH)/mobile/android/base/tests/,$(_JAVA_TESTS))
+classes.dex: $(robocop-deps)
+classes.dex: $(java-harness-dep)
+classes.dex: $(java-tests-dep)
+	$(JAVAC) $(JAVAC_FLAGS) -d classes $(JAVAFILES) $(_JAVA_HARNESS) $(java-tests-dep)
 	$(DX) --dex --output=$@ classes $(ROBOTIUM_PATH) $(ANDROID_COMPT_LIB)
 
+robocop.apk: $(robocop-deps) robocop.ap_ classes.dex
 robocop.ap_: AndroidManifest.xml $(TESTPATH)/assets/*
-	$(AAPT) package -f -M AndroidManifest.xml -I $(ANDROID_SDK)/android.jar -I . -S res -A $(TESTPATH)/assets -F $@ -J ./
+	$(AAPT) package -f -M $< -I $(ANDROID_SDK)/android.jar -I . -S res -A $(TESTPATH)/assets -F $@ -J ./
 
-robocop.apk: robocop.ap_ classes.dex
-	cp $(TESTPATH)/robocop.ini robocop.ini
-	cp $(TESTPATH)/robocop_autophone.ini robocop_autophone.ini
-	cp $(srcdir)/parse_ids.py parse_ids.py
-
-export::
-	$(NSINSTALL) -D res
-	@(cd $(srcdir)/res && tar $(TAR_CREATE_FLAGS) - *) | (cd $(DEPTH)/build/mobile/robocop/res && tar -xf -)
-
+# PP_java-tests not fully usable here
+# Intermediate step toward a library rule.
+$(dir-tests)/%.java: $(TESTPATH)/%.java.in $(call mkdir_deps,$(dir-tests))
+	$(PYTHON) $(topsrcdir)/config/Preprocessor.py $(DEFINES) $< > $@
--- a/build/mobile/robocop/moz.build
+++ b/build/mobile/robocop/moz.build
@@ -1,5 +1,7 @@
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+MODULE = 'robocop'
+
--- a/build/mobile/sutagent/android/Makefile.in
+++ b/build/mobile/sutagent/android/Makefile.in
@@ -4,18 +4,16 @@
 
 DEPTH		= @DEPTH@
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
-MODULE = sutAgentAndroid
-
 JAVAFILES = \
   AlertLooperThread.java \
   ASMozStub.java \
   CmdWorkerThread.java \
   DataWorkerThread.java \
   DoAlert.java \
   DoCommand.java \
   FindProcThread.java \
--- a/build/mobile/sutagent/android/fencp/Makefile.in
+++ b/build/mobile/sutagent/android/fencp/Makefile.in
@@ -4,18 +4,16 @@
 
 DEPTH		= @DEPTH@
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
-MODULE = FenCP
-
 JAVAFILES = \
   DirCursor.java \
   FenCP.java \
   FenCPFP.java \
   FileCursor.java \
   R.java \
   $(NULL)
 
--- a/build/mobile/sutagent/android/fencp/moz.build
+++ b/build/mobile/sutagent/android/fencp/moz.build
@@ -1,5 +1,7 @@
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+MODULE = 'FenCP'
+
--- a/build/mobile/sutagent/android/ffxcp/Makefile.in
+++ b/build/mobile/sutagent/android/ffxcp/Makefile.in
@@ -4,18 +4,16 @@
 
 DEPTH		= @DEPTH@
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
-MODULE = FfxCP
-
 JAVAFILES = \
   DirCursor.java \
   ffxcp.java \
   FfxCPFP.java \
   FileCursor.java \
   R.java \
   $(NULL)
 
--- a/build/mobile/sutagent/android/ffxcp/moz.build
+++ b/build/mobile/sutagent/android/ffxcp/moz.build
@@ -1,5 +1,7 @@
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+MODULE = 'FfxCP'
+
--- a/build/mobile/sutagent/android/moz.build
+++ b/build/mobile/sutagent/android/moz.build
@@ -1,5 +1,7 @@
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+MODULE = 'sutAgentAndroid'
+
--- a/build/mobile/sutagent/android/watcher/Makefile.in
+++ b/build/mobile/sutagent/android/watcher/Makefile.in
@@ -4,18 +4,16 @@
 
 DEPTH		= @DEPTH@
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
-MODULE = Watcher
-
 JAVAFILES = \
   IWatcherService.java \
   RedirOutputThread.java \
   R.java \
   WatcherMain.java \
   WatcherReceiver.java \
   WatcherService.java \
   $(NULL)
--- a/build/mobile/sutagent/android/watcher/moz.build
+++ b/build/mobile/sutagent/android/watcher/moz.build
@@ -1,5 +1,7 @@
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+MODULE = 'Watcher'
+
--- a/build/moz.build
+++ b/build/moz.build
@@ -17,8 +17,10 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'andr
     TEST_DIRS += [
         'mobile/sutagent/android',
         'mobile/sutagent/android/watcher',
         'mobile/sutagent/android/ffxcp',
         'mobile/sutagent/android/fencp',
         'mobile/robocop',
     ]
 
+MODULE = 'build'
+
--- a/build/unix/Makefile.in
+++ b/build/unix/Makefile.in
@@ -6,18 +6,16 @@
 
 DEPTH		= @DEPTH@
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
-MODULE       = build
-
 SDK_BINARY = run-mozilla.sh
 
 include $(topsrcdir)/config/rules.mk
 
 libs:: $(srcdir)/run-mozilla.sh
 	$(INSTALL) $< $(DIST)/bin
 
 # EOF
--- a/build/unix/moz.build
+++ b/build/unix/moz.build
@@ -6,8 +6,10 @@
 if CONFIG['STDCXX_COMPAT']:
     DIRS += ['stdc++compat']
 
 if CONFIG['USE_ELF_HACK']:
     DIRS += ['elfhack']
 
 TEST_DIRS += ['test']
 
+MODULE = 'build'
+
--- a/build/unix/stdc++compat/Makefile.in
+++ b/build/unix/stdc++compat/Makefile.in
@@ -4,17 +4,16 @@
 
 DEPTH		= @DEPTH@
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
-MODULE		= build
 LIBRARY_NAME	= stdc++compat
 HOST_LIBRARY_NAME = host_stdc++compat
 FORCE_STATIC_LIB= 1
 STL_FLAGS =
 NO_EXPAND_LIBS = 1
 NO_PROFILE_GUIDED_OPTIMIZE = 1
 
 CPPSRCS = \
--- a/build/unix/stdc++compat/moz.build
+++ b/build/unix/stdc++compat/moz.build
@@ -1,5 +1,7 @@
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+MODULE = 'build'
+
deleted file mode 100644
--- a/caps/Makefile.in
+++ /dev/null
@@ -1,16 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-DEPTH		= @DEPTH@
-topsrcdir	= @top_srcdir@
-srcdir		= @srcdir@
-VPATH		= @srcdir@
-
-include $(DEPTH)/config/autoconf.mk
-
-MODULE		= caps
-
-include $(topsrcdir)/config/rules.mk
-
--- a/caps/idl/Makefile.in
+++ b/caps/idl/Makefile.in
@@ -5,13 +5,12 @@
 
 DEPTH		= @DEPTH@
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
-MODULE		= caps
 GRE_MODULE	= 1
 
 include $(topsrcdir)/config/rules.mk
 
--- a/caps/idl/moz.build
+++ b/caps/idl/moz.build
@@ -4,8 +4,10 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 XPIDL_SOURCES += [
     'nsIPrincipal.idl',
     'nsIScriptSecurityManager.idl',
     'nsISecurityCheckedComponent.idl',
 ]
 
+MODULE = 'caps'
+
--- a/caps/include/Makefile.in
+++ b/caps/include/Makefile.in
@@ -5,16 +5,14 @@
 
 DEPTH		= @DEPTH@
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
-MODULE		= caps
-
 EXPORTS		= \
             nsJSPrincipals.h \
             $(NULL)
 
 include $(topsrcdir)/config/rules.mk
 
--- a/caps/include/moz.build
+++ b/caps/include/moz.build
@@ -1,5 +1,7 @@
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+MODULE = 'caps'
+
--- a/caps/include/nsPrincipal.h
+++ b/caps/include/nsPrincipal.h
@@ -4,17 +4,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsPrincipal_h__
 #define nsPrincipal_h__
 
 #include "nsAutoPtr.h"
 #include "nsCOMPtr.h"
 #include "nsVoidArray.h"
-#include "nsHashtable.h"
 #include "nsJSPrincipals.h"
 #include "nsTArray.h"
 #include "nsAutoPtr.h"
 #include "nsIProtocolHandler.h"
 #include "nsNetUtil.h"
 #include "nsScriptSecurityManager.h"
 
 class nsIObjectInputStream;
--- a/caps/moz.build
+++ b/caps/moz.build
@@ -1,7 +1,10 @@
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 DIRS += ['idl', 'include', 'src']
 TEST_DIRS += ['tests/mochitest']
+
+MODULE = 'caps'
+
--- a/caps/src/Makefile.in
+++ b/caps/src/Makefile.in
@@ -5,17 +5,16 @@
 
 DEPTH		= @DEPTH@
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
-MODULE		= caps
 LIBRARY_NAME	= caps_s
 FORCE_STATIC_LIB = 1
 LIBXUL_LIBRARY = 1
 
 
 CPPSRCS		= \
 		nsPrincipal.cpp \
 		nsSystemPrincipal.cpp \
--- a/caps/src/moz.build
+++ b/caps/src/moz.build
@@ -1,5 +1,7 @@
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+MODULE = 'caps'
+
--- a/caps/src/nsPrincipal.cpp
+++ b/caps/src/nsPrincipal.cpp
@@ -12,17 +12,16 @@
 #include "plstr.h"
 #include "nsCRT.h"
 #include "nsIURI.h"
 #include "nsIFileURL.h"
 #include "nsIProtocolHandler.h"
 #include "nsNetUtil.h"
 #include "nsJSPrincipals.h"
 #include "nsVoidArray.h"
-#include "nsHashtable.h"
 #include "nsIObjectInputStream.h"
 #include "nsIObjectOutputStream.h"
 #include "nsIClassInfoImpl.h"
 #include "nsError.h"
 #include "nsIContentSecurityPolicy.h"
 #include "nsContentUtils.h"
 #include "jswrapper.h"
 
deleted file mode 100644
--- a/chrome/public/Makefile.in
+++ /dev/null
@@ -1,14 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-DEPTH		= @DEPTH@
-topsrcdir	= @top_srcdir@
-srcdir		= @srcdir@
-VPATH		= @srcdir@
-
-include $(DEPTH)/config/autoconf.mk
-
-MODULE = chrome
-
-include $(topsrcdir)/config/rules.mk
--- a/chrome/public/moz.build
+++ b/chrome/public/moz.build
@@ -3,8 +3,10 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 XPIDL_SOURCES += [
     'nsIChromeRegistry.idl',
     'nsIToolkitChromeRegistry.idl',
 ]
 
+MODULE = 'chrome'
+
--- a/chrome/src/Makefile.in
+++ b/chrome/src/Makefile.in
@@ -5,17 +5,16 @@
 
 DEPTH		= @DEPTH@
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
-MODULE          = chrome
 LIBRARY_NAME    = chrome_s
 LIBXUL_LIBRARY  = 1
 FORCE_STATIC_LIB = 1
 
 EXPORTS_NAMESPACES = mozilla/chrome
 
 EXPORTS_mozilla/chrome = \
 		RegistryMessageUtils.h \
--- a/chrome/src/moz.build
+++ b/chrome/src/moz.build
@@ -1,5 +1,7 @@
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+MODULE = 'chrome'
+
--- a/chrome/test/Makefile.in
+++ b/chrome/test/Makefile.in
@@ -5,18 +5,16 @@
 DEPTH = @DEPTH@
 topsrcdir = @top_srcdir@
 srcdir = @srcdir@
 relativesrcdir = @relativesrcdir@
 VPATH = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
-MODULE = test_chrome
-
 XPCSHELL_TESTS = unit \
                  $(NULL)
 # FIXME/bug 575918: out-of-process xpcshell is broken on OS X
 ifneq ($(OS_ARCH),Darwin)
 XPCSHELL_TESTS += unit_ipc
 endif
 
 include $(topsrcdir)/config/rules.mk
--- a/chrome/test/moz.build
+++ b/chrome/test/moz.build
@@ -1,5 +1,7 @@
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+MODULE = 'test_chrome'
+
--- a/config/makefiles/java-build.mk
+++ b/config/makefiles/java-build.mk
@@ -25,13 +25,16 @@ res-dep-preqs := \
 $(res-dep): $(res-dep-preqs)
 	$(call copy_dir,$(srcdir)/res,$(CURDIR)/res)
 	@$(TOUCH) $@
 endif #}
 
 
 ifdef JAVAFILES #{
 GENERATED_DIRS += classes
+
+export:: classes
+classes: $(call mkdir_deps,classes)
 endif #}
 
 INCLUDED_JAVA_BUILD_MK := 1
 
 endif #} INCLUDED_JAVA_BUILD_MK
--- a/config/makefiles/mochitest.mk
+++ b/config/makefiles/mochitest.mk
@@ -2,25 +2,32 @@
 # vim:set ts=8 sw=8 sts=8 noet:
 #
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this file,
 # You can obtain one at http://mozilla.org/MPL/2.0/.
 
 ifndef INCLUDED_TESTS_MOCHITEST_MK #{
 
-ifdef relativesrcdir
-  mochitestdir = $(DEPTH)/_tests/testing/mochitest/$1/$(relativesrcdir)
-else
-  mochitestdir = $(DEPTH)/_tests/testing/mochitest/$1/$(subst $(topsrcdir),,$(srcdir))
-endif
+#   $1- test directory name
+#   $2- optional: if passed dot used to flatten directory hierarchy copy
+# else- relativesrcdir
+# else- determine relative path
+mochitestdir = \
+    $(strip \
+      $(if $(2),$(DEPTH)/_tests/testing/mochitest/$1/. \
+        ,$(if $(value relativesrcdir) \
+          ,$(DEPTH)/_tests/testing/mochitest/$1/$(relativesrcdir) \
+          ,$(DEPTH)/_tests/testing/mochitest/$1/$(subst $(topsrcdir),,$(srcdir)) \
+    )))
+
 
 define mochitest-libs-rule-template
 libs:: $$($(1))
-	$$(call install_cmd,$$(foreach f,$$^,"$$(f)") $$(call mochitestdir,$(2)))
+	$$(call install_cmd,$$(foreach f,$$^,"$$(f)") $$(call mochitestdir,$(2),$(3)))
 endef
 
 # Provide support for modules with such a large number of tests that
 # installing them with a single $(INSTALL) invocation would overflow
 # command-line length limits on some operating systems.
 ifdef MOCHITEST_FILES_PARTS
 ifdef MOCHITEST_FILES
 $(error You must define only one of MOCHITEST_FILES_PARTS or MOCHITEST_FILES)
@@ -46,15 +53,19 @@ endif
 ifdef MOCHITEST_BROWSER_FILES
 $(eval $(call mochitest-libs-rule-template,MOCHITEST_BROWSER_FILES,browser))
 endif
 
 ifdef MOCHITEST_A11Y_FILES
 $(eval $(call mochitest-libs-rule-template,MOCHITEST_A11Y_FILES,a11y))
 endif
 
+ifdef MOCHITEST_ROBOCOP_FILES
+$(eval $(call mochitest-libs-rule-template,MOCHITEST_ROBOCOP_FILES,tests/robocop,flat_hierarchy))
+endif
+
 ifdef MOCHITEST_WEBAPPRT_CHROME_FILES
 $(eval $(call mochitest-libs-rule-template,MOCHITEST_WEBAPPRT_CHROME_FILES,webapprtChrome))
 endif
 
 INCLUDED_TESTS_MOCHITEST_MK := 1
 
 endif #} INCLUDED_TESTS_MOCHITEST_MK
--- a/config/rules.mk
+++ b/config/rules.mk
@@ -11,16 +11,17 @@ ifndef topsrcdir
 endif
 
 # Integrate with mozbuild-generated make files. We first verify that no
 # variables provided by the automatically generated .mk files are
 # present. If they are, this is a violation of the separation of
 # responsibility between Makefile.in and mozbuild files.
 _MOZBUILD_EXTERNAL_VARIABLES := \
   DIRS \
+  MODULE \
   PARALLEL_DIRS \
   TEST_DIRS \
   TIERS \
   TOOL_DIRS \
   XPIDL_MODULE \
   $(NULL)
 
 ifndef EXTERNALLY_MANAGED_MAKE_FILE
@@ -1795,16 +1796,17 @@ FREEZE_VARIABLES = \
   EXTRA_COMPONENTS \
   EXTRA_PP_COMPONENTS \
   MOCHITEST_FILES \
   MOCHITEST_FILES_PARTS \
   MOCHITEST_CHROME_FILES \
   MOCHITEST_BROWSER_FILES \
   MOCHITEST_BROWSER_FILES_PARTS \
   MOCHITEST_A11Y_FILES \
+  MOCHITEST_ROBOCOP_FILES \
   MOCHITEST_WEBAPPRT_CHROME_FILES \
   $(NULL)
 
 $(foreach var,$(FREEZE_VARIABLES),$(eval $(var)_FROZEN := '$($(var))'))
 
 CHECK_FROZEN_VARIABLES = $(foreach var,$(FREEZE_VARIABLES), \
   $(if $(subst $($(var)_FROZEN),,'$($(var))'),$(error Makefile variable '$(var)' changed value after including rules.mk. Was $($(var)_FROZEN), now $($(var)).)))
 
--- a/config/system-headers
+++ b/config/system-headers
@@ -1102,17 +1102,16 @@ vpx/vp8cx.h
 vpx/vp8dx.h
 #endif
 #ifdef XP_WIN
 vpx/vpx_codec.h
 vpx/vpx_decoder.h
 vpx/vpx_encoder.h
 vpx/vp8cx.h
 vpx/vp8dx.h
-sydneyaudio/sydney_audio.h
 vorbis/codec.h
 theora/theoradec.h
 tremor/ivorbiscodec.h
 ogg/ogg.h
 ogg/os_types.h
 nestegg/nestegg.h
 cubeb/cubeb.h
 #endif
--- a/configure.in
+++ b/configure.in
@@ -4206,17 +4206,16 @@ MOZ_BRANDING_DIRECTORY=
 MOZ_OFFICIAL_BRANDING=
 MOZ_FEEDS=1
 MOZ_FLEXBOX=1
 MOZ_WEBAPP_RUNTIME=
 MOZ_JSDEBUGGER=1
 MOZ_AUTH_EXTENSION=1
 MOZ_OGG=1
 MOZ_RAW=
-MOZ_SYDNEYAUDIO=
 MOZ_SPEEX_RESAMPLER=1
 MOZ_SOUNDTOUCH=1
 MOZ_CUBEB=
 MOZ_VORBIS=
 MOZ_TREMOR=
 MOZ_WAVE=1
 MOZ_SAMPLE_TYPE_FLOAT32=
 MOZ_SAMPLE_TYPE_S16=
@@ -5256,18 +5255,22 @@ if test "$NS_PRINTING"; then
 fi
 
 dnl Turn off webrtc for OS's we don't handle yet, but allow 
 dnl --enable-webrtc to override.  Can disable for everything in
 dnl the master list above.
 if test -n "$MOZ_WEBRTC"; then
     case "$target" in
     *-android*|*-linuxandroid*)
-        dnl Make sure doesn't get matched by *-linux*
-        MOZ_WEBRTC=
+        if test -n "$MOZ_B2G"; then
+            MOZ_WEBRTC=1
+        else
+            dnl Make sure doesn't get matched by *-linux*
+            MOZ_WEBRTC=
+        fi
         ;;
     *-linux*|*-mingw*|*-darwin*)
         dnl Leave enabled
         ;;
     *)
         dnl default to disabled for all others
         MOZ_WEBRTC=
         ;;
@@ -5285,28 +5288,30 @@ MOZ_ARG_DISABLE_BOOL(webrtc,
 if test -n "$MOZ_WEBRTC"; then
     AC_DEFINE(MOZ_WEBRTC)
     MOZ_MEDIA=1
     MOZ_RAW=1
     MOZ_VP8=1
     MOZ_VP8_ENCODER=1
     MOZ_VP8_ERROR_CONCEALMENT=1
 
-    dnl OpenSLES is only available in Android 2.3 and later; we'll change this
-    dnl hard dependency to a dynamic load with graceful runtime failure before
-    dnl we make --enable-webrtc on by default in Android (bug 815905)
-    dnl
-    if test "$OS_TARGET" = "Android"; then
-       LDFLAGS="$LDFLAGS -lOpenSLES"
-    fi
-    case "$target" in
-    *-android*|*-linuxandroid*)
-       LDFLAGS="$LDFLAGS -lOpenSLES"
-       ;;
-    esac
+    if test "$MOZ_WIDGET_TOOLKIT" != "gonk"; then
+       dnl OpenSLES is only available in Android 2.3 and later; we'll change this
+       dnl hard dependency to a dynamic load with graceful runtime failure before
+       dnl we make --enable-webrtc on by default in Android (bug 815905)
+       dnl
+       if test "$OS_TARGET" = "Android"; then
+          LDFLAGS="$LDFLAGS -lOpenSLES"
+       fi
+       case "$target" in
+          *-android*|*-linuxandroid*)
+          LDFLAGS="$LDFLAGS -lOpenSLES"
+          ;;
+       esac
+    fi
 
 dnl enable once Signaling lands
     MOZ_WEBRTC_SIGNALING=1
     AC_DEFINE(MOZ_WEBRTC_SIGNALING)
     if test "${OS_TARGET}" = "WINNT"; then
         MOZ_WEBRTC_IN_LIBXUL=1
     fi
 dnl enable once PeerConnection lands
@@ -5359,17 +5364,16 @@ dnl = Disable Ogg Codecs
 dnl ========================================================
 MOZ_ARG_DISABLE_BOOL(ogg,
 [  --disable-ogg           Disable support for OGG media (Theora video and Vorbis audio)],
     MOZ_OGG=,
     MOZ_OGG=1)
 
 if test -n "$MOZ_OGG"; then
     AC_DEFINE(MOZ_OGG)
-    MOZ_SYDNEYAUDIO=1
     MOZ_CUBEB=1
     MOZ_MEDIA=1
 
     dnl Checks for __attribute__(aligned()) directive
     AC_CACHE_CHECK([__attribute__ ((aligned ())) support],
         [ac_cv_c_attribute_aligned],
         [ac_cv_c_attribute_aligned=0
          CFLAGS_save="${CFLAGS}"
@@ -5442,17 +5446,16 @@ fi
 
 MOZ_ARG_DISABLE_BOOL(wmf,
 [  --disable-wmf  Disable support for Windows Media Foundation],
     MOZ_WMF=,
     MOZ_WMF=1)
 
 if test -n "$MOZ_WMF"; then
     AC_DEFINE(MOZ_WMF)
-    MOZ_SYDNEYAUDIO=1
     MOZ_CUBEB=1
     MOZ_MEDIA=1
 fi;
 
 dnl ========================================================
 dnl = Enable media plugin support
 dnl ========================================================
 if test "$OS_TARGET" = Android -a x"$MOZ_WIDGET_TOOLKIT" != x"gonk"; then
@@ -5539,17 +5542,16 @@ if test -n "$MOZ_VP8"; then
     fi
 fi
 
 AC_SUBST(MOZ_NATIVE_LIBVPX)
 AC_SUBST(MOZ_LIBVPX_CFLAGS)
 AC_SUBST(MOZ_LIBVPX_LIBS)
 
 if test "$MOZ_WEBM"; then
-    MOZ_SYDNEYAUDIO=1
     MOZ_CUBEB=1
     MOZ_MEDIA=1
     if test "$MOZ_SAMPLE_TYPE_FLOAT32"; then
         MOZ_VORBIS=1
     else
         MOZ_TREMOR=1
     fi
 fi
@@ -5643,58 +5645,34 @@ dnl = Disable Wave decoder support
 dnl ========================================================
 MOZ_ARG_DISABLE_BOOL(wave,
 [  --disable-wave          Disable Wave decoder support],
     MOZ_WAVE=,
     MOZ_WAVE=1)
 
 if test -n "$MOZ_WAVE"; then
     AC_DEFINE(MOZ_WAVE)
-    MOZ_SYDNEYAUDIO=1
     MOZ_CUBEB=1
     MOZ_MEDIA=1
 fi
 
 dnl ========================================================
-dnl = Handle dependent SYDNEYAUDIO, CUBEB, and MEDIA defines
-dnl ========================================================
-
-if test -n "$MOZ_SYDNEYAUDIO"; then
-    AC_DEFINE(MOZ_SYDNEYAUDIO)
-fi
+dnl = Handle dependent CUBEB and MEDIA defines
+dnl ========================================================
 
 if test -n "$MOZ_SPEEX_RESAMPLER"; then
     AC_DEFINE(MOZ_SPEEX_RESAMPLER)
 fi
 
 if test -n "$MOZ_SOUNDTOUCH"; then
     AC_DEFINE(MOZ_SOUNDTOUCH)
 fi
 
 if test -n "$MOZ_CUBEB"; then
-    case "$target" in
-    *-android*|*-linuxandroid*)
-        AC_DEFINE(MOZ_CUBEB)
-        ;;
-    *-linux*)
-        AC_DEFINE(MOZ_CUBEB)
-        ;;
-    *-mingw*)
-        AC_DEFINE(MOZ_CUBEB)
-        ;;
-    *-darwin*)
-        AC_DEFINE(MOZ_CUBEB)
-        ;;
-    *-openbsd*)
-        AC_DEFINE(MOZ_CUBEB)
-        ;;
-    *)
-        dnl Other targets will be enabled soon.
-        ;;
-    esac
+    AC_DEFINE(MOZ_CUBEB)
 fi
 
 if test -n "$MOZ_MEDIA"; then
     AC_DEFINE(MOZ_MEDIA)
 fi
 
 if test -n "$MOZ_VORBIS" -a -n "$MOZ_TREMOR"; then
     AC_MSG_ERROR([MOZ_VORBIS and MOZ_TREMOR are mutually exclusive!  The build system should not allow them both to be set, but they are.  Please file a bug at https://bugzilla.mozilla.org/])
@@ -5716,17 +5694,17 @@ if test -n "$MOZ_WEBVTT"; then
     AC_DEFINE(MOZ_WEBVTT)
 fi
 
 dnl ========================================================
 dnl = Check alsa availability on Linux if using sydneyaudio
 dnl ========================================================
 
 dnl If using sydneyaudio with Linux, ensure that the alsa library is available
-if test -n "$MOZ_SYDNEYAUDIO" -a "$OS_TARGET" = "Linux"; then
+if test -n "$MOZ_CUBEB" -a "$OS_TARGET" = "Linux"; then
     MOZ_ALSA=1
 fi
 
 MOZ_ARG_ENABLE_BOOL(alsa,
 [  --enable-alsa          Enable Alsa support (default on Linux)],
 MOZ_ALSA=1,
 MOZ_ALSA=)
 
@@ -8840,17 +8818,16 @@ AC_SUBST(CC_VERSION)
 AC_SUBST(CXX_VERSION)
 AC_SUBST(MSMANIFEST_TOOL)
 AC_SUBST(NS_ENABLE_TSF)
 AC_SUBST(MOZ_NSS_PATCH)
 AC_SUBST(MOZ_APP_COMPONENT_LIBS)
 AC_SUBST(MOZ_APP_EXTRA_LIBS)
 
 AC_SUBST(MOZ_MEDIA)
-AC_SUBST(MOZ_SYDNEYAUDIO)
 AC_SUBST(MOZ_SPEEX_RESAMPLER)
 AC_SUBST(MOZ_SOUNDTOUCH)
 AC_SUBST(MOZ_CUBEB)
 AC_SUBST(MOZ_WAVE)
 AC_SUBST(MOZ_VORBIS)
 AC_SUBST(MOZ_TREMOR)
 AC_SUBST(MOZ_OPUS)
 AC_SUBST(MOZ_WEBM)
@@ -9051,17 +9028,21 @@ if test "${OS_TARGET}" = "WINNT"; then
    if test "$HAVE_64BIT_OS"; then
       OS_BITS=64
    else
       OS_BITS=32
    fi
    EXTRA_GYP_DEFINES="-D MSVS_VERSION=${_MSVS_VERSION} -D MSVS_OS_BITS=${OS_BITS}"
 
 elif test "${OS_TARGET}" = "Android"; then
-   EXTRA_GYP_DEFINES="-D gtest_target_type=executable -D android_toolchain=${android_toolchain} -G os=android "
+   if test "${MOZ_WIDGET_TOOLKIT}" = "gonk"; then
+      EXTRA_GYP_DEFINES="-G os=linux "
+   else
+      EXTRA_GYP_DEFINES="-D gtest_target_type=executable -D android_toolchain=${android_toolchain} -G os=android "
+   fi
 fi
 
 if test -n "$ARM_ARCH"; then
     if test "$ARM_ARCH" -lt 7; then
         EXTRA_GYP_DEFINES="${EXTRA_GYP_DEFINES} -D armv7=0 "
     else
         if test "${OS_TARGET}" = "Android"; then
             EXTRA_GYP_DEFINES="${EXTRA_GYP_DEFINES} -D armv7=1 "
@@ -9076,20 +9057,30 @@ fi
 # Don't try to compile sse4.1 code if toolchain doesn't support
 if test -z "$HAVE_TOOLCHAIN_SUPPORT_MSSE4_1"; then
   EXTRA_GYP_DEFINES="$EXTRA_GYP_DEFINES -D yuv_disable_asm=1"
 fi
 
 if test -n "$MOZ_WEBRTC"; then
    AC_MSG_RESULT("generating WebRTC Makefiles...")
 
+   if test "${MOZ_WIDGET_TOOLKIT}" = "gonk"; then
+      EXTRA_GYP_DEFINES="${EXTRA_GYP_DEFINES} -D build_with_gonk=1 -D include_internal_audio_device=0"
+   fi
+
 dnl Any --include files must also appear in -D FORCED_INCLUDE_FILE= entries
 dnl so that regeneration via dependencies works correctly
    WEBRTC_CONFIG="-D build_with_mozilla=1 -D build_with_chromium=0 --include ${srcdir}/media/webrtc/webrtc_config.gypi -D FORCED_INCLUDE_FILE=${srcdir}/media/webrtc/webrtc_config.gypi"
 
+   if test -n HAVE_CLOCK_MONOTONIC; then
+      WEBRTC_CONFIG="${WEBRTC_CONFIG} -D have_clock_monotonic=1"
+   else
+      WEBRTC_CONFIG="${WEBRTC_CONFIG} -D have_clock_monotonic=0"
+   fi
+
    GYP_WEBRTC_OPTIONS="--format=mozmake ${WEBRTC_CONFIG} -D target_arch=${WEBRTC_TARGET_ARCH} ${EXTRA_GYP_DEFINES} --depth=${srcdir}/media/webrtc/trunk --toplevel-dir=${srcdir} -G OBJDIR=${_objdir}"
 
    $PYTHON ${srcdir}/media/webrtc/trunk/build/gyp_chromium \
      $GYP_WEBRTC_OPTIONS \
      --generator-output=${_objdir}/media/webrtc/trunk \
      ${srcdir}/media/webrtc/trunk/peerconnection.gyp
    if test "$?" != 0; then
       AC_MSG_ERROR([failed to generate WebRTC Makefiles])
deleted file mode 100644
--- a/content/Makefile.in
+++ /dev/null
@@ -1,14 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-DEPTH		= @DEPTH@
-topsrcdir	= @top_srcdir@
-srcdir		= @srcdir@
-VPATH		= @srcdir@
-
-include $(DEPTH)/config/autoconf.mk
-
-MODULE		= content
-
-include $(topsrcdir)/config/rules.mk
--- a/content/base/public/Makefile.in
+++ b/content/base/public/Makefile.in
@@ -4,17 +4,16 @@
 
 DEPTH		= @DEPTH@
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
-MODULE		= content
 GRE_MODULE	= 1
 
 EXPORTS		= \
 mozFlushType.h \
 nsIContent.h \
 nsIAttribute.h \
 nsIContentIterator.h \
 nsContentPolicyUtils.h \
--- a/content/base/public/moz.build
+++ b/content/base/public/moz.build
@@ -25,8 +25,10 @@ XPIDL_SOURCES += [
     'nsISelectionDisplay.idl',
     'nsISelectionListener.idl',
     'nsISelectionPrivate.idl',
     'nsIXMLHttpRequest.idl',
 ]
 
 XPIDL_MODULE = 'content_base'
 
+MODULE = 'content'
+
--- a/content/base/public/nsContentUtils.h
+++ b/content/base/public/nsContentUtils.h
@@ -838,16 +838,21 @@ public:
   static bool IsChromeDoc(nsIDocument *aDocument);
 
   /**
    * Returns true if aDocument is in a docshell whose parent is the same type
    */
   static bool IsChildOfSameType(nsIDocument* aDoc);
 
   /**
+  '* Returns true if the content-type will be rendered as plain-text.
+   */
+  static bool IsPlainTextType(const nsACString& aContentType);
+
+  /**
    * Get the script file name to use when compiling the script
    * referenced by aURI. In cases where there's no need for any extra
    * security wrapper automation the script file name that's returned
    * will be the spec in aURI, else it will be the spec in aDocument's
    * URI followed by aURI's spec, separated by " -> ". Returns true
    * if the script file name was modified, false if it's aURI's
    * spec.
    */
--- a/content/base/src/Makefile.in
+++ b/content/base/src/Makefile.in
@@ -5,17 +5,16 @@
 
 DEPTH		= @DEPTH@
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
-MODULE		= content
 LIBRARY_NAME	= gkconbase_s
 LIBXUL_LIBRARY	= 1
 
 
 EXPORTS		= \
 		nsAtomListUtils.h \
 		nsAttrName.h \
 		nsContentList.h \
--- a/content/base/src/moz.build
+++ b/content/base/src/moz.build
@@ -1,5 +1,7 @@
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+MODULE = 'content'
+
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -3350,16 +3350,30 @@ nsContentUtils::IsChildOfSameType(nsIDoc
   nsCOMPtr<nsIDocShellTreeItem> sameTypeParent;
   if (docShellAsItem) {
     docShellAsItem->GetSameTypeParent(getter_AddRefs(sameTypeParent));
   }
   return sameTypeParent != nullptr;
 }
 
 bool
+nsContentUtils::IsPlainTextType(const nsACString& aContentType)
+{
+  return aContentType.EqualsLiteral(TEXT_PLAIN) ||
+         aContentType.EqualsLiteral(TEXT_CSS) ||
+         aContentType.EqualsLiteral(TEXT_CACHE_MANIFEST) ||
+         aContentType.EqualsLiteral(APPLICATION_JAVASCRIPT) ||
+         aContentType.EqualsLiteral(APPLICATION_XJAVASCRIPT) ||
+         aContentType.EqualsLiteral(TEXT_ECMASCRIPT) ||
+         aContentType.EqualsLiteral(APPLICATION_ECMASCRIPT) ||
+         aContentType.EqualsLiteral(TEXT_JAVASCRIPT) ||
+         aContentType.EqualsLiteral(APPLICATION_JSON);
+}
+
+bool
 nsContentUtils::GetWrapperSafeScriptFilename(nsIDocument *aDocument,
                                              nsIURI *aURI,
                                              nsACString& aScriptURI)
 {
   bool scriptFileNameModified = false;
   aURI->GetSpec(aScriptURI);
 
   if (IsChromeDoc(aDocument)) {
--- a/content/base/src/nsDocument.h
+++ b/content/base/src/nsDocument.h
@@ -26,17 +26,16 @@
 #include "nsIDOMEventTarget.h"
 #include "nsIContent.h"
 #include "nsEventListenerManager.h"
 #include "nsIDOMNodeSelector.h"
 #include "nsIPrincipal.h"
 #include "nsIParser.h"
 #include "nsBindingManager.h"
 #include "nsINodeInfo.h"
-#include "nsHashtable.h"
 #include "nsInterfaceHashtable.h"
 #include "nsIBoxObject.h"
 #include "nsPIBoxObject.h"
 #include "nsIScriptObjectPrincipal.h"
 #include "nsIURI.h"
 #include "nsScriptLoader.h"
 #include "nsIRadioGroupContainer.h"
 #include "nsILayoutHistoryState.h"
--- a/content/base/src/nsFrameLoader.cpp
+++ b/content/base/src/nsFrameLoader.cpp
@@ -1567,17 +1567,17 @@ nsFrameLoader::MaybeCreateDocShell()
     // XXX if no NAME then use ID, after a transition period this will be
     // changed so that XUL only uses ID too (bug 254284).
     if (frameName.IsEmpty() && namespaceID == kNameSpaceID_XUL) {
       mOwnerContent->GetAttr(kNameSpaceID_None, nsGkAtoms::id, frameName);
     }
   }
 
   if (!frameName.IsEmpty()) {
-    mDocShell->SetName(frameName.get());
+    mDocShell->SetName(frameName);
   }
 
   // If our container is a web-shell, inform it that it has a new
   // child. If it's not a web-shell then some things will not operate
   // properly.
 
   nsCOMPtr<nsIDocShellTreeNode> parentAsNode(do_QueryInterface(parentAsWebNav));
   if (parentAsNode) {
--- a/content/base/src/nsImageLoadingContent.cpp
+++ b/content/base/src/nsImageLoadingContent.cpp
@@ -621,43 +621,51 @@ NS_IMETHODIMP nsImageLoadingContent::For
   ErrorResult result;
   ForceReload(result);
   return result.ErrorCode();
 }
 
 NS_IMETHODIMP
 nsImageLoadingContent::BlockOnload(imgIRequest* aRequest)
 {
-  if (aRequest != mCurrentRequest) {
+  if (aRequest == mCurrentRequest) {
+    NS_ASSERTION(!(mCurrentRequestFlags & REQUEST_BLOCKS_ONLOAD),
+                 "Double BlockOnload!?");
+    mCurrentRequestFlags |= REQUEST_BLOCKS_ONLOAD;
+  } else if (aRequest == mPendingRequest) {
+    NS_ASSERTION(!(mPendingRequestFlags & REQUEST_BLOCKS_ONLOAD),
+                 "Double BlockOnload!?");
+    mPendingRequestFlags |= REQUEST_BLOCKS_ONLOAD;
+  } else {
     return NS_OK;
   }
 
-  NS_ASSERTION(!(mCurrentRequestFlags & REQUEST_BLOCKS_ONLOAD),
-               "Double BlockOnload!?");
-  mCurrentRequestFlags |= REQUEST_BLOCKS_ONLOAD;
-
   nsIDocument* doc = GetOurCurrentDoc();
   if (doc) {
     doc->BlockOnload();
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsImageLoadingContent::UnblockOnload(imgIRequest* aRequest)
 {
-  if (aRequest != mCurrentRequest) {
+  if (aRequest == mCurrentRequest) {
+    NS_ASSERTION(mCurrentRequestFlags & REQUEST_BLOCKS_ONLOAD,
+                 "Double UnblockOnload!?");
+    mCurrentRequestFlags &= ~REQUEST_BLOCKS_ONLOAD;
+  } else if (aRequest == mPendingRequest) {
+    NS_ASSERTION(mPendingRequestFlags & REQUEST_BLOCKS_ONLOAD,
+                 "Double UnblockOnload!?");
+    mPendingRequestFlags &= ~REQUEST_BLOCKS_ONLOAD;
+  } else {
     return NS_OK;
   }
 
-  NS_ASSERTION(mCurrentRequestFlags & REQUEST_BLOCKS_ONLOAD,
-               "Double UnblockOnload!?");
-  mCurrentRequestFlags &= ~REQUEST_BLOCKS_ONLOAD;
-
   nsIDocument* doc = GetOurCurrentDoc();
   if (doc) {
     doc->UnblockOnload(false);
   }
 
   return NS_OK;
 }
 
--- a/content/base/test/Makefile.in
+++ b/content/base/test/Makefile.in
@@ -6,18 +6,16 @@
 DEPTH		= @DEPTH@
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 relativesrcdir  = @relativesrcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
-MODULE = content
-
 CPP_UNIT_TESTS = \
                  TestNativeXMLHttpRequest.cpp \
                  TestGetURL.cpp \
                  TestPlainTextSerializer.cpp \
                  $(NULL)
 
 
 XPCSHELL_TESTS = \
--- a/content/base/test/moz.build
+++ b/content/base/test/moz.build
@@ -1,6 +1,9 @@
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 DIRS += ['chrome', 'websocket_hybi']
+
+MODULE = 'content'
+
--- a/content/canvas/public/Makefile.in
+++ b/content/canvas/public/Makefile.in
@@ -5,17 +5,16 @@
 
 DEPTH		= @DEPTH@
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
-MODULE		= content
 EXPORTS_NAMESPACES = mozilla/ipc
 
 EXPORTS		= \
 		nsICanvasRenderingContextInternal.h \
 		nsICanvasElementExternal.h \
 		$(NULL)
 
 EXPORTS_mozilla/ipc = \
--- a/content/canvas/public/moz.build
+++ b/content/canvas/public/moz.build
@@ -4,8 +4,10 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 XPIDL_SOURCES += [
     'nsICanvasGLPrivate.idl',
 ]
 
 XPIDL_MODULE = 'content_canvas'
 
+MODULE = 'content'
+
--- a/content/canvas/src/Makefile.in
+++ b/content/canvas/src/Makefile.in
@@ -5,17 +5,16 @@
 
 DEPTH		= @DEPTH@
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
-MODULE		= content
 LIBRARY_NAME	= gkconcvs_s
 LIBXUL_LIBRARY  = 1
 ifndef _MSC_VER
 FAIL_ON_WARNINGS = 1
 endif # !_MSC_VER
 
 EXPORTS_NAMESPACES = mozilla/dom
 
--- a/content/canvas/src/moz.build
+++ b/content/canvas/src/moz.build
@@ -1,5 +1,7 @@
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+MODULE = 'content'
+
--- a/content/events/public/Makefile.in
+++ b/content/events/public/Makefile.in
@@ -5,17 +5,16 @@
 
 DEPTH		= @DEPTH@
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
-MODULE		= content
 EXPORTS		= \
 		nsMutationEvent.h \
 		nsIPrivateTextEvent.h \
 		nsIPrivateTextRange.h \
 		nsAsyncDOMEvent.h \
 		nsEventDispatcher.h \
 		nsEventStates.h \
 		nsEventNameList.h \
--- a/content/events/public/moz.build
+++ b/content/events/public/moz.build
@@ -4,8 +4,10 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 XPIDL_SOURCES += [
     'nsIEventListenerService.idl',
 ]
 
 XPIDL_MODULE = 'content_events'
 
+MODULE = 'content'
+
--- a/content/events/src/Makefile.in
+++ b/content/events/src/Makefile.in
@@ -5,17 +5,16 @@
 
 DEPTH		= @DEPTH@
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
-MODULE		= content
 LIBRARY_NAME	= gkconevents_s
 LIBXUL_LIBRARY  = 1
 ifndef _MSC_VER
 FAIL_ON_WARNINGS = 1
 endif # !_MSC_VER
 
 EXPORTS		= \
 		nsEventStateManager.h \
--- a/content/events/src/moz.build
+++ b/content/events/src/moz.build
@@ -1,5 +1,7 @@
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+MODULE = 'content'
+
--- a/content/events/src/nsEventListenerManager.h
+++ b/content/events/src/nsEventListenerManager.h
@@ -8,17 +8,16 @@
 
 #include "nsEventListenerManager.h"
 #include "jsapi.h"
 #include "nsCOMPtr.h"
 #include "nsIDOMEventTarget.h"
 #include "nsIDOMEventListener.h"
 #include "nsAutoPtr.h"
 #include "nsCOMArray.h"
-#include "nsHashtable.h"
 #include "nsIScriptContext.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsTObserverArray.h"
 #include "nsGUIEvent.h"
 #include "nsIJSEventListener.h"
 
 class nsIDOMEvent;
 class nsIAtom;
--- a/content/events/src/nsEventStateManager.h
+++ b/content/events/src/nsEventStateManager.h
@@ -8,17 +8,16 @@
 
 #include "mozilla/TypedEnum.h"
 
 #include "nsEvent.h"
 #include "nsGUIEvent.h"
 #include "nsIContent.h"
 #include "nsIObserver.h"
 #include "nsWeakReference.h"
-#include "nsHashtable.h"
 #include "nsITimer.h"
 #include "nsCOMPtr.h"
 #include "nsIDocument.h"
 #include "nsCOMArray.h"
 #include "nsIFrameLoader.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsIMarkupDocumentViewer.h"
 #include "nsIScrollableFrame.h"
--- a/content/html/content/public/Makefile.in
+++ b/content/html/content/public/Makefile.in
@@ -5,17 +5,16 @@
 
 DEPTH     = @DEPTH@
 topsrcdir = @top_srcdir@
 srcdir    = @srcdir@
 VPATH     = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
-MODULE       = content
 EXPORTS = \
 		nsIConstraintValidation.h \
 		nsIFormControl.h \
 		nsIForm.h \
 		nsIFormProcessor.h \
 		nsILink.h \
 		nsIRadioVisitor.h \
 		nsIRadioGroupContainer.h \
--- a/content/html/content/public/moz.build
+++ b/content/html/content/public/moz.build
@@ -7,8 +7,10 @@ XPIDL_SOURCES += [
     'nsIFormSubmitObserver.idl',
     'nsIHTMLMenu.idl',
     'nsIMenuBuilder.idl',
     'nsIPhonetic.idl',
 ]
 
 XPIDL_MODULE = 'content_html'
 
+MODULE = 'content'
+
--- a/content/html/content/src/Makefile.in
+++ b/content/html/content/src/Makefile.in
@@ -5,17 +5,16 @@
 
 DEPTH		= @DEPTH@
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
-MODULE		= content
 LIBRARY_NAME	= gkconhtmlcon_s
 LIBXUL_LIBRARY	= 1
 ifndef _MSC_VER
 FAIL_ON_WARNINGS = 1
 endif # !_MSC_VER
 
 
 EXPORTS		= \
--- a/content/html/content/src/moz.build
+++ b/content/html/content/src/moz.build
@@ -1,5 +1,7 @@
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+MODULE = 'content'
+
--- a/content/html/content/src/nsGenericHTMLFrameElement.cpp
+++ b/content/html/content/src/nsGenericHTMLFrameElement.cpp
@@ -228,17 +228,17 @@ nsGenericHTMLFrameElement::SetAttr(int32
     // what we should reflect.
     LoadSrc();
   } else if (aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::name) {
     // Propagate "name" to the docshell to make browsing context names live,
     // per HTML5.
     nsIDocShell *docShell = mFrameLoader ? mFrameLoader->GetExistingDocShell()
                                          : nullptr;
     if (docShell) {
-      docShell->SetName(PromiseFlatString(aValue).get());
+      docShell->SetName(aValue);
     }
   }
 
   return NS_OK;
 }
 
 nsresult
 nsGenericHTMLFrameElement::UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute,
@@ -249,17 +249,17 @@ nsGenericHTMLFrameElement::UnsetAttr(int
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (aNameSpaceID == kNameSpaceID_None && aAttribute == nsGkAtoms::name) {
     // Propagate "name" to the docshell to make browsing context names live,
     // per HTML5.
     nsIDocShell *docShell = mFrameLoader ? mFrameLoader->GetExistingDocShell()
                                          : nullptr;
     if (docShell) {
-      docShell->SetName(EmptyString().get());
+      docShell->SetName(EmptyString());
     }
   }
 
   return NS_OK;
 }
 
 void
 nsGenericHTMLFrameElement::DestroyContent()
--- a/content/html/content/src/nsHTMLInputElement.cpp
+++ b/content/html/content/src/nsHTMLInputElement.cpp
@@ -262,59 +262,48 @@ nsHTMLInputElement::nsFilePickerShownCal
   if (aResult == nsIFilePicker::returnCancel) {
     return NS_OK;
   }
 
   // Collect new selected filenames
   nsCOMArray<nsIDOMFile> newFiles;
   if (mMulti) {
     nsCOMPtr<nsISimpleEnumerator> iter;
-    nsresult rv = mFilePicker->GetFiles(getter_AddRefs(iter));
+    nsresult rv = mFilePicker->GetDomfiles(getter_AddRefs(iter));
     NS_ENSURE_SUCCESS(rv, rv);
 
     nsCOMPtr<nsISupports> tmp;
     bool prefSaved = false;
     bool loop = true;
+
     while (NS_SUCCEEDED(iter->HasMoreElements(&loop)) && loop) {
       iter->GetNext(getter_AddRefs(tmp));
-      nsCOMPtr<nsIFile> localFile = do_QueryInterface(tmp);
-      if (!localFile) {
-        continue;
-      }
-      nsString path;
-      localFile->GetPath(path);
-      if (path.IsEmpty()) {
-        continue;
-      }
-      nsCOMPtr<nsIDOMFile> domFile =
-        do_QueryObject(new nsDOMFileFile(localFile));
+      nsCOMPtr<nsIDOMFile> domFile = do_QueryInterface(tmp);
+      MOZ_ASSERT(domFile);
+
       newFiles.AppendObject(domFile);
+
       if (!prefSaved) {
         // Store the last used directory using the content pref service
         nsHTMLInputElement::gUploadLastDir->StoreLastUsedDirectory(
-          mInput->OwnerDoc(), localFile);
+          mInput->OwnerDoc(), domFile);
         prefSaved = true;
       }
     }
   }
   else {
-    nsCOMPtr<nsIFile> localFile;
-    nsresult rv = mFilePicker->GetFile(getter_AddRefs(localFile));
+    nsCOMPtr<nsIDOMFile> domFile;
+    nsresult rv = mFilePicker->GetDomfile(getter_AddRefs(domFile));
     NS_ENSURE_SUCCESS(rv, rv);
-    if (localFile) {
-      nsString path;
-      rv = localFile->GetPath(path);
-      if (!path.IsEmpty()) {
-        nsCOMPtr<nsIDOMFile> domFile=
-          do_QueryObject(new nsDOMFileFile(localFile));
-        newFiles.AppendObject(domFile);
-        // Store the last used directory using the content pref service
-        nsHTMLInputElement::gUploadLastDir->StoreLastUsedDirectory(
-          mInput->OwnerDoc(), localFile);
-      }
+    if (domFile) {
+      newFiles.AppendObject(domFile);
+
+      // Store the last used directory using the content pref service
+      nsHTMLInputElement::gUploadLastDir->StoreLastUsedDirectory(
+        mInput->OwnerDoc(), domFile);
     }
   }
 
   if (!newFiles.Count()) {
     return NS_OK;
   }
 
   // The text control frame (if there is one) isn't going to send a change
@@ -497,26 +486,37 @@ UploadLastDir::FetchLastUsedDirectory(ns
       return NS_ERROR_OUT_OF_MEMORY;
     localFile->InitWithPath(prefStr);
     localFile.forget(aFile);
   }
   return NS_OK;
 }
 
 nsresult
-UploadLastDir::StoreLastUsedDirectory(nsIDocument* aDoc, nsIFile* aFile)
+UploadLastDir::StoreLastUsedDirectory(nsIDocument* aDoc, nsIDOMFile* aDomFile)
 {
   NS_PRECONDITION(aDoc, "aDoc is null");
-  NS_PRECONDITION(aFile, "aFile is null");
+  NS_PRECONDITION(aDomFile, "aDomFile is null");
+
+  nsString path;
+  nsresult rv = aDomFile->GetMozFullPathInternal(path);
+  if (NS_FAILED(rv) || path.IsEmpty()) {
+    return NS_OK;
+  }
+
+  nsCOMPtr<nsIFile> localFile;
+  rv = NS_NewNativeLocalFile(NS_ConvertUTF16toUTF8(path), true,
+                             getter_AddRefs(localFile));
+  NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsIURI> docURI = aDoc->GetDocumentURI();
   NS_PRECONDITION(docURI, "docURI is null");
 
   nsCOMPtr<nsIFile> parentFile;
-  aFile->GetParent(getter_AddRefs(parentFile));
+  localFile->GetParent(getter_AddRefs(parentFile));
   if (!parentFile) {
     return NS_OK;
   }
 
   // Attempt to get the CPS, if it's not present we'll just return
   nsCOMPtr<nsIContentPrefService> contentPrefService =
     do_GetService(NS_CONTENT_PREF_SERVICE_CONTRACTID);
   if (!contentPrefService)
@@ -1877,16 +1877,19 @@ nsHTMLInputElement::GetDisplayFileName(n
     aValue = mStaticDocFileList;
     return;
   }
 
   aValue.Truncate();
   for (int32_t i = 0; i < mFiles.Count(); ++i) {
     nsString str;
     mFiles[i]->GetMozFullPathInternal(str);
+    if (str.IsEmpty()) {
+      mFiles[i]->GetName(str);
+    }
     if (i == 0) {
       aValue.Append(str);
     }
     else {
       aValue.Append(NS_LITERAL_STRING(", ") + str);
     }
   }
 }
@@ -3659,21 +3662,16 @@ nsHTMLInputElement::ParseAttribute(int32
         newType = aResult.GetEnumValue();
         if ((IsExperimentalMobileType(newType) &&
              !Preferences::GetBool("dom.experimental_forms", false)) ||
             (newType == NS_FORM_INPUT_RANGE &&
              !Preferences::GetBool("dom.experimental_forms_range", false))) {
           newType = kInputDefaultType->value;
           aResult.SetTo(newType, &aValue);
         }
-        if (newType == NS_FORM_INPUT_FILE &&
-            Preferences::GetBool("dom.disable_input_file", false)) {
-          newType = kInputDefaultType->value;
-          aResult.SetTo(newType, &aValue);
-        }
       } else {
         newType = kInputDefaultType->value;
       }
 
       if (newType != mType) {
         // Make sure to do the check for newType being NS_FORM_INPUT_FILE and
         // the corresponding SetValueInternal() call _before_ we set mType.
         // That way the logic in SetValueInternal() will work right (that logic
--- a/content/html/content/src/nsHTMLInputElement.h
+++ b/content/html/content/src/nsHTMLInputElement.h
@@ -39,20 +39,20 @@ public:
    * @param aFile path to the last used directory
    */
   nsresult FetchLastUsedDirectory(nsIDocument* aDoc, nsIFile** aFile);
 
   /**
    * Store the last used directory for this location using the
    * content pref service, if it is available
    * @param aURI URI of the current page
-   * @param aFile file chosen by the user - the path to the parent of this
+   * @param aDomFile file chosen by the user - the path to the parent of this
    *        file will be stored
    */
-  nsresult StoreLastUsedDirectory(nsIDocument* aDoc, nsIFile* aFile);
+  nsresult StoreLastUsedDirectory(nsIDocument* aDoc, nsIDOMFile* aDomFile);
 };
 
 class nsHTMLInputElement : public nsGenericHTMLFormElement,
                            public nsImageLoadingContent,
                            public nsIDOMHTMLInputElement,
                            public nsITextControlElement,
                            public nsIPhonetic,
                            public nsIDOMNSEditableElement,
--- a/content/html/content/src/nsHTMLSelectElement.h
+++ b/content/html/content/src/nsHTMLSelectElement.h
@@ -151,16 +151,24 @@ public:
   bool Multiple() const
   {
     return GetBoolAttr(nsGkAtoms::multiple);
   }
   void SetMultiple(bool aVal, mozilla::ErrorResult& aRv)
   {
     SetHTMLBoolAttr(nsGkAtoms::multiple, aVal, aRv);
   }
+  uint32_t Size()
+  {
+    return GetHTMLUnsignedIntAttr(nsGkAtoms::size, 0);
+  }
+  void SetSize(uint32_t aSize, mozilla::ErrorResult& aRv)
+  {
+    SetHTMLUnsignedIntAttr(nsGkAtoms::size, aSize, aRv);
+  }
   void GetName(nsString& aName, mozilla::ErrorResult& aRv) const
   {
     GetHTMLAttr(nsGkAtoms::name, aName);
   }
   void SetName(const nsAString& aName, mozilla::ErrorResult& aRv)
   {
     SetHTMLAttr(nsGkAtoms::name, aName, aRv);
   }
--- a/content/html/content/test/forms/Makefile.in
+++ b/content/html/content/test/forms/Makefile.in
@@ -48,16 +48,15 @@ MOCHITEST_FILES = \
 		test_min_attribute.html \
 		test_step_attribute.html \
 		test_stepup_stepdown.html \
 		test_valueasnumber_attribute.html \
 		test_experimental_forms_pref.html \
 		test_input_typing_sanitization.html \
 		test_input_sanitization.html \
 		test_valueasdate_attribute.html \
-		test_input_file_b2g_disabled.html \
 		test_input_textarea_set_value_no_scroll.html \
 		test_submit_invalid_file.html \
 		submit_invalid_file.sjs \
 		$(NULL)
 
 include $(topsrcdir)/config/rules.mk
 
deleted file mode 100644
--- a/content/html/content/test/forms/test_input_file_b2g_disabled.html
+++ /dev/null
@@ -1,44 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=801635
--->
-<head>
-  <meta charset="utf-8">
-  <title>Test for Bug 801635</title>
-  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-  <script type="application/javascript">
-
-  /** Test for Bug 801635 **/
-  var oldPrefValue = null;
-  try {
-    oldPrefValue = SpecialPowers.getBoolPref('dom.disable_input_file');
-  } catch(e) {
-  }
-
-  var input = document.createElement('input');
-
-  SpecialPowers.setBoolPref('dom.disable_input_file', true); 
-  input.type='file';
-  is(input.type, 'text', "<input type='file'> should be disabled");
-  input.type ='text';
-
-  SpecialPowers.setBoolPref('dom.disable_input_file', false); 
-  input.type='file';
-  is(input.type, 'file', "<input type='file'> should not be disabled");
-
-  SpecialPowers.setBoolPref('dom.disable_input_file', oldPrefValue); 
-
-  </script>
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=801635">Disable &lt;input type='file'&gt; on B2G</a>
-<p id="display"></p>
-<div id="content" style="display: none">
-
-</div>
-<pre id="test">
-</pre>
-</body>
-</html>
deleted file mode 100644
--- a/content/html/document/public/Makefile.in
+++ /dev/null
@@ -1,14 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-DEPTH		= @DEPTH@
-topsrcdir	= @top_srcdir@
-srcdir		= @srcdir@
-VPATH		= @srcdir@
-
-include $(DEPTH)/config/autoconf.mk
-
-MODULE		= content
-include $(topsrcdir)/config/rules.mk
--- a/content/html/document/public/moz.build
+++ b/content/html/document/public/moz.build
@@ -4,8 +4,10 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 XPIDL_SOURCES += [
     'nsIImageDocument.idl',
 ]
 
 XPIDL_MODULE = 'content_htmldoc'
 
+MODULE = 'content'
+
--- a/content/html/document/src/Makefile.in
+++ b/content/html/document/src/Makefile.in
@@ -5,17 +5,16 @@
 
 DEPTH		= @DEPTH@
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
-MODULE		= content
 LIBRARY_NAME	= gkconhtmldoc_s
 LIBXUL_LIBRARY	= 1
 ifndef _MSC_VER
 FAIL_ON_WARNINGS = 1
 endif # !_MSC_VER
 
 CPPSRCS		= \
 		nsHTMLContentSink.cpp \
--- a/content/html/document/src/moz.build
+++ b/content/html/document/src/moz.build
@@ -1,5 +1,7 @@
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+MODULE = 'content'
+
--- a/content/html/document/src/nsHTMLDocument.cpp
+++ b/content/html/document/src/nsHTMLDocument.cpp
@@ -100,16 +100,17 @@
 #include "nsMimeTypes.h"
 #include "nsIRequest.h"
 #include "nsHtml5TreeOpExecutor.h"
 #include "nsHtml5Parser.h"
 #include "nsIDOMJSWindow.h"
 #include "nsSandboxFlags.h"
 #include "mozilla/dom/HTMLBodyElement.h"
 #include "nsCharsetSource.h"
+#include "nsIStringBundle.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 #define NS_MAX_DOCUMENT_WRITE_DEPTH 20
 
 #include "prtime.h"
 
@@ -582,25 +583,17 @@ nsHTMLDocument::StartDocumentLoad(const 
   bool asData = !strcmp(aCommand, kLoadAsData);
   if(!(view || viewSource || asData)) {
     MOZ_ASSERT(false, "Bad parser command");
     return NS_ERROR_INVALID_ARG;
   }
 
   bool html = contentType.EqualsLiteral(TEXT_HTML);
   bool xhtml = !html && contentType.EqualsLiteral(APPLICATION_XHTML_XML);
-  bool plainText = !html && !xhtml && (contentType.EqualsLiteral(TEXT_PLAIN) ||
-    contentType.EqualsLiteral(TEXT_CSS) ||
-    contentType.EqualsLiteral(TEXT_CACHE_MANIFEST) ||
-    contentType.EqualsLiteral(APPLICATION_JAVASCRIPT) ||
-    contentType.EqualsLiteral(APPLICATION_XJAVASCRIPT) ||
-    contentType.EqualsLiteral(TEXT_ECMASCRIPT) ||
-    contentType.EqualsLiteral(APPLICATION_ECMASCRIPT) ||
-    contentType.EqualsLiteral(TEXT_JAVASCRIPT) ||
-    contentType.EqualsLiteral(APPLICATION_JSON));
+  bool plainText = !html && !xhtml && nsContentUtils::IsPlainTextType(contentType);
   if (!(html || xhtml || plainText || viewSource)) {
     MOZ_ASSERT(false, "Channel with bad content type.");
     return NS_ERROR_INVALID_ARG;
   }
 
   bool loadAsHtml5 = true;
 
   if (!viewSource && xhtml) {
@@ -863,16 +856,31 @@ nsHTMLDocument::StartDocumentLoad(const 
       // about:blank *only*
       nsCOMPtr<nsIHTMLContentSink> htmlsink;
       NS_NewHTMLContentSink(getter_AddRefs(htmlsink), this, uri,
                             docShell, aChannel);
       mParser->SetContentSink(htmlsink);
     }
   }
 
+  if (plainText && !nsContentUtils::IsChildOfSameType(this) &&
+      Preferences::GetBool("plain_text.wrap_long_lines")) {
+    nsCOMPtr<nsIStringBundleService> bundleService = do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv);
+    NS_ASSERTION(NS_SUCCEEDED(rv) && bundleService, "The bundle service could not be loaded");
+    nsCOMPtr<nsIStringBundle> bundle;
+    rv = bundleService->CreateBundle("chrome://global/locale/browser.properties",
+                                     getter_AddRefs(bundle));
+    NS_ASSERTION(NS_SUCCEEDED(rv) && bundle, "chrome://global/locale/browser.properties could not be loaded");
+    nsXPIDLString title;
+    if (bundle) {
+      bundle->GetStringFromName(NS_LITERAL_STRING("plainText.wordWrap").get(), getter_Copies(title));
+    }
+    SetSelectedStyleSheetSet(title);
+  }
+
   // parser the content of the URI
   mParser->Parse(uri, nullptr, (void *)this);
 
   return rv;
 }
 
 void
 nsHTMLDocument::StopDocumentLoad()
--- a/content/mathml/content/src/Makefile.in
+++ b/content/mathml/content/src/Makefile.in
@@ -5,17 +5,16 @@
 
 DEPTH		= @DEPTH@
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
-MODULE		= content
 LIBRARY_NAME	= gkcontentmathml_s
 LIBXUL_LIBRARY	= 1
 ifndef _MSC_VER
 FAIL_ON_WARNINGS = 1
 endif # !_MSC_VER
 
 CPPSRCS		= \
 		nsMathMLElement.cpp               \
--- a/content/mathml/content/src/moz.build
+++ b/content/mathml/content/src/moz.build
@@ -1,5 +1,7 @@
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+MODULE = 'content'
+
--- a/content/media/AudioStream.cpp
+++ b/content/media/AudioStream.cpp
@@ -8,19 +8,16 @@
 #include "prlog.h"
 #include "prdtoa.h"
 #include "AudioStream.h"
 #include "nsAlgorithm.h"
 #include "VideoUtils.h"
 #include "mozilla/Monitor.h"
 #include "mozilla/Mutex.h"
 #include <algorithm>
-extern "C" {
-#include "sydneyaudio/sydney_audio.h"
-}
 #include "mozilla/Preferences.h"
 
 #if defined(MOZ_CUBEB)
 #include "nsAutoRef.h"
 #include "cubeb/cubeb.h"
 
 template <>
 class nsAutoRefTraits<cubeb_stream> : public nsPointerRefTraits<cubeb_stream>
@@ -28,90 +25,38 @@ class nsAutoRefTraits<cubeb_stream> : pu
 public:
   static void Release(cubeb_stream* aStream) { cubeb_stream_destroy(aStream); }
 };
 
 #endif
 
 namespace mozilla {
 
-#if defined(XP_MACOSX)
-#define SA_PER_STREAM_VOLUME 1
-#endif
-
 #ifdef PR_LOGGING
 PRLogModuleInfo* gAudioStreamLog = nullptr;
 #endif
 
-static const uint32_t FAKE_BUFFER_SIZE = 176400;
-
-// Number of milliseconds per second.
-static const int64_t MS_PER_S = 1000;
-
-class NativeAudioStream : public AudioStream
-{
- public:
-  ~NativeAudioStream();
-  NativeAudioStream();
-
-  nsresult Init(int32_t aNumChannels, int32_t aRate,
-                const dom::AudioChannelType aAudioChannelType);
-  void Shutdown();
-  nsresult Write(const AudioDataValue* aBuf, uint32_t aFrames);
-  uint32_t Available();
-  void SetVolume(double aVolume);
-  void Drain();
-  void Start();
-  void Pause();
-  void Resume();
-  int64_t GetPosition();
-  int64_t GetPositionInFrames();
-  int64_t GetPositionInFramesInternal();
-  bool IsPaused();
-  int32_t GetMinWriteSize();
-
- private:
-  int32_t WriteToBackend(const float* aBuffer, uint32_t aFrames);
-  int32_t WriteToBackend(const short* aBuffer, uint32_t aFrames);
-
-  double mVolume;
-  void* mAudioHandle;
-
-  // True if this audio stream is paused.
-  bool mPaused;
-
-  // True if this stream has encountered an error.
-  bool mInError;
-
-};
-
 #define PREF_VOLUME_SCALE "media.volume_scale"
-#define PREF_USE_CUBEB "media.use_cubeb"
 #define PREF_CUBEB_LATENCY "media.cubeb_latency_ms"
 
 static Mutex* gAudioPrefsLock = nullptr;
 static double gVolumeScale;
-static bool gUseCubeb;
 static uint32_t gCubebLatency;
 
 static int PrefChanged(const char* aPref, void* aClosure)
 {
   if (strcmp(aPref, PREF_VOLUME_SCALE) == 0) {
     nsAdoptingString value = Preferences::GetString(aPref);
     MutexAutoLock lock(*gAudioPrefsLock);
     if (value.IsEmpty()) {
       gVolumeScale = 1.0;
     } else {
       NS_ConvertUTF16toUTF8 utf8(value);
       gVolumeScale = std::max<double>(0, PR_strtod(utf8.get(), nullptr));
     }
-  } else if (strcmp(aPref, PREF_USE_CUBEB) == 0) {
-    bool value = Preferences::GetBool(aPref, true);
-    MutexAutoLock lock(*gAudioPrefsLock);
-    gUseCubeb = value;
   } else if (strcmp(aPref, PREF_CUBEB_LATENCY) == 0) {
     // Arbitrary default stream latency of 100ms.  The higher this
     // value, the longer stream volume changes will take to become
     // audible.
     uint32_t value = Preferences::GetUint(aPref, 100);
     MutexAutoLock lock(*gAudioPrefsLock);
     gCubebLatency = std::min<uint32_t>(std::max<uint32_t>(value, 20), 1000);
   }
@@ -120,22 +65,16 @@ static int PrefChanged(const char* aPref
 
 static double GetVolumeScale()
 {
   MutexAutoLock lock(*gAudioPrefsLock);
   return gVolumeScale;
 }
 
 #if defined(MOZ_CUBEB)
-static bool GetUseCubeb()
-{
-  MutexAutoLock lock(*gAudioPrefsLock);
-  return gUseCubeb;
-}
-
 static cubeb* gCubebContext;
 
 static cubeb* GetCubebContext()
 {
   MutexAutoLock lock(*gAudioPrefsLock);
   if (gCubebContext ||
       cubeb_init(&gCubebContext, "AudioStream") == CUBEB_OK) {
     return gCubebContext;
@@ -146,39 +85,16 @@ static cubeb* GetCubebContext()
 
 static uint32_t GetCubebLatency()
 {
   MutexAutoLock lock(*gAudioPrefsLock);
   return gCubebLatency;
 }
 #endif
 
-static sa_stream_type_t ConvertChannelToSAType(dom::AudioChannelType aType)
-{
-  switch(aType) {
-    case dom::AUDIO_CHANNEL_NORMAL:
-      return SA_STREAM_TYPE_SYSTEM;
-    case dom::AUDIO_CHANNEL_CONTENT:
-      return SA_STREAM_TYPE_MUSIC;
-    case dom::AUDIO_CHANNEL_NOTIFICATION:
-      return SA_STREAM_TYPE_NOTIFICATION;
-    case dom::AUDIO_CHANNEL_ALARM:
-      return SA_STREAM_TYPE_ALARM;
-    case dom::AUDIO_CHANNEL_TELEPHONY:
-      return SA_STREAM_TYPE_VOICE_CALL;
-    case dom::AUDIO_CHANNEL_RINGER:
-      return SA_STREAM_TYPE_RING;
-    case dom::AUDIO_CHANNEL_PUBLICNOTIFICATION:
-      return SA_STREAM_TYPE_ENFORCED_AUDIBLE;
-    default:
-      NS_ERROR("The value of AudioChannelType is invalid");
-      return SA_STREAM_TYPE_MAX;
-  }
-}
-
 #if defined(MOZ_CUBEB) && (__ANDROID__)
 static cubeb_stream_type ConvertChannelToCubebType(dom::AudioChannelType aType)
 {
   switch(aType) {
     case dom::AUDIO_CHANNEL_NORMAL:
       return CUBEB_STREAM_TYPE_SYSTEM;
     case dom::AUDIO_CHANNEL_CONTENT:
       return CUBEB_STREAM_TYPE_MUSIC;
@@ -211,28 +127,26 @@ void AudioStream::InitLibrary()
 {
 #ifdef PR_LOGGING
   gAudioStreamLog = PR_NewLogModule("AudioStream");
 #endif
   gAudioPrefsLock = new Mutex("AudioStream::gAudioPrefsLock");
   PrefChanged(PREF_VOLUME_SCALE, nullptr);
   Preferences::RegisterCallback(PrefChanged, PREF_VOLUME_SCALE);
 #if defined(MOZ_CUBEB)
-  PrefChanged(PREF_USE_CUBEB, nullptr);
-  Preferences::RegisterCallback(PrefChanged, PREF_USE_CUBEB);
   PrefChanged(PREF_CUBEB_LATENCY, nullptr);
   Preferences::RegisterCallback(PrefChanged, PREF_CUBEB_LATENCY);
 #endif
 }
 
 void AudioStream::ShutdownLibrary()
 {
   Preferences::UnregisterCallback(PrefChanged, PREF_VOLUME_SCALE);
 #if defined(MOZ_CUBEB)
-  Preferences::UnregisterCallback(PrefChanged, PREF_USE_CUBEB);
+  Preferences::UnregisterCallback(PrefChanged, PREF_CUBEB_LATENCY);
 #endif
   delete gAudioPrefsLock;
   gAudioPrefsLock = nullptr;
 
 #if defined(MOZ_CUBEB)
   if (gCubebContext) {
     cubeb_destroy(gCubebContext);
     gCubebContext = nullptr;
@@ -310,268 +224,16 @@ nsresult AudioStream::SetPreservesPitch(
   return NS_OK;
 }
 
 int64_t AudioStream::GetWritten()
 {