Merge m-c to inbound.
authorRyan VanderMeulen <ryanvm@gmail.com>
Sat, 01 Feb 2014 17:22:56 -0500
changeset 182541 b973195f0aaf72c4c6f49c2c0158b46900dfcfb1
parent 182540 e9c405b9851a23a95241190bb85a82ee19f02972 (current diff)
parent 182455 f66e1ff54609fcb5386be739c8fe9017d27f270e (diff)
child 182542 09013fef24b123f128bf424822fe4151b8bf32cf
push id3343
push userffxbld
push dateMon, 17 Mar 2014 21:55:32 +0000
treeherdermozilla-beta@2f7d3415f79f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone29.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 m-c to inbound.
--- a/accessible/src/jsat/content-script.js
+++ b/accessible/src/jsat/content-script.js
@@ -15,18 +15,16 @@ XPCOMUtils.defineLazyModuleGetter(this, 
 XPCOMUtils.defineLazyModuleGetter(this, 'Presentation',
   'resource://gre/modules/accessibility/Presentation.jsm');
 XPCOMUtils.defineLazyModuleGetter(this, 'TraversalRules',
   'resource://gre/modules/accessibility/TraversalRules.jsm');
 XPCOMUtils.defineLazyModuleGetter(this, 'Utils',
   'resource://gre/modules/accessibility/Utils.jsm');
 XPCOMUtils.defineLazyModuleGetter(this, 'EventManager',
   'resource://gre/modules/accessibility/EventManager.jsm');
-XPCOMUtils.defineLazyModuleGetter(this, 'ObjectWrapper',
-  'resource://gre/modules/ObjectWrapper.jsm');
 XPCOMUtils.defineLazyModuleGetter(this, 'Roles',
   'resource://gre/modules/accessibility/Constants.jsm');
 
 Logger.debug('content-script.js');
 
 let eventManager = null;
 
 function moveCursor(aMessage) {
--- a/b2g/chrome/content/payment.js
+++ b/b2g/chrome/content/payment.js
@@ -42,18 +42,16 @@ XPCOMUtils.defineLazyServiceGetter(this,
                                    "@mozilla.org/childprocessmessagemanager;1",
                                    "nsIMessageSender");
 
 XPCOMUtils.defineLazyServiceGetter(this, "uuidgen",
                                    "@mozilla.org/uuid-generator;1",
                                    "nsIUUIDGenerator");
 
 #ifdef MOZ_B2G_RIL
-Cu.import('resource://gre/modules/ObjectWrapper.jsm');
-
 XPCOMUtils.defineLazyServiceGetter(this, "gRil",
                                    "@mozilla.org/ril;1",
                                    "nsIRadioInterfaceLayer");
 
 XPCOMUtils.defineLazyServiceGetter(this, "iccProvider",
                                    "@mozilla.org/ril/content-helper;1",
                                    "nsIIccProvider");
 
@@ -327,17 +325,17 @@ let PaymentProvider = {
           iccId: info.iccid,
           mcc: info.mcc,
           mnc: info.mnc,
           dataPrimary: i == this._settings.dataServiceId
         };
       }
     }
 
-    return ObjectWrapper.wrap(this._iccInfo, content);
+    return Cu.cloneInto(this._iccInfo, content);
   },
 
   _silentNumbers: null,
   _silentSmsObservers: null,
 
   sendSilentSms: function sendSilentSms(aNumber, aMessage) {
     if (_debug) {
       LOG("Sending silent message " + aNumber + " - " + aMessage);
--- a/b2g/chrome/content/shell.js
+++ b/b2g/chrome/content/shell.js
@@ -5,17 +5,16 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 Cu.import('resource://gre/modules/ContactService.jsm');
 Cu.import('resource://gre/modules/SettingsChangeNotifier.jsm');
 Cu.import('resource://gre/modules/DataStoreChangeNotifier.jsm');
 Cu.import('resource://gre/modules/AlarmService.jsm');
 Cu.import('resource://gre/modules/ActivitiesService.jsm');
 Cu.import('resource://gre/modules/PermissionPromptHelper.jsm');
-Cu.import('resource://gre/modules/ObjectWrapper.jsm');
 Cu.import('resource://gre/modules/NotificationDB.jsm');
 Cu.import('resource://gre/modules/Payment.jsm');
 Cu.import("resource://gre/modules/AppsUtils.jsm");
 Cu.import('resource://gre/modules/UserAgentOverrides.jsm');
 Cu.import('resource://gre/modules/Keyboard.jsm');
 Cu.import('resource://gre/modules/ErrorPage.jsm');
 #ifdef MOZ_WIDGET_GONK
 Cu.import('resource://gre/modules/NetworkStatsService.jsm');
@@ -545,33 +544,33 @@ var shell = {
     let event = content.document.createEvent('CustomEvent');
     event.initCustomEvent(type, true, true, details ? details : {});
     content.dispatchEvent(event);
   },
 
   sendCustomEvent: function shell_sendCustomEvent(type, details) {
     let content = getContentWindow();
     let event = content.document.createEvent('CustomEvent');
-    let payload = details ? ObjectWrapper.wrap(details, content) : {};
+    let payload = details ? Cu.cloneInto(details, content) : {};
     event.initCustomEvent(type, true, true, payload);
     content.dispatchEvent(event);
   },
 
   sendChromeEvent: function shell_sendChromeEvent(details) {
     if (!this.isHomeLoaded) {
       if (!('pendingChromeEvents' in this)) {
         this.pendingChromeEvents = [];
       }
 
       this.pendingChromeEvents.push(details);
       return;
     }
 
     this.sendEvent(getContentWindow(), "mozChromeEvent",
-                   ObjectWrapper.wrap(details, getContentWindow()));
+                   Cu.cloneInto(details, getContentWindow()));
   },
 
   openAppForSystemMessage: function shell_openAppForSystemMessage(msg) {
     let origin = Services.io.newURI(msg.manifest, null, null).prePath;
     let payload = {
       url: msg.uri,
       manifestURL: msg.manifest,
       isActivity: (msg.type == 'activity'),
--- a/b2g/components/FxAccountsMgmtService.jsm
+++ b/b2g/components/FxAccountsMgmtService.jsm
@@ -19,17 +19,16 @@
 "use strict";
 
 this.EXPORTED_SYMBOLS = ["FxAccountsMgmtService"];
 
 const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
 
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/ObjectWrapper.jsm");
 Cu.import("resource://gre/modules/FxAccountsCommon.js");
 
 XPCOMUtils.defineLazyModuleGetter(this, "FxAccountsManager",
   "resource://gre/modules/FxAccountsManager.jsm");
 
 this.FxAccountsMgmtService = {
 
   _sendChromeEvent: function(aEventName, aMsg) {
--- a/b2g/components/FxAccountsUIGlue.js
+++ b/b2g/components/FxAccountsUIGlue.js
@@ -3,17 +3,16 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict"
 
 const { interfaces: Ci, utils: Cu } = Components;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/ObjectWrapper.jsm");
 Cu.import("resource://gre/modules/Promise.jsm");
 Cu.import("resource://gre/modules/FxAccountsCommon.js");
 
 XPCOMUtils.defineLazyServiceGetter(this, "uuidgen",
                                    "@mozilla.org/uuid-generator;1",
                                    "nsIUUIDGenerator");
 
 function FxAccountsUIGlue() {
--- a/b2g/config/emulator-ics/sources.xml
+++ b/b2g/config/emulator-ics/sources.xml
@@ -7,17 +7,17 @@
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="59605a7c026ff06cc1613af3938579b1dddc6cfe">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="67f11d9b60750270f0bea834832e8108e95204e8"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="ba8b7bf62f871fff4b6a844504c969860c6889b7"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9b6626eddbc85873eaa2a9174a9bd5101e5c05f"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="eda08beb3ba9a159843c70ffde0f9660ec351eb9"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="87aa8679560ce09f6445621d6f370d9de722cdba"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="e33ea242b4328fb0d1824c951f379332b5021512"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="0ff2eb11982b9d3c7a3333900cf0d3a5c0f77e32"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
@@ -90,12 +90,12 @@
   <project name="platform/system/netd" path="system/netd" revision="3d298fde142bee3fc4f07f63f16f2d8ce42339c0"/>
   <project name="platform/system/vold" path="system/vold" revision="919829940468066a32f403980b43f6ebfee5d314"/>
   <!-- Emulator specific things -->
   <project name="android-development" path="development" remote="b2g" revision="4e236e65a5d652a66ac32590f69f2123d17cb4ad"/>
   <project name="device_generic_goldfish" path="device/generic/goldfish" remote="b2g" revision="5be0a9c4b3c6c004786917fdb5bee248960d045b"/>
   <project name="platform/external/iproute2" path="external/iproute2" revision="c66c5716d5335e450f7a7b71ccc6a604fb2f41d2"/>
   <project name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="d2685281e2e54ca14d1df304867aa82c37b27162"/>
   <project name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="627f9b20fc518937b93747a7ff1ed4f5ed46e06f"/>
-  <project name="platform/prebuilts/tools" path="prebuilts/tools" revision="a3daa50e9b5db558696951ae724f913e4e5c7489"/>
+  <project name="platform/prebuilts/tools" path="prebuilts/tools" revision="c16df012d9649be75d6590f93aeacbdc24b29d53"/>
   <project name="platform_prebuilts_qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="11663426672fcc46e2a0f29239afa736b90635ba"/>
   <project name="android-sdk" path="sdk" remote="b2g" revision="5701d3cb45c2e848cc57003cda2e1141288ecae4"/>
 </manifest>
--- a/b2g/config/emulator-jb/sources.xml
+++ b/b2g/config/emulator-jb/sources.xml
@@ -6,17 +6,17 @@
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="317f25e0a4cb3e8e86e2b76c37a14081372f0307">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="67f11d9b60750270f0bea834832e8108e95204e8"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="ba8b7bf62f871fff4b6a844504c969860c6889b7"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9b6626eddbc85873eaa2a9174a9bd5101e5c05f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="e33ea242b4328fb0d1824c951f379332b5021512"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="0ff2eb11982b9d3c7a3333900cf0d3a5c0f77e32"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="905bfa3548eb75cf1792d0d8412b92113bbd4318"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="c3d7efc45414f1b44cd9c479bb2758c91c4707c0"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="5c45f43419d5582949284eee9cef0c43d866e03b"/>
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="3748b4168e7bd8d46457d4b6786003bc6a5223ce"/>
--- a/b2g/config/emulator/sources.xml
+++ b/b2g/config/emulator/sources.xml
@@ -7,17 +7,17 @@
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="59605a7c026ff06cc1613af3938579b1dddc6cfe">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="67f11d9b60750270f0bea834832e8108e95204e8"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="ba8b7bf62f871fff4b6a844504c969860c6889b7"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9b6626eddbc85873eaa2a9174a9bd5101e5c05f"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="eda08beb3ba9a159843c70ffde0f9660ec351eb9"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="87aa8679560ce09f6445621d6f370d9de722cdba"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="e33ea242b4328fb0d1824c951f379332b5021512"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="0ff2eb11982b9d3c7a3333900cf0d3a5c0f77e32"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
@@ -90,12 +90,12 @@
   <project name="platform/system/netd" path="system/netd" revision="3d298fde142bee3fc4f07f63f16f2d8ce42339c0"/>
   <project name="platform/system/vold" path="system/vold" revision="919829940468066a32f403980b43f6ebfee5d314"/>
   <!-- Emulator specific things -->
   <project name="android-development" path="development" remote="b2g" revision="4e236e65a5d652a66ac32590f69f2123d17cb4ad"/>
   <project name="device_generic_goldfish" path="device/generic/goldfish" remote="b2g" revision="5be0a9c4b3c6c004786917fdb5bee248960d045b"/>
   <project name="platform/external/iproute2" path="external/iproute2" revision="c66c5716d5335e450f7a7b71ccc6a604fb2f41d2"/>
   <project name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="d2685281e2e54ca14d1df304867aa82c37b27162"/>
   <project name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="627f9b20fc518937b93747a7ff1ed4f5ed46e06f"/>
-  <project name="platform/prebuilts/tools" path="prebuilts/tools" revision="a3daa50e9b5db558696951ae724f913e4e5c7489"/>
+  <project name="platform/prebuilts/tools" path="prebuilts/tools" revision="c16df012d9649be75d6590f93aeacbdc24b29d53"/>
   <project name="platform_prebuilts_qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="11663426672fcc46e2a0f29239afa736b90635ba"/>
   <project name="android-sdk" path="sdk" remote="b2g" revision="5701d3cb45c2e848cc57003cda2e1141288ecae4"/>
 </manifest>
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -1,4 +1,4 @@
 {
-    "revision": "56cedb487649ecd17173482c4ffe87d1bc298d86", 
+    "revision": "3f66811d103f803b94ec2c7127356ff3283073cd", 
     "repo_path": "/integration/gaia-central"
 }
--- a/b2g/config/hamachi/sources.xml
+++ b/b2g/config/hamachi/sources.xml
@@ -6,17 +6,17 @@
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="b2g/ics_strawberry" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="59605a7c026ff06cc1613af3938579b1dddc6cfe">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="67f11d9b60750270f0bea834832e8108e95204e8"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="ba8b7bf62f871fff4b6a844504c969860c6889b7"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9b6626eddbc85873eaa2a9174a9bd5101e5c05f"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="84f2f2fce22605e17d511ff1767e54770067b5b5"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="e33ea242b4328fb0d1824c951f379332b5021512"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="0ff2eb11982b9d3c7a3333900cf0d3a5c0f77e32"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
   <project name="platform/bionic" path="bionic" revision="d2eb6c7b6e1bc7643c17df2d9d9bcb1704d0b9ab"/>
--- a/b2g/config/helix/sources.xml
+++ b/b2g/config/helix/sources.xml
@@ -5,17 +5,17 @@
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <default remote="caf" revision="b2g/ics_strawberry" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="59605a7c026ff06cc1613af3938579b1dddc6cfe">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="67f11d9b60750270f0bea834832e8108e95204e8"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="ba8b7bf62f871fff4b6a844504c969860c6889b7"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9b6626eddbc85873eaa2a9174a9bd5101e5c05f"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="84f2f2fce22605e17d511ff1767e54770067b5b5"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="e33ea242b4328fb0d1824c951f379332b5021512"/>
   <project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
   <project name="platform/bionic" path="bionic" revision="d2eb6c7b6e1bc7643c17df2d9d9bcb1704d0b9ab"/>
--- a/b2g/config/inari/sources.xml
+++ b/b2g/config/inari/sources.xml
@@ -7,17 +7,17 @@
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="ics_chocolate_rb4.2" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="59605a7c026ff06cc1613af3938579b1dddc6cfe">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="67f11d9b60750270f0bea834832e8108e95204e8"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="ba8b7bf62f871fff4b6a844504c969860c6889b7"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9b6626eddbc85873eaa2a9174a9bd5101e5c05f"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="84f2f2fce22605e17d511ff1767e54770067b5b5"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="e33ea242b4328fb0d1824c951f379332b5021512"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="0ff2eb11982b9d3c7a3333900cf0d3a5c0f77e32"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
   <project name="platform/bionic" path="bionic" revision="cd5dfce80bc3f0139a56b58aca633202ccaee7f8"/>
--- a/b2g/config/leo/sources.xml
+++ b/b2g/config/leo/sources.xml
@@ -6,17 +6,17 @@
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="b2g/ics_strawberry" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="59605a7c026ff06cc1613af3938579b1dddc6cfe">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="67f11d9b60750270f0bea834832e8108e95204e8"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="ba8b7bf62f871fff4b6a844504c969860c6889b7"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9b6626eddbc85873eaa2a9174a9bd5101e5c05f"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="84f2f2fce22605e17d511ff1767e54770067b5b5"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="e33ea242b4328fb0d1824c951f379332b5021512"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="0ff2eb11982b9d3c7a3333900cf0d3a5c0f77e32"/>
   <project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
--- a/b2g/config/mako/sources.xml
+++ b/b2g/config/mako/sources.xml
@@ -6,17 +6,17 @@
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="317f25e0a4cb3e8e86e2b76c37a14081372f0307">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="67f11d9b60750270f0bea834832e8108e95204e8"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="ba8b7bf62f871fff4b6a844504c969860c6889b7"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9b6626eddbc85873eaa2a9174a9bd5101e5c05f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="e33ea242b4328fb0d1824c951f379332b5021512"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="0ff2eb11982b9d3c7a3333900cf0d3a5c0f77e32"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="905bfa3548eb75cf1792d0d8412b92113bbd4318"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="c3d7efc45414f1b44cd9c479bb2758c91c4707c0"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="5c45f43419d5582949284eee9cef0c43d866e03b"/>
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="3748b4168e7bd8d46457d4b6786003bc6a5223ce"/>
--- a/b2g/config/wasabi/sources.xml
+++ b/b2g/config/wasabi/sources.xml
@@ -6,17 +6,17 @@
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="ics_chocolate_rb4.2" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="59605a7c026ff06cc1613af3938579b1dddc6cfe">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="67f11d9b60750270f0bea834832e8108e95204e8"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="ba8b7bf62f871fff4b6a844504c969860c6889b7"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9b6626eddbc85873eaa2a9174a9bd5101e5c05f"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="84f2f2fce22605e17d511ff1767e54770067b5b5"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="e33ea242b4328fb0d1824c951f379332b5021512"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="0ff2eb11982b9d3c7a3333900cf0d3a5c0f77e32"/>
   <project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
--- a/b2g/confvars.sh
+++ b/b2g/confvars.sh
@@ -52,13 +52,13 @@ MOZ_TIME_MANAGER=1
 
 MOZ_B2G_CERTDATA=1
 MOZ_PAY=1
 MOZ_TOOLKIT_SEARCH=
 MOZ_PLACES=
 MOZ_B2G=1
 
 if test "$OS_TARGET" = "Android"; then
-MOZ_NUWA_PROCESS=1
+MOZ_NUWA_PROCESS=
 fi
 MOZ_FOLD_LIBS=1
 
 MOZ_JSDOWNLOADS=1
--- a/browser/app/blocklist.xml
+++ b/browser/app/blocklist.xml
@@ -1,10 +1,10 @@
 <?xml version="1.0"?>
-<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1390521109000">
+<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1391123284000">
   <emItems>
       <emItem  blockID="i454" id="sqlmoz@facebook.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
                                 <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
                     <prefs>
               </prefs>
@@ -373,28 +373,40 @@
               </prefs>
     </emItem>
       <emItem  blockID="i499" id="{babb9931-ad56-444c-b935-38bffe18ad26}">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
                     <prefs>
               </prefs>
     </emItem>
+      <emItem  blockID="i356" id="{341f4dac-1966-47ff-aacf-0ce175f1498a}">
+                        <versionRange  minVersion="0" maxVersion="*" severity="1">
+                    </versionRange>
+                    <prefs>
+              </prefs>
+    </emItem>
       <emItem  blockID="i111" os="WINNT" id="{C3949AC2-4B17-43ee-B4F1-D26B9D42404D}">
                         <versionRange  minVersion="0" maxVersion="15.0.5" severity="1">
                     </versionRange>
                     <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i136" id="Adobe@flash.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
                     <prefs>
               </prefs>
     </emItem>
+      <emItem  blockID="i543" id="{badea1ae-72ed-4f6a-8c37-4db9a4ac7bc9}">
+                        <versionRange  minVersion="0" maxVersion="*" severity="1">
+                    </versionRange>
+                    <prefs>
+              </prefs>
+    </emItem>
       <emItem  blockID="i447" id="{B18B1E5C-4D81-11E1-9C00-AFEB4824019B}">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
                     <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i519" id="703db0db-5fe9-44b6-9f53-c6a91a0ad5bd@7314bc82-969e-4d2a-921b-e5edd0b02cf1.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
@@ -415,39 +427,36 @@
               </prefs>
     </emItem>
       <emItem  blockID="i532" id="249911bc-d1bd-4d66-8c17-df533609e6d8@c76f3de9-939e-4922-b73c-5d7a3139375d.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
                     <prefs>
               </prefs>
     </emItem>
-      <emItem  blockID="i466" id="afext@anchorfree.com">
-                        <versionRange  minVersion="0" maxVersion="*" severity="1">
+      <emItem  blockID="i258" id="helperbar@helperbar.com">
+                        <versionRange  minVersion="0" maxVersion="1.0" severity="1">
                     </versionRange>
                     <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i98" id="youtubeeing@youtuberie.com">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
                     <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i515" id="/^({bf9194c2-b86d-4ebc-9b53-1c08b6ff779e}|{61a83e16-7198-49c6-8874-3e4e8faeb4f3}|{f0af464e-5167-45cf-9cf0-66b396d1918c}|{5d9968c3-101c-4944-ba71-72d77393322d}|{01e86e69-a2f8-48a0-b068-83869bdba3d0})$/">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
                     <prefs>
               </prefs>
     </emItem>
-      <emItem  blockID="i46" id="{841468a1-d7f4-4bd3-84e6-bb0f13a06c64}">
-                        <versionRange  minVersion="0.1" maxVersion="*">
-                      <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-                              <versionRange  minVersion="9.0a1" maxVersion="9.0" />
-                          </targetApplication>
+      <emItem  blockID="i549" id="/^firefox@(albrechto|swiftbrowse|springsmart|storimbo|squirrelweb|betterbrowse|lizardlink|rolimno|browsebeyond|clingclang|weblayers|kasimos|higher-aurum|xaven|bomlabio)\.(com?|net|org|info|biz)$/">
+                        <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
                     <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i168" id="flashX@adobe.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
                     <prefs>
@@ -590,18 +599,18 @@
               </prefs>
     </emItem>
       <emItem  blockID="i352" id="vpyekkifgv@vpyekkifgv.org">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
                     <prefs>
               </prefs>
     </emItem>
-      <emItem  blockID="i258" id="helperbar@helperbar.com">
-                        <versionRange  minVersion="0" maxVersion="1.0" severity="1">
+      <emItem  blockID="i466" id="afext@anchorfree.com">
+                        <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
                     <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i468" id="05dd836e-2cbd-4204-9ff3-2f8a8665967d@a8876730-fb0c-4057-a2fc-f9c09d438e81.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
                     <prefs>
@@ -688,16 +697,22 @@
               </prefs>
     </emItem>
       <emItem  blockID="i218" id="ffxtlbr@claro.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
                     <prefs>
               </prefs>
     </emItem>
+      <emItem  blockID="i548" id="/^firefox@(jumpflip|webconnect|browsesmart|mybuzzsearch|outobox|greygray|lemurleap|divapton|secretsauce|batbrowse|whilokii|linkswift|qualitink|browsefox|kozaka|diamondata|glindorus|saltarsmart|bizzybolt|websparkle)\.(com?|net|org|info|biz)$/">
+                        <versionRange  minVersion="0" maxVersion="*" severity="1">
+                    </versionRange>
+                    <prefs>
+              </prefs>
+    </emItem>
       <emItem  blockID="i79" id="GifBlock@facebook.com">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
                     <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i69" id="{977f3b97-5461-4346-92c8-a14c749b77c9}">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
@@ -728,16 +743,22 @@
               </prefs>
     </emItem>
       <emItem  blockID="i446" id="{E90FA778-C2B7-41D0-9FA9-3FEC1CA54D66}">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
                     <prefs>
               </prefs>
     </emItem>
+      <emItem  blockID="i394" id="{7D4F1959-3F72-49d5-8E59-F02F8AA6815D}">
+                        <versionRange  minVersion="0" maxVersion="*" severity="1">
+                    </versionRange>
+                    <prefs>
+              </prefs>
+    </emItem>
       <emItem  blockID="i507" id="4zffxtbr-bs@VideoDownloadConverter_4z.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
                     <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i7" id="{2224e955-00e9-4613-a844-ce69fccaae91}">
                           <prefs>
@@ -756,16 +777,30 @@
               </prefs>
     </emItem>
       <emItem  blockID="i52" id="ff-ext@youtube">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
                     <prefs>
               </prefs>
     </emItem>
+      <emItem  blockID="i38" id="{B7082FAA-CB62-4872-9106-E42DD88EDE45}">
+                        <versionRange  minVersion="0.1" maxVersion="3.3.0.*">
+                      <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
+                              <versionRange  minVersion="3.7a1" maxVersion="*" />
+                          </targetApplication>
+                    </versionRange>
+                                <versionRange  minVersion="3.3.1" maxVersion="*">
+                      <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
+                              <versionRange  minVersion="5.0a1" maxVersion="*" />
+                          </targetApplication>
+                    </versionRange>
+                    <prefs>
+              </prefs>
+    </emItem>
       <emItem  blockID="i471" id="firefox@luckyleap.net">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
                     <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i495" id="kallow@facebook.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
@@ -870,18 +905,18 @@
               </prefs>
     </emItem>
       <emItem  blockID="i461" id="{8E9E3331-D360-4f87-8803-52DE43566502}">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
                     <prefs>
               </prefs>
     </emItem>
-      <emItem  blockID="i394" id="{7D4F1959-3F72-49d5-8E59-F02F8AA6815D}">
-                        <versionRange  minVersion="0" maxVersion="*" severity="1">
+      <emItem  blockID="i542" id="/^({bf67a47c-ea97-4caf-a5e3-feeba5331231}|{24a0cfe1-f479-4b19-b627-a96bf1ea3a56})$/">
+                        <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
                     <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i493" id="12x3q@3244516.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
                     <prefs>
@@ -930,17 +965,17 @@
               </prefs>
     </emItem>
       <emItem  blockID="i524" id="/^({4e988b08-8c51-45c1-8d74-73e0c8724579}|{93ec97bf-fe43-4bca-a735-5c5d6a0a40c4}|{aed63b38-7428-4003-a052-ca6834d8bad3}|{0b5130a9-cc50-4ced-99d5-cda8cc12ae48}|{C4CFC0DE-134F-4466-B2A2-FF7C59A8BFAD})$/">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
                     <prefs>
               </prefs>
     </emItem>
-      <emItem  blockID="i76" id="crossriderapp3924@crossrider.com">
+      <emItem  blockID="i68" id="flashupdate@adobe.com">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
                     <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i382" id="{6926c7f7-6006-42d1-b046-eba1b3010315}">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
@@ -980,48 +1015,52 @@
               </prefs>
     </emItem>
       <emItem  blockID="i460" id="{845cab51-d8d2-472f-8bd9-2b44642d97c2}">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
                     <prefs>
               </prefs>
     </emItem>
-      <emItem  blockID="i38" id="{B7082FAA-CB62-4872-9106-E42DD88EDE45}">
-                        <versionRange  minVersion="0.1" maxVersion="3.3.0.*">
-                      <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-                              <versionRange  minVersion="3.7a1" maxVersion="*" />
-                          </targetApplication>
-                    </versionRange>
-                                <versionRange  minVersion="3.3.1" maxVersion="*">
-                      <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
-                              <versionRange  minVersion="5.0a1" maxVersion="*" />
-                          </targetApplication>
+      <emItem  blockID="i547" id="{87934c42-161d-45bc-8cef-ef18abe2a30c}">
+                        <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
                     <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i6" id="{3f963a5b-e555-4543-90e2-c3908898db71}">
                         <versionRange  minVersion=" " maxVersion="8.5">
                     </versionRange>
                     <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i56" id="flash@adobe.com">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
                     <prefs>
               </prefs>
     </emItem>
+      <emItem  blockID="i538" id="{354dbb0a-71d5-4e9f-9c02-6c88b9d387ba}">
+                        <versionRange  minVersion="0" maxVersion="*" severity="3">
+                    </versionRange>
+                    <prefs>
+              </prefs>
+    </emItem>
       <emItem  blockID="i451" id="{e44a1809-4d10-4ab8-b343-3326b64c7cdd}">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
                     <prefs>
               </prefs>
     </emItem>
+      <emItem  blockID="i540" id="/^(ffxtlbr@mixidj\.com|{c0c2693d-2ee8-47b4-9df7-b67a0ee31988}|{67097627-fd8e-4f6b-af4b-ecb65e50112e}|{f6f0f973-a4a3-48cf-9a7a-b7a69c30d71a}|{a3d0e35f-f1da-4ccb-ae77-e9d27777e68d}|{1122b43d-30ee-403f-9bfa-3cc99b0caddd})$/">
+                        <versionRange  minVersion="0" maxVersion="*" severity="3">
+                    </versionRange>
+                    <prefs>
+              </prefs>
+    </emItem>
       <emItem  blockID="i216" id="fdm_ffext@freedownloadmanager.org">
                         <versionRange  minVersion="1.0" maxVersion="1.3.1">
                       <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
                               <versionRange  minVersion="3.0a1" maxVersion="*" />
                           </targetApplication>
                     </versionRange>
                                 <versionRange  minVersion="1.5.7.5" maxVersion="1.5.7.5" severity="1">
                     </versionRange>
@@ -1096,18 +1135,18 @@
               </prefs>
     </emItem>
       <emItem  blockID="i103" id="kdrgun@gmail.com">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
                     <prefs>
               </prefs>
     </emItem>
-      <emItem  blockID="i476" id="mbroctone@facebook.com">
-                        <versionRange  minVersion="0" maxVersion="*" severity="3">
+      <emItem  blockID="i539" id="ScorpionSaver@jetpack">
+                        <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
                     <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i3" id="langpack-vi-VN@firefox.mozilla.org">
                         <versionRange  minVersion="2.0" maxVersion="2.0">
                     </versionRange>
                     <prefs>
@@ -1138,16 +1177,25 @@
               </prefs>
     </emItem>
       <emItem  blockID="i106" os="WINNT" id="{97E22097-9A2F-45b1-8DAF-36AD648C7EF4}">
                         <versionRange  minVersion="0" maxVersion="15.0.5" severity="1">
                     </versionRange>
                     <prefs>
               </prefs>
     </emItem>
+      <emItem  blockID="i46" id="{841468a1-d7f4-4bd3-84e6-bb0f13a06c64}">
+                        <versionRange  minVersion="0.1" maxVersion="*">
+                      <targetApplication  id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
+                              <versionRange  minVersion="9.0a1" maxVersion="9.0" />
+                          </targetApplication>
+                    </versionRange>
+                    <prefs>
+              </prefs>
+    </emItem>
       <emItem  blockID="i505" id="extacylife@a.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
                     <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i15" id="personas@christopher.beard">
                         <versionRange  minVersion="1.6" maxVersion="1.6">
@@ -1201,16 +1249,22 @@
               </prefs>
     </emItem>
       <emItem  blockID="i312" id="extension21804@extension21804.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
                     <prefs>
               </prefs>
     </emItem>
+      <emItem  blockID="i545" id="superlrcs@svenyor.net">
+                        <versionRange  minVersion="0" maxVersion="*" severity="1">
+                    </versionRange>
+                    <prefs>
+              </prefs>
+    </emItem>
       <emItem  blockID="i324" id="/^((34qEOefiyYtRJT@IM5Munavn\.com)|(Mro5Fm1Qgrmq7B@ByrE69VQfZvZdeg\.com)|(KtoY3KGxrCe5ie@yITPUzbBtsHWeCdPmGe\.com)|(9NgIdLK5Dq4ZMwmRo6zk@FNt2GCCLGyUuOD\.com)|(NNux7bWWW@RBWyXdnl6VGls3WAwi\.com)|(E3wI2n@PEHTuuNVu\.com)|(2d3VuWrG6JHBXbQdbr@3BmSnQL\.com))$/">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
                     <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i503" id="{9CE11043-9A15-4207-A565-0C94C42D590D}">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
@@ -1285,16 +1339,22 @@
               </prefs>
     </emItem>
       <emItem  blockID="i220" id="pricepeep@getpricepeep.com">
                         <versionRange  minVersion="0" maxVersion="2.1.0.19.99" severity="1">
                     </versionRange>
                     <prefs>
               </prefs>
     </emItem>
+      <emItem  blockID="i544" id="/^(93abedcf-8e3a-4d02-b761-d1441e437c09@243f129d-aee2-42c2-bcd1-48858e1c22fd\.com|9acfc440-ac2d-417a-a64c-f6f14653b712@09f9a966-9258-4b12-af32-da29bdcc28c5\.com|58ad0086-1cfb-48bb-8ad2-33a8905572bc@5715d2be-69b9-4930-8f7e-64bdeb961cfd\.com)$/">
+                        <versionRange  minVersion="0" maxVersion="*" severity="1">
+                    </versionRange>
+                    <prefs>
+              </prefs>
+    </emItem>
       <emItem  blockID="i224" id="{336D0C35-8A85-403a-B9D2-65C292C39087}">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
                     <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i61" id="youtube@youtube3.com">
                         <versionRange  minVersion="0" maxVersion="*">
@@ -1317,18 +1377,18 @@
               </prefs>
     </emItem>
       <emItem  blockID="i372" id="5nc3QHFgcb@r06Ws9gvNNVRfH.com">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
                     <prefs>
               </prefs>
     </emItem>
-      <emItem  blockID="i356" id="{341f4dac-1966-47ff-aacf-0ce175f1498a}">
-                        <versionRange  minVersion="0" maxVersion="*" severity="1">
+      <emItem  blockID="i476" id="mbroctone@facebook.com">
+                        <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
                     <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i70" id="psid-vhvxQHMZBOzUZA@jetpack">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
                     <prefs>
@@ -1353,16 +1413,22 @@
               </prefs>
     </emItem>
       <emItem  blockID="i60" id="youtb3@youtb3.com">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
                     <prefs>
               </prefs>
     </emItem>
+      <emItem  blockID="i546" id="firefox@browsefox.com">
+                        <versionRange  minVersion="0" maxVersion="*" severity="1">
+                    </versionRange>
+                    <prefs>
+              </prefs>
+    </emItem>
       <emItem  blockID="i510" id="{3c9a72a0-b849-40f3-8c84-219109c27554}">
                         <versionRange  minVersion="0" maxVersion="*" severity="3">
                     </versionRange>
                     <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i23" id="firefox@bandoo.com">
                         <versionRange  minVersion="5.0" maxVersion="5.0" severity="1">
@@ -1398,17 +1464,23 @@
               </prefs>
     </emItem>
       <emItem  blockID="i497" id="{872b5b88-9db5-4310-bdd0-ac189557e5f5}">
                         <versionRange  minVersion="0" maxVersion="*" severity="1">
                     </versionRange>
                     <prefs>
               </prefs>
     </emItem>
-      <emItem  blockID="i68" id="flashupdate@adobe.com">
+      <emItem  blockID="i541" id="/^({988919ff-0cd8-4d0c-bc7e-60d55a49eb64}|{494b9726-9084-415c-a499-68c07e187244}|{55b95864-3251-45e9-bb30-1a82589aaff1}|{eef3855c-fc2d-41e6-8d91-d368f51b3055}|{90a1b331-c2b4-4933-9f63-ba7b84d60d58}|{d2cf9842-af95-48cd-b873-bfbb48cd7f5e})$/">
+                        <versionRange  minVersion="0" maxVersion="*" severity="3">
+                    </versionRange>
+                    <prefs>
+              </prefs>
+    </emItem>
+      <emItem  blockID="i76" id="crossriderapp3924@crossrider.com">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
                     <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i445" id="firefoxaddon@youtubeenhancer.com">
                         <versionRange  minVersion="208.7.0" maxVersion="208.7.0" severity="3">
                     </versionRange>
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -1338,15 +1338,19 @@ pref("network.disable.ipc.security", tru
 
 // CustomizableUI debug logging.
 pref("browser.uiCustomization.debug", false);
 
 // The URL where remote content that composes the UI for Firefox Accounts should
 // be fetched. Must use HTTPS.
 pref("identity.fxaccounts.remote.uri", "https://accounts.firefox.com/?service=sync&context=fx_desktop_v1");
 
+// The URL where remote content that forces re-authentication for Firefox Accounts
+// should be fetched.  Must use HTTPS.
+pref("identity.fxaccounts.remote.force_auth.uri", "https://accounts.firefox.com/force_auth?service=sync&context=fx_desktop_v1");
+
 // The URL we take the user to when they opt to "manage" their Firefox Account.
 // Note that this will always need to be in the same TLD as the
 // "identity.fxaccounts.remote.uri" pref.
 pref("identity.fxaccounts.settings.uri", "https://accounts.firefox.com/settings");
 
 // The URL of the Firefox Accounts auth server backend
 pref("identity.fxaccounts.auth.uri", "https://api.accounts.firefox.com/v1");
--- a/browser/base/content/aboutaccounts/aboutaccounts.js
+++ b/browser/base/content/aboutaccounts/aboutaccounts.js
@@ -53,51 +53,51 @@ function sha256(str) {
   hasher.update(data, data.length);
 
   return hasher.finish(true);
 }
 
 function promptForRelink(acctName) {
   let sb = Services.strings.createBundle("chrome://browser/locale/syncSetup.properties");
   let continueLabel = sb.GetStringFromName("continue.label");
-  let title = sb.GetStringFromName("relink.verify.title");
-  let description = sb.formatStringFromName("relink.verify.description",
+  let title = sb.GetStringFromName("relinkVerify.title");
+  let description = sb.formatStringFromName("relinkVerify.description",
                                             [acctName], 1);
-  let body = sb.GetStringFromName("relink.verify.heading") +
+  let body = sb.GetStringFromName("relinkVerify.heading") +
              "\n\n" + description;
   let ps = Services.prompt;
   let buttonFlags = (ps.BUTTON_POS_0 * ps.BUTTON_TITLE_IS_STRING) +
                     (ps.BUTTON_POS_1 * ps.BUTTON_TITLE_CANCEL) +
                     ps.BUTTON_POS_1_DEFAULT;
   let pressed = Services.prompt.confirmEx(window, title, body, buttonFlags,
                                      continueLabel, null, null, null,
                                      {});
   return pressed == 0; // 0 is the "continue" button
 }
 
 let wrapper = {
   iframe: null,
 
-  init: function () {
+  init: function (url=null) {
     let weave = Cc["@mozilla.org/weave/service;1"]
                   .getService(Ci.nsISupports)
                   .wrappedJSObject;
 
     // Don't show about:accounts with FxA disabled.
     if (!weave.fxAccountsEnabled) {
       document.body.remove();
       return;
     }
 
     let iframe = document.getElementById("remote");
     this.iframe = iframe;
     iframe.addEventListener("load", this);
 
     try {
-      iframe.src = fxAccounts.getAccountsURI();
+      iframe.src = url || fxAccounts.getAccountsURI();
     } catch (e) {
       error("Couldn't init Firefox Account wrapper: " + e.message);
     }
   },
 
   handleEvent: function (evt) {
     switch (evt.type) {
       case "load":
@@ -231,21 +231,24 @@ function getStarted() {
   show("remote");
 }
 
 function openPrefs() {
   window.openPreferences("paneSync");
 }
 
 function init() {
-  let signinQuery = window.location.href.match(/signin=true$/);
-
-  if (signinQuery) {
+  if (window.location.href.contains("action=signin")) {
     show("remote");
     wrapper.init();
+  } else if (window.location.href.contains("action=reauth")) {
+    fxAccounts.promiseAccountsForceSigninURI().then(url => {
+      show("remote");
+      wrapper.init(url);
+    });
   } else {
     // Check if we have a local account
     fxAccounts.getSignedInUser().then(user => {
       if (user) {
         show("stage");
         show("manage");
         let sb = Services.strings.createBundle("chrome://browser/locale/syncSetup.properties");
         document.title = sb.GetStringFromName("manage.pageTitle");
--- a/browser/base/content/aboutaccounts/aboutaccounts.xhtml
+++ b/browser/base/content/aboutaccounts/aboutaccounts.xhtml
@@ -10,17 +10,17 @@
   <!ENTITY % aboutAccountsDTD SYSTEM "chrome://browser/locale/aboutAccounts.dtd">
   %aboutAccountsDTD;
   <!ENTITY % syncBrandDTD SYSTEM "chrome://browser/locale/syncBrand.dtd">
   %syncBrandDTD;
 ]>
 
 <html xmlns="http://www.w3.org/1999/xhtml">
   <head>
-   <title>&aboutAccounts.pageTitle;</title>
+   <title>&syncBrand.fullName.label;</title>
    <meta name="viewport" content="width=device-width"/>
 
 
    <link rel="icon" type="image/png" id="favicon"
          href="chrome://branding/content/icon32.png"/>
    <link rel="stylesheet"
      href="chrome://browser/content/aboutaccounts/fonts.css"
      type="text/css" />
@@ -34,33 +34,33 @@
      href="chrome://browser/content/aboutaccounts/aboutaccounts.css"
      type="text/css" />
   </head>
   <body>
     <div id="stage">
 
       <div id="manage">
         <header>
-          <h1>&syncBrand.fxa-plural.label;</h1>
-
-          <h2>&syncBrand.shortName.label;</h2>
+          <h1><span>&syncBrand.fullName.label;</span></h1>
+          <h2><span>&aboutAccounts.welcome;</span></h2>
         </header>
 
         <section>
             <div class="graphic graphic-sync-intro"> </div>
 
             <div class="button-row">
-              <a class="button" href="#" onclick="openPrefs()">Manage</a>
+              <a class="button" href="#" onclick="openPrefs()">&aboutAccountsConfig.manage.label;</a>
             </div>
         </section>
       </div>
 
       <div id="intro">
         <header>
-          <h1>&aboutAccounts.pageTitle;</h1>
+          <h1><span>&syncBrand.fullName.label;</span></h1>
+          <h2><span>&aboutAccounts.welcome;</span></h2>
         </header>
 
         <section>
             <div class="graphic graphic-sync-intro"> </div>
 
             <div class="description">&aboutAccountsConfig.description;</div>
 
             <div class="button-row">
--- a/browser/base/content/aboutaccounts/fonts.css
+++ b/browser/base/content/aboutaccounts/fonts.css
@@ -1,31 +1,25 @@
 @font-face {
   font-family: 'Fira Sans';
   font-style: normal;
   font-weight: 400;
   src: local('Fira Sans'),
        local('FiraSans'),
-       url('fonts/firasans-regular.woff') format('woff'),
-       /*url('/fonts/latin/firasans-regular.ttf') format('truetype'),*/
-       /*url('/fonts/latin/firasans-regular.svg#Fira Sans') format('svg');*/
+       url('fonts/firasans-regular.woff') format('woff');
 }
 @font-face {
   font-family: 'Fira Sans';
   font-style: normal;
   font-weight: 300;
   src: local('Fira Sans Light'),
        local('FiraSansLight'),
-       url('fonts/firasans-light.woff') format('woff'),
-       /*url('/fonts/latin/firasans-light.ttf') format('truetype'),*/
-       /*url('/fonts/latin/firasans-light.svg#Fira Sans') format('svg');*/
+       url('fonts/firasans-light.woff') format('woff');
 }
 @font-face {
   font-family: 'Clear Sans';
   font-style: normal;
   font-weight: 400;
   src: local('Clear Sans'),
        local('ClearSans'),
-       url('fonts/clearsans-regular.woff') format('woff'),
-       /*url('/fonts/latin/clearsans-regular.ttf') format('truetype'),*/
-       /*url('/fonts/latin/clearsans-regular.svg#Clear Sans') format('svg');*/
+       url('fonts/clearsans-regular.woff') format('woff');
 }
 
--- a/browser/base/content/browser-customization.js
+++ b/browser/base/content/browser-customization.js
@@ -95,17 +95,16 @@ let CustomizationHandler = {
     CombinedStopReload.init();
     CombinedBackForward.init();
     UpdateUrlbarSearchSplitterState();
 
     // Update the urlbar
     if (gURLBar) {
       URLBarSetURI();
       XULBrowserWindow.asyncUpdateUI();
-      BookmarkingUI.updateStarState();
     }
 
     // Re-enable parts of the UI we disabled during the dialog
     let menubar = document.getElementById("main-menubar");
     for (let childNode of menubar.childNodes)
       childNode.setAttribute("disabled", false);
     let cmd = document.getElementById("cmd_CustomizeToolbars");
     cmd.removeAttribute("disabled");
--- a/browser/base/content/browser-fxaccounts.js
+++ b/browser/base/content/browser-fxaccounts.js
@@ -181,26 +181,31 @@ let gFxAccounts = {
           this.button.setAttribute("signedin", "true");
           this.button.setAttribute("label", userData.email);
           this.button.setAttribute("tooltiptext", userData.email);
         }
       }
     });
   },
 
-  toggle: function (event) {
+  onMenuPanelCommand: function (event) {
     if (event.originalTarget.hasAttribute("signedin")) {
       this.openPreferences();
     } else {
-      this.openSignInPage();
+      this.openAccountsPage();
     }
 
     PanelUI.hide();
   },
 
   openPreferences: function () {
     openPreferences("paneSync");
   },
 
-  openSignInPage: function () {
+  openAccountsPage: function () {
     switchToTabHavingURI("about:accounts", true);
+  },
+
+  openSignInAgainPage: function () {
+    // FIXME: This should actually show the pre-filled username version of about:accounts?
+    switchToTabHavingURI("about:accounts?signin=true", true);
   }
 };
--- a/browser/base/content/browser-menubar.inc
+++ b/browser/base/content/browser-menubar.inc
@@ -357,28 +357,28 @@
     <menupopup id="bookmarksMenuPopup"
 #ifndef XP_MACOSX
                placespopup="true"
 #endif
                context="placesContext"
                openInTabs="children"
                oncommand="BookmarksEventHandler.onCommand(event, this.parentNode._placesView);"
                onclick="BookmarksEventHandler.onClick(event, this.parentNode._placesView);"
-               onpopupshowing="PlacesCommandHook.updateBookmarkAllTabsCommand();
+               onpopupshowing="BookmarkingUI.onMainMenuPopupShowing(event);
                                if (!this.parentNode._placesView)
                                  new PlacesMenu(event, 'place:folder=BOOKMARKS_MENU');"
                tooltip="bhTooltip" popupsinherittooltip="true">
       <menuitem id="bookmarksShowAll"
                 label="&showAllBookmarks2.label;"
                 command="Browser:ShowAllBookmarks"
                 key="manBookmarkKb"/>
       <menuseparator id="organizeBookmarksSeparator"/>
       <menuitem id="menu_bookmarkThisPage"
-                label="&bookmarkThisPageCmd.label;"
                 command="Browser:AddBookmarkAs"
+                observes="bookmarkThisPageBroadcaster"
                 key="addBookmarkAsKb"/>
       <menuitem id="subscribeToPageMenuitem"
 #ifndef XP_MACOSX
                 class="menuitem-iconic"
 #endif
                 label="&subscribeToPageMenuitem.label;"
                 oncommand="return FeedHandler.subscribeToFeed(null, event);"
                 onclick="checkForMiddleClick(this, event);"
--- a/browser/base/content/browser-places.js
+++ b/browser/base/content/browser-places.js
@@ -954,49 +954,58 @@ let PlacesToolbarHelper = {
 //// BookmarkingUI
 
 /**
  * Handles the bookmarks menu-button in the toolbar.
  */
 
 let BookmarkingUI = {
   get button() {
+    delete this.button;
     let widgetGroup = CustomizableUI.getWidget("bookmarks-menu-button");
-    if (widgetGroup.areaType == CustomizableUI.TYPE_TOOLBAR) {
-      return widgetGroup.forWindow(window).node;
-    }
-    return null;
+    return this.button = widgetGroup.forWindow(window).node;
   },
 
+  /* Can't make this a self-deleting getter because it's anonymous content
+   * and might lose/regain bindings at some point. */
   get star() {
-    let button = this.button;
-    return button && document.getAnonymousElementByAttribute(button, "anonid",
-                                                             "button");
+    return document.getAnonymousElementByAttribute(this.button, "anonid",
+                                                   "button");
   },
 
   get anchor() {
+    if (!this._shouldUpdateStarState()) {
+      return null;
+    }
     let widget = CustomizableUI.getWidget("bookmarks-menu-button")
                                .forWindow(window);
     if (widget.overflowed)
       return widget.anchor;
 
-    let star = this.star;
-    return star && document.getAnonymousElementByAttribute(star, "class",
-                                                           "toolbarbutton-icon");
+    return document.getAnonymousElementByAttribute(this.star, "class",
+                                                   "toolbarbutton-icon");
+  },
+
+  get broadcaster() {
+    delete this.broadcaster;
+    let broadcaster = document.getElementById("bookmarkThisPageBroadcaster");
+    return this.broadcaster = broadcaster;
   },
 
   STATUS_UPDATING: -1,
   STATUS_UNSTARRED: 0,
   STATUS_STARRED: 1,
   get status() {
+    if (!this._shouldUpdateStarState()) {
+      return this.STATUS_UNSTARRED;
+    }
     if (this._pendingStmt)
       return this.STATUS_UPDATING;
-    let button = this.button;
-    return button && button.hasAttribute("starred") ? this.STATUS_STARRED
-                                                    : this.STATUS_UNSTARRED;
+    return this.button.hasAttribute("starred") ? this.STATUS_STARRED
+                                               : this.STATUS_UNSTARRED;
   },
 
   get _starredTooltip()
   {
     delete this._starredTooltip;
     return this._starredTooltip =
       gNavigatorBundle.getString("starButtonOn.tooltip");
   },
@@ -1004,16 +1013,25 @@ let BookmarkingUI = {
   get _unstarredTooltip()
   {
     delete this._unstarredTooltip;
     return this._unstarredTooltip =
       gNavigatorBundle.getString("starButtonOff.tooltip");
   },
 
   /**
+   * The type of the area in which the button is currently located.
+   * When in the panel, we don't update the button's icon.
+   */
+  _currentAreaType: null,
+  _shouldUpdateStarState: function() {
+    return this._currentAreaType == CustomizableUI.TYPE_TOOLBAR;
+  },
+
+  /**
    * The popup contents must be updated when the user customizes the UI, or
    * changes the personal toolbar collapsed status.  In such a case, any needed
    * change should be handled in the popupshowing helper, for performance
    * reasons.
    */
   _popupNeedsUpdate: true,
   onToolbarVisibilityChange: function BUI_onToolbarVisibilityChange() {
     this._popupNeedsUpdate = true;
@@ -1064,94 +1082,105 @@ let BookmarkingUI = {
       insertionPoint: ".panel-subview-footer"
     });
   },
 
   /**
    * Handles star styling based on page proxy state changes.
    */
   onPageProxyStateChanged: function BUI_onPageProxyStateChanged(aState) {
-    if (!this.star) {
+    if (!this._shouldUpdateStarState()) {
       return;
     }
 
     if (aState == "invalid") {
       this.star.setAttribute("disabled", "true");
       this.button.removeAttribute("starred");
       this.button.setAttribute("buttontooltiptext", "");
     }
     else {
       this.star.removeAttribute("disabled");
+      this._updateStar();
     }
     this._updateToolbarStyle();
   },
 
+  _updateCustomizationState: function BUI__updateCustomizationState() {
+    let placement = CustomizableUI.getPlacementOfWidget("bookmarks-menu-button");
+    this._currentAreaType = placement && CustomizableUI.getAreaType(placement.area);
+  },
+
   _updateToolbarStyle: function BUI__updateToolbarStyle() {
-    let button = this.button;
-    if (!button)
-      return;
-
-    let personalToolbar = document.getElementById("PersonalToolbar");
-    let onPersonalToolbar = button.parentNode == personalToolbar ||
-                            button.parentNode.parentNode == personalToolbar;
+    let onPersonalToolbar = false;
+    if (this._currentAreaType == CustomizableUI.TYPE_TOOLBAR) {
+      let personalToolbar = document.getElementById("PersonalToolbar");
+      onPersonalToolbar = this.button.parentNode == personalToolbar ||
+                          this.button.parentNode.parentNode == personalToolbar;
+    }
 
     if (onPersonalToolbar) {
-      button.classList.add("bookmark-item");
-      button.classList.remove("toolbarbutton-1");
+      this.button.classList.add("bookmark-item");
+      this.button.classList.remove("toolbarbutton-1");
     }
     else {
-      button.classList.remove("bookmark-item");
-      button.classList.add("toolbarbutton-1");
+      this.button.classList.remove("bookmark-item");
+      this.button.classList.add("toolbarbutton-1");
     }
   },
 
   _uninitView: function BUI__uninitView() {
     // When an element with a placesView attached is removed and re-inserted,
     // XBL reapplies the binding causing any kind of issues and possible leaks,
     // so kill current view and let popupshowing generate a new one.
-    let button = this.button;
-    if (button && button._placesView)
-      button._placesView.uninit();
+    if (this.button._placesView)
+      this.button._placesView.uninit();
   },
 
   customizeStart: function BUI_customizeStart() {
     this._uninitView();
   },
 
   customizeChange: function BUI_customizeChange() {
+    let usedToUpdateStarState = this._shouldUpdateStarState();
+    this._updateCustomizationState();
+    if (usedToUpdateStarState != this._shouldUpdateStarState()) {
+      this.updateStarState();
+    }
     this._updateToolbarStyle();
   },
 
   customizeDone: function BUI_customizeDone() {
     this.onToolbarVisibilityChange();
     this._updateToolbarStyle();
   },
 
   init: function() {
     CustomizableUI.addListener(this);
+    this._updateCustomizationState();
   },
 
   _hasBookmarksObserver: false,
   uninit: function BUI_uninit() {
+    this._updateBookmarkPageMenuItem(true);
     CustomizableUI.removeListener(this);
 
     this._uninitView();
 
     if (this._hasBookmarksObserver) {
       PlacesUtils.removeLazyBookmarkObserver(this);
     }
 
     if (this._pendingStmt) {
       this._pendingStmt.cancel();
       delete this._pendingStmt;
     }
   },
 
   updateStarState: function BUI_updateStarState() {
-    if (!this.button || (this._uri && gBrowser.currentURI.equals(this._uri))) {
+    if (this._uri && gBrowser.currentURI.equals(this._uri)) {
       return;
     }
 
     // Reset tracked values.
     this._uri = gBrowser.currentURI;
     this._itemIds = [];
 
     if (this._pendingStmt) {
@@ -1190,184 +1219,224 @@ let BookmarkingUI = {
         }
       }
 
       delete this._pendingStmt;
     }, this);
   },
 
   _updateStar: function BUI__updateStar() {
-    let button = this.button;
-    if (!button)
+    if (!this._shouldUpdateStarState()) {
+      if (this.button.hasAttribute("starred")) {
+        this.button.removeAttribute("starred");
+        this.button.removeAttribute("buttontooltiptext");
+      }
       return;
+    }
 
-    if (this._itemIds.length > 0) {
-      button.setAttribute("starred", "true");
-      button.setAttribute("buttontooltiptext", this._starredTooltip);
+    if (this._itemIds && this._itemIds.length > 0) {
+      this.button.setAttribute("starred", "true");
+      this.button.setAttribute("buttontooltiptext", this._starredTooltip);
     }
     else {
-      button.removeAttribute("starred");
-      button.setAttribute("buttontooltiptext", this._unstarredTooltip);
+      this.button.removeAttribute("starred");
+      this.button.setAttribute("buttontooltiptext", this._unstarredTooltip);
     }
   },
 
+  /**
+   * forceReset is passed when we're destroyed and the label should go back
+   * to the default (Bookmark This Page) for OS X.
+   */
+  _updateBookmarkPageMenuItem: function BUI__updateBookmarkPageMenuItem(forceReset) {
+    let isStarred = !forceReset && this._itemIds && this._itemIds.length > 0;
+    let label = isStarred ? "editlabel" : "bookmarklabel";
+    this.broadcaster.setAttribute("label", this.broadcaster.getAttribute(label));
+  },
+
+  onMainMenuPopupShowing: function BUI_onMainMenuPopupShowing(event) {
+    this._updateBookmarkPageMenuItem();
+    PlacesCommandHook.updateBookmarkAllTabsCommand();
+  },
+
   onCommand: function BUI_onCommand(aEvent) {
     if (aEvent.target != aEvent.currentTarget) {
       return;
     }
 
     // Handle special case when the button is in the panel.
-    let widgetGroup = CustomizableUI.getWidget("bookmarks-menu-button");
-    let widget = widgetGroup.forWindow(window);
-    if (widgetGroup.areaType == CustomizableUI.TYPE_MENU_PANEL) {
+    let widget = CustomizableUI.getWidget("bookmarks-menu-button")
+                               .forWindow(window);
+    if (this._currentAreaType == CustomizableUI.TYPE_MENU_PANEL) {
       let view = document.getElementById("PanelUI-bookmarks");
-      view.addEventListener("ViewShowing", this.onPanelMenuViewShowing);
-      view.addEventListener("ViewHiding", this.onPanelMenuViewHiding);
+      view.addEventListener("ViewShowing", this);
+      view.addEventListener("ViewHiding", this);
       widget.node.setAttribute("closemenu", "none");
       PanelUI.showSubView("PanelUI-bookmarks", widget.node,
                           CustomizableUI.AREA_PANEL);
       return;
     }
-    else if (widget.overflowed) {
+    if (widget.overflowed) {
       // Allow to close the panel if the page is already bookmarked, cause
       // we are going to open the edit bookmark panel.
       if (this._itemIds.length > 0)
         widget.node.removeAttribute("closemenu");
       else
         widget.node.setAttribute("closemenu", "none");
     }
 
     // Ignore clicks on the star if we are updating its state.
     if (!this._pendingStmt) {
       PlacesCommandHook.bookmarkCurrentPage(this._itemIds.length > 0);
     }
   },
 
+  handleEvent: function BUI_handleEvent(aEvent) {
+    switch (aEvent.type) {
+      case "ViewShowing":
+        this.onPanelMenuViewShowing(aEvent);
+        break;
+      case "ViewHiding":
+        this.onPanelMenuViewHiding(aEvent);
+        break;
+    }
+  },
+
   onPanelMenuViewShowing: function BUI_onViewShowing(aEvent) {
+    this._updateBookmarkPageMenuItem();
     // Update checked status of the toolbar toggle.
     let viewToolbar = document.getElementById("panelMenu_viewBookmarksToolbar");
     let personalToolbar = document.getElementById("PersonalToolbar");
     if (personalToolbar.collapsed)
       viewToolbar.removeAttribute("checked");
     else
       viewToolbar.setAttribute("checked", "true");
     // Setup the Places view.
     this._panelMenuView = new PlacesPanelMenuView("place:folder=BOOKMARKS_MENU",
                                                   "panelMenu_bookmarksMenu",
                                                   "panelMenu_bookmarksMenu", {
                                                     extraClasses: {
                                                       mainLevel: "subviewbutton"
                                                     }
                                                   });
+    aEvent.target.removeEventListener("ViewShowing", this);
   },
 
   onPanelMenuViewHiding: function BUI_onViewHiding(aEvent) {
     this._panelMenuView.uninit();
     delete this._panelMenuView;
+    aEvent.target.removeEventListener("ViewHiding", this);
   },
 
   onPanelMenuViewCommand: function BUI_onPanelMenuViewCommand(aEvent, aView) {
     let target = aEvent.originalTarget;
     if (!target._placesNode)
       return;
     if (PlacesUtils.nodeIsContainer(target._placesNode))
       PlacesCommandHook.showPlacesOrganizer([ "BookmarksMenu", target._placesNode.itemId ]);
     else
       PlacesUIUtils.openNodeWithEvent(target._placesNode, aEvent, aView);
     PanelUI.hide();
   },
 
   // nsINavBookmarkObserver
   onItemAdded: function BUI_onItemAdded(aItemId, aParentId, aIndex, aItemType,
                                         aURI) {
-    if (!this.button) {
-      return;
-    }
-
     if (aURI && aURI.equals(this._uri)) {
       // If a new bookmark has been added to the tracked uri, register it.
       if (this._itemIds.indexOf(aItemId) == -1) {
         this._itemIds.push(aItemId);
-        this._updateStar();
+        // Only need to update the UI if it wasn't marked as starred before:
+        if (this._itemIds.length == 1) {
+          this._updateStar();
+        }
       }
     }
   },
 
   onItemRemoved: function BUI_onItemRemoved(aItemId) {
-    if (!this.button) {
-      return;
-    }
-
     let index = this._itemIds.indexOf(aItemId);
     // If one of the tracked bookmarks has been removed, unregister it.
     if (index != -1) {
       this._itemIds.splice(index, 1);
-      this._updateStar();
+      // Only need to update the UI if the page is no longer starred
+      if (this._itemIds.length == 0) {
+        this._updateStar();
+      }
     }
   },
 
   onItemChanged: function BUI_onItemChanged(aItemId, aProperty,
                                             aIsAnnotationProperty, aNewValue) {
-    if (!this.button) {
-      return;
-    }
-
     if (aProperty == "uri") {
       let index = this._itemIds.indexOf(aItemId);
       // If the changed bookmark was tracked, check if it is now pointing to
       // a different uri and unregister it.
       if (index != -1 && aNewValue != this._uri.spec) {
         this._itemIds.splice(index, 1);
-        this._updateStar();
+        // Only need to update the UI if the page is no longer starred
+        if (this._itemIds.length == 0) {
+          this._updateStar();
+        }
       }
       // If another bookmark is now pointing to the tracked uri, register it.
       else if (index == -1 && aNewValue == this._uri.spec) {
         this._itemIds.push(aItemId);
-        this._updateStar();
+        // Only need to update the UI if it wasn't marked as starred before:
+        if (this._itemIds.length == 1) {
+          this._updateStar();
+        }
       }
     }
   },
 
   onBeginUpdateBatch: function () {},
   onEndUpdateBatch: function () {},
   onBeforeItemRemoved: function () {},
   onItemVisited: function () {},
   onItemMoved: function () {},
 
   // CustomizableUI events:
   _starButtonLabel: null,
-  _starButtonOverflowedLabel: null,
+  get _starButtonOverflowedLabel() {
+    delete this._starButtonOverflowedLabel;
+    this._starButtonOverflowedLabel =
+      gNavigatorBundle.getString("starButtonOverflowed.label");
+  },
+  get _starButtonOverflowedStarredLabel() {
+    delete this._starButtonOverflowedStarredLabel;
+    this._starButtonOverflowedStarredLabel =
+      gNavigatorBundle.getString("starButtonOverflowedStarred.label");
+  },
   onWidgetOverflow: function(aNode, aContainer) {
     let win = aNode.ownerDocument.defaultView;
     if (aNode.id != "bookmarks-menu-button" || win != window)
       return;
 
-    if (!this._starButtonOverflowedLabel) {
-      this._starButtonOverflowedLabel = gNavigatorBundle.getString(
-                                        "starButtonOverflowed.label");
-    }
-
     let currentLabel = aNode.getAttribute("label");
     if (!this._starButtonLabel)
       this._starButtonLabel = currentLabel;
 
-    if (currentLabel == this._starButtonLabel)
-      aNode.setAttribute("label", this._starButtonOverflowedLabel);
+    if (currentLabel == this._starButtonLabel) {
+      let desiredLabel = this._itemIds.length > 0 ? this._starButtonOverflowedStarredLabel
+                                                 : this._starButtonOverflowedLabel;
+      aNode.setAttribute("label", desiredLabel);
+    }
   },
 
   onWidgetUnderflow: function(aNode, aContainer) {
     let win = aNode.ownerDocument.defaultView;
     if (aNode.id != "bookmarks-menu-button" || win != window)
       return;
 
     // If the button hasn't been in the overflow panel before, we may ignore
     // this event.
-    if (!this._starButtonOverflowedLabel || !this._starButtonLabel)
+    if (!this._starButtonLabel)
       return;
 
-    if (aNode.getAttribute("label") == this._starButtonOverflowedLabel)
+    if (aNode.getAttribute("label") != this._starButtonLabel)
       aNode.setAttribute("label", this._starButtonLabel);
   },
 
   QueryInterface: XPCOMUtils.generateQI([
     Ci.nsINavBookmarkObserver
   ])
 };
--- a/browser/base/content/browser-sets.inc
+++ b/browser/base/content/browser-sets.inc
@@ -135,16 +135,21 @@
                  type="checkbox" group="sidebar"
                  sidebarurl="chrome://browser/content/history/history-panel.xul"
                  oncommand="toggleSidebar('viewHistorySidebar');"/>
 
     <broadcaster id="viewWebPanelsSidebar" autoCheck="false"
                  type="checkbox" group="sidebar" sidebarurl="chrome://browser/content/web-panels.xul"
                  oncommand="toggleSidebar('viewWebPanelsSidebar');"/>
 
+    <broadcaster id="bookmarkThisPageBroadcaster"
+                 label="&bookmarkThisPageCmd.label;"
+                 bookmarklabel="&bookmarkThisPageCmd.label;"
+                 editlabel="&editThisBookmarkCmd.label;"/>
+
     <!-- popup blocking menu items -->
     <broadcaster id="blockedPopupAllowSite"
                  accesskey="&allowPopups.accesskey;"
                  oncommand="gPopupBlockerObserver.toggleAllowPopupsForSite(event);"/>
     <broadcaster id="blockedPopupEditSettings"
 #ifdef XP_WIN
                  label="&editPopupSettings.label;"
 #else
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -384,58 +384,51 @@
       </hbox>
       <hbox pack="center">
         <button id="ctrlTab-showAll" class="ctrlTab-preview" noicon="true"/>
       </hbox>
     </panel>
 
     <!-- Sync Panel -->
     <panel id="sync-start-panel" class="sync-panel" type="arrow" hidden="true"
-           noautofocus="true" level="top" onclick="this.hidePopup();">
+           noautofocus="true" level="top" onclick="this.hidePopup();"
+           flip="slide">
       <hbox class="sync-panel-outer">
         <image class="sync-panel-icon"/>
         <vbox class="sync-panel-inner">
           <description id="sync-start-panel-title"
-                       value="&syncStartPanel.title;"/>
+                       value="&syncStartPanel.heading;"/>
           <description id="sync-start-panel-subtitle">
 #ifdef XP_UNIX
             &syncStartPanel.subTitleUnix;
 #else
             &syncStartPanel.subTitle;
 #endif
           </description>
         </vbox>
       </hbox>
     </panel>
 
     <!-- Sync Error Panel -->
     <panel id="sync-error-panel" class="sync-panel" type="arrow" hidden="true"
-           noautofocus="true" level="top" onclick="this.hidePopup();">
+           noautofocus="true" level="top" onclick="this.hidePopup();"
+           flip="slide">
       <hbox class="sync-panel-outer">
         <image class="sync-panel-icon"/>
         <vbox class="sync-panel-inner">
           <description id="sync-error-panel-title"
-                       value="&syncErrorPanel.title;"/>
+                       value="&syncErrorPanel.heading;"/>
           <description id="sync-error-panel-subtitle"
                        value="&syncErrorPanel.subTitle;"/>
           <hbox class="sync-panel-button-box">
-            <button class="sync-panel-button"
-#ifdef XP_UNIX
-                    label="&syncErrorPanel.prefButtonUnix.label;"
-                    accesskey="&syncErrorPanel.prefButtonUnix.accesskey;"
-#else
-                    label="&syncErrorPanel.prefButton.label;"
-                    accesskey="&syncErrorPanel.prefButton.accesskey;"
-#endif
-                    onclick="gFxAccounts.openPreferences();"/>
             <spacer flex="1"/>
             <button class="sync-panel-button"
                     label="&syncErrorPanel.signInButton.label;"
                     accesskey="&syncErrorPanel.signInButton.accesskey;"
-                    onclick="gFxAccounts.openSignInPage();"/>
+                    onclick="gFxAccounts.openSignInAgainPage();"/>
           </hbox>
         </vbox>
       </hbox>
     </panel>
 
     <!-- Bookmarks and history tooltip -->
     <tooltip id="bhTooltip"/>
 
--- a/browser/base/content/sync/customize.xul
+++ b/browser/base/content/sync/customize.xul
@@ -27,19 +27,19 @@
       <preference id="engine.passwords" name="services.sync.engine.passwords" type="bool"/>
       <preference id="engine.addons"    name="services.sync.engine.addons"    type="bool"/>
       <preference id="engine.prefs"     name="services.sync.engine.prefs"     type="bool"/>
     </preferences>
 
     <label id="sync-customize-title" value="&syncCustomize.title;"/>
     <description id="sync-customize-subtitle"
 #ifdef XP_UNIX
-                 value="&syncCustomize.subTitleUnix;"
+                 value="&syncCustomizeUnix.description;"
 #else
-                 value="&syncCustomize.subTitle;"
+                 value="&syncCustomize.description;"
 #endif
                  />
 
     <checkbox label="&engine.bookmarks.label;"
               accesskey="&engine.bookmarks.accesskey;"
               preference="engine.bookmarks"/>
     <checkbox label="&engine.history.label;"
               accesskey="&engine.history.accesskey;"
--- a/browser/base/content/test/chrome/test_aboutCrashed.xul
+++ b/browser/base/content/test/chrome/test_aboutCrashed.xul
@@ -60,26 +60,26 @@
       let errorPageReady = waitForErrorPage(frame1);
       frame1.docShell.chromeEventHandler.setAttribute("crashedPageTitle", "pageTitle");
       frame1.docShell.displayLoadError(Components.results.NS_ERROR_CONTENT_CRASHED, uri1, null);
 
       yield errorPageReady;
       frame1.docShell.chromeEventHandler.removeAttribute("crashedPageTitle");
 
       SimpleTest.is(frame1.contentDocument.documentURI,
-                    "about:tabcrashed?e=tabcrashed&u=http%3A//www.example.com/1&c=UTF-8&d=pageTitle",
+                    "about:tabcrashed?e=tabcrashed&u=http%3A//www.example.com/1&c=UTF-8&d=pageTitle&f=regular",
                     "Correct about:tabcrashed displayed for page with title.");
 
       errorPageReady = waitForErrorPage(frame2);
       frame2.docShell.displayLoadError(Components.results.NS_ERROR_CONTENT_CRASHED, uri2, null);
 
       yield errorPageReady;
 
       SimpleTest.is(frame2.contentDocument.documentURI,
-                    "about:tabcrashed?e=tabcrashed&u=http%3A//www.example.com/2&c=UTF-8&d=%20",
+                    "about:tabcrashed?e=tabcrashed&u=http%3A//www.example.com/2&c=UTF-8&d=%20&f=regular",
                     "Correct about:tabcrashed displayed for page with no title.");
 
       SimpleTest.finish();
   });
   }
   ]]></script>
 
   <body xmlns="http://www.w3.org/1999/xhtml" style="height: 300px; overflow: auto;" />
--- a/browser/base/content/test/general/browser_aboutAccounts.js
+++ b/browser/base/content/test/general/browser_aboutAccounts.js
@@ -6,27 +6,25 @@ XPCOMUtils.defineLazyModuleGetter(this, 
   "resource://gre/modules/Promise.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "Task",
   "resource://gre/modules/Task.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "fxAccounts",
   "resource://gre/modules/FxAccounts.jsm");
 
 registerCleanupFunction(function() {
   // Ensure we don't pollute prefs for next tests.
-  Services.prefs.clearUserPref("identity.fxaccounts.enabled");
   Services.prefs.clearUserPref("identity.fxaccounts.remote.uri");
 });
 
 let gTests = [
 
 {
   desc: "Test the remote commands",
   setup: function ()
   {
-    Services.prefs.setBoolPref("identity.fxaccounts.enabled", true);
     Services.prefs.setCharPref("identity.fxaccounts.remote.uri",
                                "https://example.com/browser/browser/base/content/test/general/accounts_testRemoteCommands.html");
   },
   run: function ()
   {
     let deferred = Promise.defer();
 
     let results = 0;
--- a/browser/base/jar.mn
+++ b/browser/base/jar.mn
@@ -45,25 +45,28 @@ browser.jar:
         content/browser/abouthome/restore@2x.png       (content/abouthome/restore@2x.png)
         content/browser/abouthome/restore-large@2x.png (content/abouthome/restore-large@2x.png)
         content/browser/abouthome/mozilla@2x.png       (content/abouthome/mozilla@2x.png)
 #ifdef MOZ_SERVICES_HEALTHREPORT
         content/browser/abouthealthreport/abouthealth.xhtml   (content/abouthealthreport/abouthealth.xhtml)
         content/browser/abouthealthreport/abouthealth.js      (content/abouthealthreport/abouthealth.js)
         content/browser/abouthealthreport/abouthealth.css     (content/abouthealthreport/abouthealth.css)
 #endif
-        content/browser/aboutaccounts/aboutaccounts.xhtml   (content/aboutaccounts/aboutaccounts.xhtml)
-        content/browser/aboutaccounts/aboutaccounts.js      (content/aboutaccounts/aboutaccounts.js)
-        content/browser/aboutaccounts/aboutaccounts.css     (content/aboutaccounts/aboutaccounts.css)
-        content/browser/aboutaccounts/main.css              (content/aboutaccounts/main.css)
-        content/browser/aboutaccounts/normalize.css         (content/aboutaccounts/normalize.css)
-        content/browser/aboutaccounts/fonts.css             (content/aboutaccounts/fonts.css)
-        content/browser/aboutaccounts/images/fox.png             (content/aboutaccounts/images/fox.png)
-        content/browser/aboutaccounts/images/graphic_sync_intro.png             (content/aboutaccounts/images/graphic_sync_intro.png)
-        content/browser/aboutaccounts/images/graphic_sync_intro@2x.png             (content/aboutaccounts/images/graphic_sync_intro@2x.png)
+        content/browser/aboutaccounts/aboutaccounts.xhtml                     (content/aboutaccounts/aboutaccounts.xhtml)
+        content/browser/aboutaccounts/aboutaccounts.js                        (content/aboutaccounts/aboutaccounts.js)
+        content/browser/aboutaccounts/aboutaccounts.css                       (content/aboutaccounts/aboutaccounts.css)
+        content/browser/aboutaccounts/main.css                                (content/aboutaccounts/main.css)
+        content/browser/aboutaccounts/normalize.css                           (content/aboutaccounts/normalize.css)
+        content/browser/aboutaccounts/fonts.css                               (content/aboutaccounts/fonts.css)
+        content/browser/aboutaccounts/fonts/clearsans-regular.woff            (content/aboutaccounts/fonts/clearsans-regular.woff)
+        content/browser/aboutaccounts/fonts/firasans-light.woff               (content/aboutaccounts/fonts/firasans-light.woff)
+        content/browser/aboutaccounts/fonts/firasans-regular.woff             (content/aboutaccounts/fonts/firasans-regular.woff)
+        content/browser/aboutaccounts/images/fox.png                          (content/aboutaccounts/images/fox.png)
+        content/browser/aboutaccounts/images/graphic_sync_intro.png           (content/aboutaccounts/images/graphic_sync_intro.png)
+        content/browser/aboutaccounts/images/graphic_sync_intro@2x.png        (content/aboutaccounts/images/graphic_sync_intro@2x.png)
 
         content/browser/aboutRobots-icon.png          (content/aboutRobots-icon.png)
         content/browser/aboutRobots-widget-left.png   (content/aboutRobots-widget-left.png)
         content/browser/aboutSocialError.xhtml        (content/aboutSocialError.xhtml)
         content/browser/aboutTabCrashed.js            (content/aboutTabCrashed.js)
         content/browser/aboutTabCrashed.xhtml         (content/aboutTabCrashed.xhtml)
 *       content/browser/browser.css                   (content/browser.css)
 *       content/browser/browser.js                    (content/browser.js)
--- a/browser/components/customizableui/content/panelUI.inc.xul
+++ b/browser/components/customizableui/content/panelUI.inc.xul
@@ -13,17 +13,17 @@
       <vbox id="PanelUI-contents-scroller">
         <vbox id="PanelUI-contents" class="panelUI-grid"/>
       </vbox>
 
       <footer id="PanelUI-footer">
         <toolbarbutton id="PanelUI-fxa-status"
                        defaultlabel="&fxaSignIn.label;"
                        errorlabel="&fxaSignInError.label;"
-                       oncommand="gFxAccounts.toggle(event);"
+                       oncommand="gFxAccounts.onMenuPanelCommand(event);"
                        hidden="true"/>
 
         <hbox id="PanelUI-footer-inner">
           <toolbarbutton id="PanelUI-customize" label="&appMenuCustomize.label;"
                          exitLabel="&appMenuCustomizeExit.label;"
                          tooltiptext="&appMenuCustomize.tooltip;"
                          exitTooltiptext="&appMenuCustomizeExit.tooltip;"
                          closemenu="none"
@@ -83,18 +83,18 @@
                      class="panel-subview-footer subviewbutton"
                      label="&appMenuHistory.showAll.label;"
                      oncommand="PlacesCommandHook.showPlacesOrganizer('History'); CustomizableUI.hidePanelForNode(this);"/>
     </panelview>
 
     <panelview id="PanelUI-bookmarks" flex="1" class="PanelUI-subView">
       <label value="&bookmarksMenu.label;" class="panel-subview-header"/>
       <toolbarbutton id="panelMenuBookmarkThisPage"
-                     label="&bookmarkThisPageCmd.label;"
                      class="subviewbutton"
+                     observes="bookmarkThisPageBroadcaster"
                      command="Browser:AddBookmarkAs"
                      onclick="PanelUI.hide();"/>
       <toolbarseparator/>
       <toolbarbutton id="panelMenu_viewBookmarksSidebar"
                      label="&viewBookmarksSidebar2.label;"
                      class="subviewbutton"
                      oncommand="toggleSidebar('viewBookmarksSidebar'); PanelUI.hide();">
         <observes element="viewBookmarksSidebar" attribute="checked"/>
--- a/browser/components/preferences/sync.js
+++ b/browser/components/preferences/sync.js
@@ -251,18 +251,22 @@ let gSyncPane = {
       gSyncUtils._openLink(url);
       return;
     }
     win.switchToTabHavingURI(url, true);
     // seeing as we are doing this in a tab we close the prefs dialog.
     window.close();
   },
 
+  signIn: function() {
+    this.openContentInBrowser("about:accounts?action=signin");
+  },
+
   reSignIn: function() {
-    this.openContentInBrowser("about:accounts");
+    this.openContentInBrowser("about:accounts?action=reauth");
   },
 
   manageFirefoxAccount: function() {
     let url = Services.prefs.getCharPref("identity.fxaccounts.settings.uri");
     this.openContentInBrowser(url);
   },
 
   verifyFirefoxAccount: function() {
@@ -285,27 +289,29 @@ let gSyncPane = {
     this.openContentInBrowser(url);
   },
 
   unlinkFirefoxAccount: function(confirm) {
     if (confirm) {
       // We use a string bundle shared with aboutAccounts.
       let sb = Services.strings.createBundle("chrome://browser/locale/syncSetup.properties");
       let continueLabel = sb.GetStringFromName("continue.label");
-      let title = sb.GetStringFromName("unlink.verify.title");
-      let body = sb.GetStringFromName("unlink.verify.heading") +
+      let title = sb.GetStringFromName("disconnect.verify.title");
+      let brandBundle = Services.strings.createBundle("chrome://branding/locale/brand.properties");
+      let brandShortName = brandBundle.GetStringFromName("brandShortName");
+      let body = sb.GetStringFromName("disconnect.verify.heading") +
                  "\n\n" +
-                 sb.GetStringFromName("unlink.verify.description");
+                 sb.formatStringFromName("disconnect.verify.description",
+                                         [brandShortName], 1);
       let ps = Services.prompt;
       let buttonFlags = (ps.BUTTON_POS_0 * ps.BUTTON_TITLE_IS_STRING) +
                         (ps.BUTTON_POS_1 * ps.BUTTON_TITLE_CANCEL) +
                         ps.BUTTON_POS_1_DEFAULT;
       let pressed = Services.prompt.confirmEx(window, title, body, buttonFlags,
-                                         continueLabel, null, null, null,
-                                         {});
+                                              continueLabel, null, null, null, {});
       if (pressed != 0) { // 0 is the "continue" button
         return;
       }
     }
     Components.utils.import('resource://gre/modules/FxAccounts.jsm');
     fxAccounts.signOut().then(() => {
       this.updateWeavePrefs();
     });
--- a/browser/components/preferences/sync.xul
+++ b/browser/components/preferences/sync.xul
@@ -183,41 +183,44 @@
           <spacer flex="1"/>
           <p>&determiningStatus.label;</p>
           <spacer flex="1"/>
         </vbox>
 
         <vbox id="noFxaAccount">
           <description>&welcome.description;</description>
           <label class="text-link"
-                 onclick="gSyncPane.openContentInBrowser('about:accounts?signin=true'); return false;"
-                 value="&welcome.startButton.label;"/>
+                 onclick="gSyncPane.signIn(); return false;"
+                 value="&welcome.createAccount.label;"/>
+          <label class="text-link"
+                 onclick="gSyncPane.signIn(); return false;"
+                 value="&welcome.signIn.label;"/>
           <spacer flex="1"/>
           <label class="text-link"
                  onclick="gSyncPane.openOldSyncSupportPage(); return false;"
                  value="&welcome.useOldSync.label;"/>
           <spacer flex="10"/>
         </vbox>
 
         <vbox id="hasFxaAccount">
           <groupbox id="fxaGroup">
-            <caption label="&syncBrand.fxa-singular.label;"/>
+            <caption label="&syncBrand.fxAccount.label;"/>
 
             <deck id="fxaLoginStatus">
 
               <!-- logged in and verified and all is good -->
               <hbox flex="1">
                 <label id="fxaEmailAddress1"/>
                 <label class="text-link"
                        onclick="gSyncPane.manageFirefoxAccount();"
                        value="&manage.label;"/>
                 <spacer flex="1"/>
                 <vbox align="end">
                   <button onclick="gSyncPane.unlinkFirefoxAccount(true);"
-                          label="&unlink.label;" />
+                          label="&disconnect.label;" />
                 </vbox>
               </hbox>
 
               <!-- logged in to an unverified account -->
               <hbox flex="1">
                 <description>
                   &signedInUnverified.beforename.label;
                   <span id="fxaEmailAddress2"></span>
--- a/browser/devtools/sourceeditor/autocomplete.js
+++ b/browser/devtools/sourceeditor/autocomplete.js
@@ -40,16 +40,32 @@ function setupAutoCompletion(ctx, walker
     "Shift-Tab": cm => {
       if (popup && popup.isOpen) {
         cycleSuggestions(ed, true);
         return;
       }
 
       return win.CodeMirror.Pass;
     },
+    "Up": cm => {
+      if (popup && popup.isOpen) {
+        cycleSuggestions(ed, true);
+        return;
+      }
+
+      return win.CodeMirror.Pass;
+    },
+    "Down": cm => {
+      if (popup && popup.isOpen) {
+        cycleSuggestions(ed);
+        return;
+      }
+
+      return win.CodeMirror.Pass;
+    },
   };
   keyMap[Editor.accel("Space")] = cm => autoComplete(ctx);
   cm.addKeyMap(keyMap);
 
   cm.on("keydown", (cm, e) => onEditorKeypress(ed, e));
   ed.on("change", () => autoComplete(ctx));
   ed.on("destroy", () => {
     cm.off("keydown", (cm, e) => onEditorKeypress(ed, e));
@@ -142,27 +158,27 @@ function cycleSuggestions(ed, reverse) {
 
 /**
  * onkeydown handler for the editor instance to prevent autocompleting on some
  * keypresses.
  */
 function onEditorKeypress(ed, event) {
   let private = privates.get(ed);
   switch (event.keyCode) {
-    case event.DOM_VK_UP:
-    case event.DOM_VK_DOWN:
+    case event.DOM_VK_ESCAPE:
+      if (private.popup.isOpen)
+        event.preventDefault();
     case event.DOM_VK_LEFT:
     case event.DOM_VK_RIGHT:
     case event.DOM_VK_HOME:
     case event.DOM_VK_END:
     case event.DOM_VK_BACK_SPACE:
     case event.DOM_VK_DELETE:
     case event.DOM_VK_ENTER:
     case event.DOM_VK_RETURN:
-    case event.DOM_VK_ESCAPE:
       private.doNotAutocomplete = true;
       private.popup.hidePopup();
       break;
 
     default:
       private.doNotAutocomplete = false;
   }
 }
--- a/browser/devtools/styleeditor/test/browser_styleeditor_autocomplete.js
+++ b/browser/devtools/styleeditor/test/browser_styleeditor_autocomplete.js
@@ -17,33 +17,39 @@ const AUTOCOMPLETION_PREF = "devtools.st
 //   1 to check whether the selected suggestion is inserted into the editor or not
 // ]
 let TEST_CASES = [
   ['VK_RIGHT', -1],
   ['VK_RIGHT', -1],
   ['VK_RIGHT', -1],
   ['VK_RIGHT', -1],
   [-1, 1, 0],
+  ['VK_LEFT', -1],
+  ['VK_RIGHT', -1],
   ['VK_DOWN', -1],
   ['VK_RIGHT', -1],
   ['VK_RIGHT', -1],
   ['VK_RIGHT', -1],
   [-1, MAX_SUGGESTIONS, 0],
   ['VK_END', -1],
   ['VK_RETURN', -1],
   ['b', MAX_SUGGESTIONS, 0],
   ['a', 11, 0],
-  ['VK_TAB', 11, 0, 1],
+  ['VK_DOWN', 11, 0, 1],
   ['VK_TAB', 11, 1, 1],
   [':', -1],
   ['b', 9, 0],
   ['l', 4, 0],
   ['VK_TAB', 4, 0, 1],
+  ['VK_DOWN', 4, 1, 1],
+  ['VK_UP', 4, 0, 1],
   ['VK_TAB', 4, 1, 1],
   ['VK_TAB', 4, 2, 1],
+  ['VK_LEFT', -1],
+  ['VK_RIGHT', -1],
   ['VK_DOWN', -1],
   ['VK_RETURN', -1],
   ['b', 2, 0],
   ['u', 1, 0],
   ['VK_TAB', -1],
   ['{', -1],
   ['VK_HOME', -1],
   ['VK_DOWN', -1],
@@ -97,22 +103,23 @@ function testState() {
 
   if (key == -1) {
     info("pressing Ctrl + Space to get result: [" + TEST_CASES[index] +
          "] for index " + index);
     gEditor.once("after-suggest", checkState);
     key = " ";
     mods.accelKey = true;
   }
-  else if (/(down|left|right|return|home|end)/ig.test(key)) {
+  else if (/(left|right|return|home|end)/ig.test(key) ||
+           (key == "VK_DOWN" && !gPopup.isOpen)) {
     info("pressing key " + key + " to get result: [" + TEST_CASES[index] +
          "] for index " + index);
     gEditor.once("cursorActivity", checkState);
   }
-  else if (key == "VK_TAB") {
+  else if (key == "VK_TAB" || key == "VK_UP" || key == "VK_DOWN") {
     info("pressing key " + key + " to get result: [" + TEST_CASES[index] +
          "] for index " + index);
     gEditor.once("suggestion-entered", checkState);
   }
   else {
     info("pressing key " + key + " to get result: [" + TEST_CASES[index] +
          "] for index " + index);
     gEditor.once("after-suggest", checkState);
@@ -134,18 +141,17 @@ function checkState() {
         let { preLabel, label } = gPopup.getItemAtIndex(current);
         let { line, ch } = gEditor.getCursor();
         let lineText = gEditor.getText(line);
         is(lineText.substring(ch - label.length, ch), label,
            "Current suggestion from the popup is inserted into the editor.");
       }
     }
     else {
-      ok(gPopup._panel.state != "open" && gPopup._panel.state != "showing",
-         "Popup is closed for index " + index);
+      ok(!gPopup.isOpen, "Popup is closed for index " + index);
     }
     index++;
     testState();
   });
 }
 
 function testAutocompletionDisabled() {
   gBrowser.removeCurrentTab();
--- a/browser/locales/en-US/chrome/browser/aboutAccounts.dtd
+++ b/browser/locales/en-US/chrome/browser/aboutAccounts.dtd
@@ -1,9 +1,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/. -->
 
-<!ENTITY aboutAccounts.pageTitle "Welcome to Sync">
+<!ENTITY aboutAccounts.welcome "Welcome to &syncBrand.shortName.label;">
 
 <!ENTITY aboutAccountsConfig.description "Sign in to sync your tabs, bookmarks, passwords &amp; more.">
 <!ENTITY aboutAccountsConfig.startButton.label "Get started">
 <!ENTITY aboutAccountsConfig.useOldSync.label "Using an older version of Sync?">
+<!ENTITY aboutAccountsConfig.manage.label "Manage">
--- a/browser/locales/en-US/chrome/browser/browser.dtd
+++ b/browser/locales/en-US/chrome/browser/browser.dtd
@@ -93,25 +93,21 @@ These should match what Safari and other
 <!ENTITY fullScreenCmd.label "Full Screen">
 <!ENTITY fullScreenCmd.accesskey "F">
 <!ENTITY fullScreenCmd.macCommandKey "f">
 <!ENTITY showAllTabsCmd.label "Show All Tabs">
 <!ENTITY showAllTabsCmd.accesskey "A">
 
 <!ENTITY fxaSignIn.label "Sign in to &syncBrand.shortName.label;">
 <!ENTITY fxaSignInError.label "Reconnect to &syncBrand.shortName.label;">
-<!ENTITY syncStartPanel.title "&brandShortName; is now syncing.">
+<!ENTITY syncStartPanel.heading "&brandShortName; is now syncing">
 <!ENTITY syncStartPanel.subTitle "You can manage &syncBrand.shortName.label; in Options.">
 <!ENTITY syncStartPanel.subTitleUnix "You can manage &syncBrand.shortName.label; in Preferences.">
-<!ENTITY syncErrorPanel.title "Cannot connect to &syncBrand.shortName.label;">
+<!ENTITY syncErrorPanel.heading "Cannot connect to &syncBrand.shortName.label;">
 <!ENTITY syncErrorPanel.subTitle "Please sign in to resume syncing.">
-<!ENTITY syncErrorPanel.prefButton.label "Options">
-<!ENTITY syncErrorPanel.prefButton.accesskey "O">
-<!ENTITY syncErrorPanel.prefButtonUnix.label "Preferences">
-<!ENTITY syncErrorPanel.prefButtonUnix.accesskey "P">
 <!ENTITY syncErrorPanel.signInButton.label "Sign In">
 <!ENTITY syncErrorPanel.signInButton.accesskey "S">
 
 
 <!ENTITY fullScreenMinimize.tooltip "Minimize">
 <!ENTITY fullScreenRestore.tooltip "Restore">
 <!ENTITY fullScreenClose.tooltip "Close">
 <!ENTITY fullScreenAutohide.label "Hide Toolbars">
@@ -126,16 +122,17 @@ These should match what Safari and other
 <!ENTITY leaveDOMFullScreen.accesskey "u">
 
 <!ENTITY closeWindow.label "Close Window">
 <!ENTITY closeWindow.accesskey "d">
 
 <!ENTITY bookmarksMenu.label "Bookmarks">
 <!ENTITY bookmarksMenu.accesskey "B">
 <!ENTITY bookmarkThisPageCmd.label "Bookmark This Page">
+<!ENTITY editThisBookmarkCmd.label "Edit This Bookmark">
 <!ENTITY bookmarkThisPageCmd.commandkey "d">
 <!ENTITY markPageCmd.commandkey "l">
 <!ENTITY sharePageCmd.label "Share This Page">
 <!ENTITY sharePageCmd.commandkey "S">
 <!ENTITY sharePageCmd.accesskey "s">
 <!ENTITY shareLinkCmd.label "Share This Link">
 <!ENTITY shareLinkCmd.accesskey "s">
 <!ENTITY shareImageCmd.label "Share This Image">
--- a/browser/locales/en-US/chrome/browser/browser.properties
+++ b/browser/locales/en-US/chrome/browser/browser.properties
@@ -235,16 +235,17 @@ refreshBlocked.redirectLabel=%S prevente
 # General bookmarks button
 # LOCALIZATION NOTE (bookmarksMenuButton.tooltip):
 # %S is the keyboard shortcut for "Show All Bookmarks"
 bookmarksMenuButton.tooltip=Show your bookmarks (%S)
 # Star button
 starButtonOn.tooltip=Edit this bookmark
 starButtonOff.tooltip=Bookmark this page
 starButtonOverflowed.label=Bookmark This Page
+starButtonOverflowedStarred.label=Edit This Bookmark
 
 # Print button tooltip on OS X
 # LOCALIZATION NOTE (printButton.tooltip):
 # Use the unicode ellipsis char, \u2026,
 # or use "..." if \u2026 doesn't suit traditions in your locale.
 # %S is the keyboard shortcut for "Print"
 printButton.tooltip=Print this page… (%S)
 
--- a/browser/locales/en-US/chrome/browser/preferences/preferences.properties
+++ b/browser/locales/en-US/chrome/browser/preferences/preferences.properties
@@ -135,9 +135,9 @@ syncUnlinkConfirm.label=Unlink
 featureEnableRequiresRestart=%S must restart to enable this feature.
 featureDisableRequiresRestart=%S must restart to disable this feature.
 shouldRestartTitle=Restart %S
 
 ###Preferences::Sync::Firefox Accounts
 firefoxAccountsVerificationSentTitle=Verification Sent
 # LOCALIZATION NOTE: %S = user's email address.
 firefoxAccountsVerificationSentHeading=A verification link has been sent to %S
-firefoxAccountVerificationSentDescription=Please check your email and click the verification link to begin syncing.
+firefoxAccountVerificationSentDescription=Please check your email and click the link to begin syncing.
--- a/browser/locales/en-US/chrome/browser/preferences/sync.dtd
+++ b/browser/locales/en-US/chrome/browser/preferences/sync.dtd
@@ -43,25 +43,27 @@
 <!ENTITY unlinkDevice.label           "Unlink This Device">
 
 <!-- Footer stuff -->
 <!ENTITY prefs.tosLink.label        "Terms of Service">
 <!ENTITY prefs.ppLink.label         "Privacy Policy">
 
 <!-- Firefox Accounts stuff -->
 <!ENTITY fxaPrivacyNotice.link.label "Privacy Notice">
-<!ENTITY determiningStatus.label    "Determining your Firefox Account status…">
+<!ENTITY determiningStatus.label     "Determining your Firefox Account status…">
 <!ENTITY signedInUnverified.beforename.label "">
 <!ENTITY signedInUnverified.aftername.label "is not verified.">
 
 <!ENTITY signedInLoginFailure.beforename.label "Please sign in to reconnect">
 <!ENTITY signedInLoginFailure.aftername.label "">
 
 <!ENTITY notSignedIn.label           "You are not signed in.">
 <!ENTITY signIn.label                "Sign in">
 <!ENTITY manage.label                "Manage">
-<!ENTITY unlink.label                "Unlink this Browser…">
+<!ENTITY disconnect.label            "Disconnect…">
 <!ENTITY verify.label                "Verify Email">
 <!ENTITY forget.label                "Forget this Email">
 
 <!ENTITY welcome.description "Access your tabs, bookmarks, passwords and more wherever you use &brandShortName;.">
-<!ENTITY welcome.startButton.label "Sign in or Create an Account">
+<!ENTITY welcome.signIn.label "Sign In">
+<!ENTITY welcome.createAccount.label "Create Account">
+
 <!ENTITY welcome.useOldSync.label "Using an older version of Sync?">
--- a/browser/locales/en-US/chrome/browser/syncBrand.dtd
+++ b/browser/locales/en-US/chrome/browser/syncBrand.dtd
@@ -1,8 +1,7 @@
 <!-- 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/. -->
 
 <!ENTITY syncBrand.shortName.label  "Sync">
 <!ENTITY syncBrand.fullName.label   "Firefox Sync">
-<!ENTITY syncBrand.fxa-singular.label "Firefox Account">
-<!ENTITY syncBrand.fxa-plural.label "Firefox Accounts">
+<!ENTITY syncBrand.fxAccount.label  "Firefox Account">
--- a/browser/locales/en-US/chrome/browser/syncCustomize.dtd
+++ b/browser/locales/en-US/chrome/browser/syncCustomize.dtd
@@ -1,18 +1,18 @@
 <!-- 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/. -->
 
 <!ENTITY syncCustomize.dialog.title       "Sync Selection">
 <!ENTITY syncCustomize.acceptButton.label "Start">
 
 <!ENTITY syncCustomize.title              "What would you like to sync?">
-<!ENTITY syncCustomize.subTitle           "You can manage this selection in Options.">
-<!ENTITY syncCustomize.subTitleUnix       "You can manage this selection in Preferences.">
+<!ENTITY syncCustomize.description        "You can change this selection in Options.">
+<!ENTITY syncCustomizeUnix.description    "You can change this selection in Preferences.">
 
 <!--
   These engine names are the same as in browser/preferences/sync.dtd except
   for the last two that are marked as being specific to Desktop browsers.
 -->
 <!ENTITY engine.bookmarks.label           "Bookmarks">
 <!ENTITY engine.bookmarks.accesskey       "m">
 <!ENTITY engine.history.label             "History">
--- a/browser/locales/en-US/chrome/browser/syncSetup.properties
+++ b/browser/locales/en-US/chrome/browser/syncSetup.properties
@@ -47,19 +47,20 @@ wipeClient.change2.label = Firefox Sync 
 wipeRemote.change2.label = Firefox Sync will now replace all of the browser data in your Sync account with the data on this device.
 existingAccount.change.label = You can change this preference by selecting Sync Options below.
 
 # Several other strings are used (via Weave.Status.login), but they come from
 #  /services/sync
 
 # Firefox Accounts based setup.
 continue.label = Continue
-unlink.verify.title = Unlink Browser
-unlink.verify.heading = Are you sure?
-unlink.verify.description = This browser will stop syncing with your other computers, but won't delete any of your local browsing data.
+disconnect.verify.title = Disconnect
+disconnect.verify.heading = Are you sure?
+# LOCALIZATION NOTE (disconnect.verify.description): %S will be replaced with
+# brandShortName
+disconnect.verify.description = %S will stop syncing with your account, but won’t delete any of your browsing data on this computer.
 
-relink.verify.title = Merge Warning
-relink.verify.heading = Are you sure you want to sign in to Sync?
-# LOCALIZATION NOTE (relink.verify.description): Email address of a user previously signed into sync.
-relink.verify.description = A different user was previously signed in to Sync on this device. Signing in will merge this browser's bookmarks, passwords and other settings with %S
-
+relinkVerify.title = Merge Warning
+relinkVerify.heading = Are you sure you want to sign in to Sync?
+# LOCALIZATION NOTE (relinkVerify.description): Email address of a user previously signed into sync.
+relinkVerify.description = A different user was previously signed in to Sync on this computer. Signing in will merge this browser’s bookmarks, passwords and other settings with %S
 
 manage.pageTitle = Manage Sync
--- a/browser/metro/base/content/startui/FirstRunOverlay.xul
+++ b/browser/metro/base/content/startui/FirstRunOverlay.xul
@@ -15,55 +15,56 @@
 
 <overlay id="firstrun"
          xmlns:html="http://www.w3.org/1999/xhtml"
          xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
 
   <hbox id="start-container">
     <box id="instruction-topsites-box" insertafter="start-topsites" class="firstrun">
       <box id="instruction-topsites">
-        <vbox align="center">
+        <vbox class="instruction-content-container">
+          <image class="instruction-arrow arrow-left-straight" />
           <image class="instruction-arrow arrow-left" />
-          <label class="instruction-label" value="&firstRunTopSites.label;"/>
+          <label class="instruction-label">&firstRunTopSites.label;</label>
         </vbox>
       </box>
     </box>
 
     <vbox id="firstrun-welcome" insertafter="instruction-topsites-box" class="firstrun" align="center" pack="center">
       <image class="welcome-image" />
       <label class="welcome-title" value="&firstRunWelcome.label;"/>
       <label class="welcome-subtitle" value="&firstRunDifferent.label;"/>
     </vbox>
 
     <box insertafter="start-bookmarks" class="firstrun">
       <box id="instruction-bookmarks">
-        <vbox align="center">
+        <vbox class="instruction-content-container" align="center">
           <image class="instruction-arrow arrow-right" />
-          <label class="instruction-label" value="&firstRunBookmarks.label;"/>
+          <label class="instruction-label">&firstRunBookmarks.label;</label>
         </vbox>
       </box>
     </box>
 
     <box id="instruction-history-container" insertafter="start-history" class="firstrun">
       <box id="instruction-history">
-        <vbox align="center">
+        <vbox class="instruction-content-container" align="center">
           <image class="instruction-arrow arrow-right" />
-          <label class="instruction-label" value="&firstRunHistory.label;"/>
+          <label class="instruction-label">&firstRunHistory.label;</label>
         </vbox>
       </box>
     </box>
 
     <box id="instruction-tabs" class="firstrun">
-      <vbox align="center">
+      <vbox class="instruction-content-container" align="center">
         <image class="instruction-arrow arrow-top" />
-        <label class="instruction-label" value="&firstRunTabs.label;"/>
+        <label class="instruction-label">&firstRunTabs.label;</label>
       </vbox>
     </box>
 
     <box id="instruction-menu" class="firstrun">
-      <hbox>
-        <label class="instruction-label" value="&firstRunMenu.label;"/>
+      <hbox class="instruction-content-container" align="right">
+        <label class="instruction-label">&firstRunMenu.label;</label>
         <image class="instruction-arrow arrow-down" />
       </hbox>
     </box>
 
  </hbox>
 </overlay>
\ No newline at end of file
--- a/browser/metro/shell/commandexecutehandler/CommandExecuteHandler.cpp
+++ b/browser/metro/shell/commandexecutehandler/CommandExecuteHandler.cpp
@@ -98,16 +98,17 @@ public:
     mRequestType(DEFAULT_LAUNCH),
     mRequestMet(false),
     mDelayedLaunchType(NONE),
     mVerb(L"open")
   {
   }
 
   bool RequestMet() { return mRequestMet; }
+  void SetRequestMet();
   long RefCount() { return mRef; }
   void HeartBeat();
 
   // IUnknown
   IFACEMETHODIMP QueryInterface(REFIID aRefID, void **aInt)
   {
     static const QITAB qit[] = {
       QITABENT(CExecuteCommandVerb, IExecuteCommand),
@@ -381,18 +382,16 @@ public:
     CStringW browserPath;
     GetDefaultBrowserPath(browserPath);
 
     return !selfPath.CompareNoCase(browserPath);
   }
 private:
   ~CExecuteCommandVerb()
   {
-    SafeRelease(&mShellItemArray);
-    SafeRelease(&mUnkSite);
   }
 
   void LaunchDesktopBrowser();
   bool LaunchMetroBrowser();
   bool SetTargetPath(IShellItem* aItem);
   bool TestForUpdateLock();
 
   /*
@@ -660,22 +659,22 @@ CExecuteCommandVerb::LaunchDesktopBrowse
 
 void
 CExecuteCommandVerb::HeartBeat()
 {
   if (mRequestType == METRO_UPDATE && mDelayedLaunchType == DESKTOP &&
       !IsMetroProcessRunning()) {
     mDelayedLaunchType = NONE;
     LaunchDesktopBrowser();
-    mRequestMet = true;
+    SetRequestMet();
   }
   if (mDelayedLaunchType == METRO && !TestForUpdateLock()) {
     mDelayedLaunchType = NONE;
     LaunchMetroBrowser();
-    mRequestMet = true;
+    SetRequestMet();
   }
 }
 
 static bool
 PrepareActivationManager(CComPtr<IApplicationActivationManager> &activateMgr)
 {
   HRESULT hr = activateMgr.CoCreateInstance(CLSID_ApplicationActivationManager,
                                             nullptr, CLSCTX_LOCAL_SERVER);
@@ -743,33 +742,31 @@ CExecuteCommandVerb::LaunchMetroBrowser(
   // protocols
   } else {
     hr = activateMgr->ActivateForProtocol(appModelID, mShellItemArray, &processID);
     Log(L"ActivateForProtocol result %X", hr);
   }
   return true;
 }
 
-class AutoSetRequestMet
+void CExecuteCommandVerb::SetRequestMet()
 {
-public:
-  explicit AutoSetRequestMet(bool* aFlag) :
-    mFlag(aFlag) {}
-  ~AutoSetRequestMet() { if (mFlag) *mFlag = true; }
-private:
-  bool* mFlag;
-};
+  SafeRelease(&mShellItemArray);
+  SafeRelease(&mUnkSite);
+  mRequestMet = true;
+  Log(L"Request met, exiting.");
+}
 
 IFACEMETHODIMP CExecuteCommandVerb::Execute()
 {
   Log(L"Execute()");
 
   if (!mTarget.GetLength()) {
     // We shut down when this flips to true
-    mRequestMet = true;
+    SetRequestMet();
     return E_FAIL;
   }
 
   // Deal with metro restart for an update - launch desktop with a command
   // that tells it to run updater then launch the metro browser.
   if (mRequestType == METRO_UPDATE) {
     // We'll complete this in the heart beat callback from the main msg loop.
     // We do this because the last browser instance makes this call to Execute
@@ -779,29 +776,29 @@ IFACEMETHODIMP CExecuteCommandVerb::Exec
     mDelayedLaunchType = DESKTOP;
     return S_OK;
   }
 
   // Launch on the desktop
   if (mRequestType == DESKTOP_RESTART ||
       (mRequestType == DEFAULT_LAUNCH && DefaultLaunchIsDesktop())) {
     LaunchDesktopBrowser();
-    mRequestMet = true;
+    SetRequestMet();
     return S_OK;
   }
 
   // If we have an update in the works, don't try to activate yet,
   // delay until the lock is removed.
   if (TestForUpdateLock()) {
     mDelayedLaunchType = METRO;
     return S_OK;
   }
 
   LaunchMetroBrowser();
-  mRequestMet = true;
+  SetRequestMet();
   return S_OK;
 }
 
 class ClassFactory : public IClassFactory 
 {
 public:
   ClassFactory(IUnknown *punkObject);
   ~ClassFactory();
--- a/browser/metro/theme/firstrun.css
+++ b/browser/metro/theme/firstrun.css
@@ -68,16 +68,20 @@ below instruction */
   font-size: 16px;
   color: #808080;
   line-height: 22px;
   padding-top: 10px;
 }
 
 /* Instructions ---------------------- */
 
+.instruction-content-container {
+    width: 380px;
+}
+
 .instruction-label {
   font-size: 16px;
   color: #808080;
   line-height: 22px;
 }
 
 .instruction-arrow {
   width: 76px;
@@ -89,69 +93,106 @@ below instruction */
   background-image: url("chrome://browser/skin/images/arrow-top.png");
 }
 
 .instruction-arrow.arrow-down {
   transform: rotate(180deg);
 }
 
 .instruction-arrow.arrow-left,
-.instruction-arrow.arrow-right {
+.instruction-arrow.arrow-right,
+.instruction-arrow.arrow-left-straight,
+.instruction-arrow.arrow-right-straight {
   background-image: url("chrome://browser/skin/images/arrow-left.png");
 }
 
 .instruction-arrow.arrow-right {
   transform: rotate(180deg) scaleY(-1);
 }
 
+.instruction-arrow.arrow-left-straight {
+  transform: rotate(220deg) scaleX(-1);
+}
+
+.instruction-arrow.arrow-right-straight {
+  transform: rotate(-220deg);
+}
+
 #instruction-tabs {
   position: absolute;
   top: 10px;
   transform: translateX(calc(630px - 50%));
 }
 
 #start-container[viewstate="portrait"] #instruction-tabs {
   transform: translateX(calc(50vw - 50%));
 }
 
 #start-container[viewstate="landscape"] #instruction-topsites {
   position: absolute;
-  bottom: 20px;
-  transform: translateX(-50%);
-  margin-left: 20px;
+  bottom: 15%;
+}
+
+#start-container[viewstate="landscape"] #instruction-topsites .instruction-content-container {
+  -moz-box-align: start;
+}
+
+#start-container[viewstate="portrait"] #instruction-topsites-box {
+  margin-bottom: 20px;
+}
+
+#start-container[viewstate="portrait"] #instruction-topsites .instruction-content-container {
+  -moz-box-align: center;
 }
 
-#start-container[viewstate="portrait"] #instruction-topsites {
-  transform: translateX(calc(150px + 50%)) translateY(-60px);
+#start-container[viewstate="portrait"] #instruction-topsites .arrow-left-straight {
+  display: none;
+}
+
+#start-container[viewstate="portrait"] #instruction-topsites .arrow-left {
+  display: block;
+}
+
+#start-container[viewstate="landscape"] #instruction-topsites .arrow-left-straight {
+  display: block;
+}
+
+#start-container[viewstate="landscape"] #instruction-topsites .arrow-left {
+  display: none;
 }
 
 #start-container[viewstate="landscape"] #instruction-history,
 #start-container[viewstate="landscape"] #instruction-bookmarks {
   position: absolute;
   top: 310px;
   transform: translateX(calc(-300px - 50%));
 }
 
 #start-container[viewstate="portrait"] #instruction-history,
-#start-container[viewstate="portrait"] #instruction-bookmarks {
+#start-container[viewstate="portrait"] #instruction-bookmarks,
+#start-container[viewstate="portrait"] #instruction-topsites {
   transform: translateX(-55px);
 }
 
 #start-container[viewstate="landscape"] #instruction-menu {
   position: fixed;
   bottom: 16px;
   right: 37px;
 }
 
 #start-container[viewstate="portrait"] #instruction-menu {
   position: absolute;
   right: 37px;
   transform: translateY(40px);
 }
 
+#start-container #instruction-menu .instruction-label {
+    max-width: 300px;
+}
+
 #start-container[viewstate="landscape"] #start-history {
   padding-left: 50px;
 }
 
 /* Higher resolution images ---------------------- */
 
 @media (min-resolution: @min_res_140pc@) {
   /* Load 140% image when scaled by 140% */
--- a/browser/themes/linux/browser.css
+++ b/browser/themes/linux/browser.css
@@ -1677,35 +1677,32 @@ toolbarbutton.chevron > .toolbarbutton-i
   -moz-appearance: button;
   color: ButtonText;
   padding: 0 3px;
   margin-top: 10px;
 }
 
 /* Sync Panel */
 
-.sync-panel {
-  padding: 10px;
-}
-
 .sync-panel-icon {
   width: 32px;
   background: url("chrome://browser/content/abouthome/sync.png") top left no-repeat;
 }
 
 .sync-panel-inner {
   width: 0;
   padding-left: 10px;
 }
 
 .sync-panel-button-box {
   margin-top: 1em;
 }
 
-#sync-error-panel-title {
+#sync-error-panel-title,
+#sync-start-panel-title {
   font-weight: bold;
 }
 
 #sync-start-panel-subtitle,
 #sync-error-panel-subtitle {
   margin: 0;
 }
 
--- a/browser/themes/osx/browser.css
+++ b/browser/themes/osx/browser.css
@@ -957,20 +957,16 @@ toolbar .toolbarbutton-1:not([type="menu
     -moz-image-region: rect(0px, 256px, 64px, 192px);
   }
 
   #bookmarks-menu-button[cui-areatype="menu-panel"],
   toolbarpaletteitem[place="palette"] > #bookmarks-menu-button {
     -moz-image-region: rect(0px, 320px, 64px, 256px);
   }
 
-  #bookmarks-menu-button[starred][cui-areatype="menu-panel"] {
-    -moz-image-region: rect(0px, 384px, 64px, 320px);
-  }
-
   #history-panelmenu[cui-areatype="menu-panel"],
   toolbarpaletteitem[place="palette"] > #history-panelmenu {
     -moz-image-region: rect(0px, 448px, 64px, 384px);
   }
 
   #downloads-button[cui-areatype="menu-panel"],
   toolbarpaletteitem[place="palette"] > #downloads-button {
     -moz-image-region: rect(0px, 512px, 64px, 448px);
@@ -3596,20 +3592,16 @@ toolbarbutton.chevron > .toolbarbutton-m
 }
 
 #ctrlTab-showAll {
   margin-top: .5em;
 }
 
 /* Sync Panels */
 
-.sync-panel {
-  padding: 10px;
-}
-
 .sync-panel-icon {
   width: 32px;
   background: url("chrome://browser/content/abouthome/sync.png") top left no-repeat;
 }
 
 @media (min-resolution: 2dppx) {
   .sync-panel-icon {
     background: url("chrome://browser/content/abouthome/sync@2x.png") top left no-repeat;
@@ -3636,17 +3628,18 @@ toolbarbutton.chevron > .toolbarbutton-m
 .sync-panel-button:hover:active {
   @hudButtonPressed@
 }
 
 .sync-panel-button:-moz-focusring {
   @hudButtonFocused@
 }
 
-#sync-error-panel-title {
+#sync-error-panel-title,
+#sync-start-panel-title {
   font-weight: bold;
 }
 
 #sync-start-panel-subtitle,
 #sync-error-panel-subtitle {
   margin: 0;
 }
 
--- a/browser/themes/shared/menupanel.inc.css
+++ b/browser/themes/shared/menupanel.inc.css
@@ -10,20 +10,16 @@ toolbarpaletteitem[place="palette"] > #h
   -moz-image-region: rect(0px, 128px, 32px, 96px);
 }
 
 #bookmarks-menu-button[cui-areatype="menu-panel"],
 toolbarpaletteitem[place="palette"] > #bookmarks-menu-button {
   -moz-image-region: rect(0px, 160px, 32px, 128px);
 }
 
-#bookmarks-menu-button[starred][cui-areatype="menu-panel"] {
-  -moz-image-region: rect(0px, 192px, 32px, 160px);
-}
-
 #history-panelmenu[cui-areatype="menu-panel"],
 toolbarpaletteitem[place="palette"] > #history-panelmenu {
   -moz-image-region: rect(0px, 224px, 32px, 192px);
 }
 
 #downloads-button[cui-areatype="menu-panel"],
 toolbarpaletteitem[place="palette"] > #downloads-button {
   -moz-image-region: rect(0px, 256px, 32px, 224px);
--- a/browser/themes/windows/browser.css
+++ b/browser/themes/windows/browser.css
@@ -2139,35 +2139,32 @@ toolbarbutton.bookmark-item[dragover="tr
 }
 
 #ctrlTab-showAll {
   margin-top: .5em;
 }
 
 /* Sync Panel */
 
-.sync-panel {
-  padding: 10px;
-}
-
 .sync-panel-icon {
   width: 32px;
   background: url("chrome://browser/content/abouthome/sync.png") top left no-repeat;
 }
 
 .sync-panel-inner {
   width: 0;
   padding-left: 10px;
 }
 
 .sync-panel-button-box {
   margin-top: 1em;
 }
 
-#sync-error-panel-title {
+#sync-error-panel-title,
+#sync-start-panel-title {
   font-weight: bold;
 }
 
 #sync-start-panel-subtitle,
 #sync-error-panel-subtitle {
   margin: 0;
 }
 
--- a/content/base/src/CSPUtils.jsm
+++ b/content/base/src/CSPUtils.jsm
@@ -398,17 +398,17 @@ CSPRep.fromString = function(aStr, self,
           // parse failure.
           uri.host;
 
           // warn about, but do not prohibit non-http and non-https schemes for
           // reporting URIs.  The spec allows unrestricted URIs resolved
           // relative to "self", but we should let devs know if the scheme is
           // abnormal and may fail a POST.
           if (!uri.schemeIs("http") && !uri.schemeIs("https")) {
-            cspWarn(aCSPR, CSPLocalizer.getFormatStr("reportURInotHttpsOrHttp",
+            cspWarn(aCSPR, CSPLocalizer.getFormatStr("reportURInotHttpsOrHttp2",
                                                      [uri.asciiSpec]));
           }
         } catch(e) {
           switch (e.result) {
             case Components.results.NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS:
             case Components.results.NS_ERROR_HOST_IS_IP_ADDRESS:
               if (uri.host !== selfUri.host) {
                 cspWarn(aCSPR,
@@ -646,17 +646,17 @@ CSPRep.fromStringSpecCompliant = functio
           // parse failure.
           uri.host;
 
           // warn about, but do not prohibit non-http and non-https schemes for
           // reporting URIs.  The spec allows unrestricted URIs resolved
           // relative to "self", but we should let devs know if the scheme is
           // abnormal and may fail a POST.
           if (!uri.schemeIs("http") && !uri.schemeIs("https")) {
-            cspWarn(aCSPR, CSPLocalizer.getFormatStr("reportURInotHttpsOrHttp",
+            cspWarn(aCSPR, CSPLocalizer.getFormatStr("reportURInotHttpsOrHttp2",
                                                      [uri.asciiSpec]));
           }
         } catch(e) {
           switch (e.result) {
             case Components.results.NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS:
             case Components.results.NS_ERROR_HOST_IS_IP_ADDRESS:
               if (uri.host !== selfUri.host) {
                 cspWarn(aCSPR, CSPLocalizer.getFormatStr("pageCannotSendReportsTo",
--- a/content/media/encoder/fmp4_muxer/ISOControl.cpp
+++ b/content/media/encoder/fmp4_muxer/ISOControl.cpp
@@ -10,18 +10,16 @@
 #include "EncodedFrameContainer.h"
 
 namespace mozilla {
 
 // For MP4 creation_time and modification_time offset from January 1, 1904 to
 // January 1, 1970.
 #define iso_time_offset 2082844800
 
-const static uint32_t MUXING_BUFFER_SIZE = 512*1024;
-
 FragmentBuffer::FragmentBuffer(uint32_t aTrackType, uint32_t aFragDuration,
                                TrackMetadataBase* aMetadata)
   : mTrackType(aTrackType)
   , mFragDuration(aFragDuration)
   , mMediaStartTime(0)
   , mFragmentNumber(0)
   , mEOS(false)
 {
@@ -135,17 +133,18 @@ FragmentBuffer::GetFirstFragmentSampleSi
 ISOControl::ISOControl()
   : mAudioFragmentBuffer(nullptr)
   , mVideoFragmentBuffer(nullptr)
   , mFragNum(0)
   , mOutputSize(0)
   , mBitCount(0)
   , mBit(0)
 {
-  mOutBuffer.SetCapacity(MUXING_BUFFER_SIZE);
+  // Create a data array for first mp4 Box, ftyp.
+  mOutBuffers.SetLength(1);
   MOZ_COUNT_CTOR(ISOControl);
 }
 
 ISOControl::~ISOControl()
 {
   MOZ_COUNT_DTOR(ISOControl);
 }
 
@@ -245,32 +244,58 @@ ISOControl::GetFragment(uint32_t aType)
   } else if (aType == Video_Track){
     return mVideoFragmentBuffer;
   }
   MOZ_ASSERT(0);
   return nullptr;
 }
 
 nsresult
-ISOControl::GetBuf(nsTArray<uint8_t>& aOutBuf)
+ISOControl::GetBufs(nsTArray<nsTArray<uint8_t>>* aOutputBufs)
 {
-  mOutputSize += mOutBuffer.Length();
-  aOutBuf.SwapElements(mOutBuffer);
+  uint32_t len = mOutBuffers.Length();
+  for (uint32_t i = 0; i < len; i++) {
+    mOutBuffers[i].SwapElements(*aOutputBufs->AppendElement());
+    mOutputSize += mOutBuffers[i].Length();
+  }
   return FlushBuf();
 }
 
 nsresult
 ISOControl::FlushBuf()
 {
-  mOutBuffer.SetCapacity(MUXING_BUFFER_SIZE);
+  mOutBuffers.SetLength(1);
   mLastWrittenBoxPos = 0;
   return NS_OK;
 }
 
 uint32_t
+ISOControl::WriteAVData(nsTArray<uint8_t>& aArray)
+{
+  MOZ_ASSERT(!mBitCount);
+
+  uint32_t len = aArray.Length();
+  if (!len) {
+    return 0;
+  }
+
+  // The last element already has data, allocated a new element for pointer
+  // swapping.
+  if (mOutBuffers.LastElement().Length()) {
+    mOutBuffers.AppendElement();
+  }
+  // Swap the video/audio data pointer.
+  mOutBuffers.LastElement().SwapElements(aArray);
+  // Following data could be boxes, so appending a new uint8_t array here.
+  mOutBuffers.AppendElement();
+
+  return len;
+}
+
+uint32_t
 ISOControl::WriteBits(uint64_t aBits, size_t aNumBits)
 {
   uint8_t output_byte = 0;
 
   MOZ_ASSERT(aNumBits <= 64);
   // TODO: rewritten following with bitset?
   for (size_t i = aNumBits; i > 0; i--) {
     mBit |= (((aBits >> (i - 1)) & 1) << (8 - ++mBitCount));
@@ -282,29 +307,40 @@ ISOControl::WriteBits(uint64_t aBits, si
     }
   }
   return output_byte;
 }
 
 uint32_t
 ISOControl::Write(uint8_t* aBuf, uint32_t aSize)
 {
-  mOutBuffer.AppendElements(aBuf, aSize);
+  mOutBuffers.LastElement().AppendElements(aBuf, aSize);
   return aSize;
 }
 
 uint32_t
 ISOControl::Write(uint8_t aData)
 {
   MOZ_ASSERT(!mBitCount);
   Write((uint8_t*)&aData, sizeof(uint8_t));
   return sizeof(uint8_t);
 }
 
 uint32_t
+ISOControl::GetBufPos()
+{
+  uint32_t len = mOutBuffers.Length();
+  uint32_t pos = 0;
+  for (uint32_t i = 0; i < len; i++) {
+    pos += mOutBuffers.ElementAt(i).Length();
+  }
+  return pos;
+}
+
+uint32_t
 ISOControl::WriteFourCC(const char* aType)
 {
   // Bit operation should be aligned to byte before writing any byte data.
   MOZ_ASSERT(!mBitCount);
 
   uint32_t size = strlen(aType);
   if (size == 4) {
     return Write((uint8_t*)aType, size);
--- a/content/media/encoder/fmp4_muxer/ISOControl.h
+++ b/content/media/encoder/fmp4_muxer/ISOControl.h
@@ -2,17 +2,16 @@
 /* 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 ISOCOMPOSITOR_H_
 #define ISOCOMPOSITOR_H_
 
 #include "mozilla/Endian.h"
-#include "TrackMetadataBase.h"
 #include "nsTArray.h"
 #include "ISOTrackMetadata.h"
 #include "EncodedFrameContainer.h"
 
 namespace mozilla {
 
 class Box;
 class ISOControl;
@@ -125,16 +124,19 @@ friend class Box;
 public:
   ISOControl();
   ~ISOControl();
 
   nsresult GenerateFtyp();
   nsresult GenerateMoov();
   nsresult GenerateMoof(uint32_t aTrackType);
 
+  // Swap elementary stream pointer to output buffers.
+  uint32_t WriteAVData(nsTArray<uint8_t>& aArray);
+
   uint32_t Write(uint8_t* aBuf, uint32_t aSize);
 
   uint32_t Write(uint8_t aData);
 
   template <typename T>
   uint32_t Write(T aData) {
     MOZ_ASSERT(!mBitCount);
 
@@ -155,18 +157,18 @@ public:
   }
 
   uint32_t WriteFourCC(const char* aType);
 
   // Bit writing. Note: it needs to be byte-boundary before using
   // others non-bit writing function.
   uint32_t WriteBits(uint64_t aBits, size_t aNumBits);
 
-  // This is called by GetContainerData and swap the buffer to aOutBuf.
-  nsresult GetBuf(nsTArray<uint8_t>& aOutBuf);
+  // This is called by GetContainerData and swap all the buffers to aOutputBuffers.
+  nsresult GetBufs(nsTArray<nsTArray<uint8_t>>* aOutputBufs);
 
   // Presentation time in seconds since midnight, Jan. 1, 1904, in UTC time.
   uint32_t GetTime();
 
   // current fragment number
   uint32_t GetCurFragmentNumber() { return mFragNum; }
 
   nsresult SetFragment(FragmentBuffer* aFragment);
@@ -179,37 +181,47 @@ public:
   // Track ID is the Metadata index in mMetaArray.
   uint32_t GetTrackID(uint32_t aTrackType);
   uint32_t GetNextTrackID();
 
   bool HasAudioTrack();
   bool HasVideoTrack();
 
 private:
-  uint32_t GetBufPos() { return mOutBuffer.Length(); }
+  uint32_t GetBufPos();
   nsresult FlushBuf();
 
   // Audio and video fragments are owned by ISOMediaWriter.
   // They don't need to worry about pointer going stale.
   FragmentBuffer* mAudioFragmentBuffer;
   FragmentBuffer* mVideoFragmentBuffer;
 
   // Generated fragment number
   uint32_t mFragNum;
 
   // The (index + 1) will be the track ID.
   nsTArray<nsRefPtr<TrackMetadataBase>> mMetaArray;
 
-  // TODO:
-  // ContainerWriter accepts a array of uint8_t array so it is possible to
-  // create a serial of small box header + swap the raw data pointer from
-  // WriteEncodedTrack to another array without any memory copy.
-  nsTArray<uint8_t> mOutBuffer;
+  // Array of output buffers.
+  // To save memory usage, audio/video sample will be swapped into a new element
+  // of this array.
+  //
+  // For example,
+  //   mOutBuffers[0] --> boxes (allocated by muxer)
+  //   mOutBuffers[1] --> video raw data (allocated by encoder)
+  //   mOutBuffers[2] --> video raw data (allocated by encoder)
+  //   mOutBuffers[3] --> video raw data (allocated by encoder)
+  //   mOutBuffers[4] --> boxes (allocated by muxer)
+  //   mOutBuffers[5] --> audio raw data (allocated by encoder)
+  //   ...etc.
+  //
+  nsTArray<nsTArray<uint8_t>> mOutBuffers;
 
-  // Last written position of current box, it is for box checking purpose.
+  // Last written position of current box, it is for box checking purpose and
+  // calculating the sample offset in moof.
   uint32_t mLastWrittenBoxPos;
 
   // Accumulate size of output fragments.
   uint64_t mOutputSize;
 
   // Bit writing operation. Note: the mBitCount should be 0 before any
   // byte-boundary writing method be called (Write(uint32_t), Write(uint16_t)...etc);
   // otherwise, there will be assertion on these functions.
--- a/content/media/encoder/fmp4_muxer/ISOMediaBoxes.cpp
+++ b/content/media/encoder/fmp4_muxer/ISOMediaBoxes.cpp
@@ -35,17 +35,20 @@ Box::BoxSizeChecker::BoxSizeChecker(ISOC
 }
 
 Box::BoxSizeChecker::~BoxSizeChecker()
 {
   uint32_t cur_size = mControl->GetBufPos();
   if ((cur_size - ori_size) != box_size) {
     MOZ_ASSERT(false);
   }
-  mControl->mLastWrittenBoxPos = mControl->mOutBuffer.Length();
+
+  // Keeps the last box size position, it is for counting the sample offset when
+  // generating moof.
+  mControl->mLastWrittenBoxPos += box_size;
   MOZ_COUNT_DTOR(BoxSizeChecker);
 }
 
 nsresult
 MediaDataBox::Generate(uint32_t* aBoxSize)
 {
   mFirstSampleOffset = size;
   mAllSampleSize = 0;
@@ -80,18 +83,19 @@ MediaDataBox::Write()
       nsTArray<nsRefPtr<EncodedFrame>> frames;
 
       // Here is the last time we get fragment frames, flush it!
       rv = frag->GetFirstFragment(frames, true);
       NS_ENSURE_SUCCESS(rv, rv);
 
       uint32_t len = frames.Length();
       for (uint32_t i = 0; i < len; i++) {
-        mControl->Write((uint8_t*)frames.ElementAt(i)->GetFrameData().Elements(),
-            frames.ElementAt(i)->GetFrameData().Length());
+        nsTArray<uint8_t> frame_buffer;
+        frames.ElementAt(i)->SwapOutFrameData(frame_buffer);
+        mControl->WriteAVData(frame_buffer);
       }
     }
   }
 
   return NS_OK;
 }
 
 MediaDataBox::MediaDataBox(uint32_t aTrackType, ISOControl* aControl)
--- a/content/media/encoder/fmp4_muxer/ISOMediaWriter.cpp
+++ b/content/media/encoder/fmp4_muxer/ISOMediaWriter.cpp
@@ -112,20 +112,22 @@ ISOMediaWriter::WriteEncodedTrack(const 
 
     frag->AddFrame(frame);
   }
 
   // Encoder should send CSD (codec specific data) frame before sending the
   // audio/video frames. When CSD data is ready, it is sufficient to generate a
   // moov data. If encoder doesn't send CSD yet, muxer needs to wait before
   // generating anything.
-  if (mType & Audio_Track && !mAudioFragmentBuffer->HasCSD()) {
+  if (mType & Audio_Track && (!mAudioFragmentBuffer ||
+                              !mAudioFragmentBuffer->HasCSD())) {
     return NS_OK;
   }
-  if (mType & Video_Track && !mVideoFragmentBuffer->HasCSD()) {
+  if (mType & Video_Track && (!mVideoFragmentBuffer ||
+                              !mVideoFragmentBuffer->HasCSD())) {
     return NS_OK;
   }
 
   // Only one FrameType in EncodedFrameContainer so it doesn't need to be
   // inside the for-loop.
   if (frag && (aFlags & END_OF_STREAM)) {
     frag->SetEndOfStream();
   }
@@ -188,18 +190,17 @@ nsresult
 ISOMediaWriter::GetContainerData(nsTArray<nsTArray<uint8_t>>* aOutputBufs,
                                  uint32_t aFlags)
 {
   if (mBlobReady) {
     if (mState == MUXING_DONE) {
       mIsWritingComplete = true;
     }
     mBlobReady = false;
-    aOutputBufs->AppendElement();
-    return mControl->GetBuf(aOutputBufs->LastElement());
+    return mControl->GetBufs(aOutputBufs);
   }
   return NS_OK;
 }
 
 nsresult
 ISOMediaWriter::SetMetadata(TrackMetadataBase* aMetadata)
 {
   if (aMetadata->GetKind() == TrackMetadataBase::METADATA_AAC ) {
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -4786,16 +4786,20 @@ nsDocShell::LoadErrorPage(nsIURI *aURI, 
       nsCString manifestParam;
       SAFE_ESCAPE(manifestParam,
                   NS_ConvertUTF16toUTF8(manifestURL).get(),
                   url_Path);
       errorPageUrl.AppendLiteral("&m=");
       errorPageUrl.AppendASCII(manifestParam.get());
     }
 
+    nsAutoCString frameType(FrameTypeToString(mFrameType));
+    errorPageUrl.AppendLiteral("&f=");
+    errorPageUrl.AppendASCII(frameType.get());
+
     nsCOMPtr<nsIURI> errorPageURI;
     rv = NS_NewURI(getter_AddRefs(errorPageURI), errorPageUrl);
     NS_ENSURE_SUCCESS(rv, rv);
 
     return InternalLoad(errorPageURI, nullptr, nullptr,
                         INTERNAL_LOAD_FLAGS_INHERIT_OWNER, nullptr, nullptr,
                         NullString(), nullptr, nullptr, LOAD_ERROR_PAGE,
                         nullptr, true, NullString(), this, nullptr, nullptr);
--- a/docshell/base/nsDocShell.h
+++ b/docshell/base/nsDocShell.h
@@ -662,16 +662,31 @@ protected:
     bool JustStartedNetworkLoad();
 
     enum FrameType {
         eFrameTypeRegular,
         eFrameTypeBrowser,
         eFrameTypeApp
     };
 
+    static const nsCString FrameTypeToString(FrameType aFrameType)
+    {
+      switch (aFrameType) {
+      case FrameType::eFrameTypeApp:
+        return NS_LITERAL_CSTRING("app");
+      case FrameType::eFrameTypeBrowser:
+        return NS_LITERAL_CSTRING("browser");
+      case FrameType::eFrameTypeRegular:
+        return NS_LITERAL_CSTRING("regular");
+      default:
+        NS_ERROR("Unknown frame type");
+        return EmptyCString();
+      }
+    }
+
     FrameType GetInheritedFrameType();
 
     bool HasUnloadedParent();
 
     // Dimensions of the docshell
     nsIntRect                  mBounds;
     nsString                   mName;
     nsString                   mTitle;
--- a/dom/activities/src/ActivityProxy.js
+++ b/dom/activities/src/ActivityProxy.js
@@ -5,17 +5,16 @@
 "use strict";
 
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cu = Components.utils;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/ObjectWrapper.jsm");
 
 XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
                                    "@mozilla.org/childprocessmessagemanager;1",
                                    "nsISyncMessageSender");
 
 function debug(aMsg) {
   //dump("-- ActivityProxy " + Date.now() + " : " + aMsg + "\n");
 }
@@ -71,17 +70,17 @@ ActivityProxy.prototype = {
     if (msg.id != this.id)
       return;
     debug("msg=" + JSON.stringify(msg));
 
     switch(aMessage.name) {
       case "Activity:FireSuccess":
         debug("FireSuccess");
         Services.DOMRequest.fireSuccess(this.activity,
-                                        ObjectWrapper.wrap(msg.result, this.window));
+                                        Cu.cloneInto(msg.result, this.window));
         Services.obs.notifyObservers(null, "Activity:Success", null);
         break;
       case "Activity:FireError":
         debug("FireError");
         Services.DOMRequest.fireError(this.activity, msg.error);
         Services.obs.notifyObservers(null, "Activity:Error", null);
         break;
     }
--- a/dom/activities/src/ActivityWrapper.js
+++ b/dom/activities/src/ActivityWrapper.js
@@ -4,17 +4,16 @@
 
 "use strict";
 
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cu = Components.utils;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/ObjectWrapper.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 
 XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
                                    "@mozilla.org/childprocessmessagemanager;1",
                                    "nsISyncMessageSender");
 
 function debug(aMsg) {
   //dump("-- ActivityWrapper.js " + Date.now() + " : " + aMsg + "\n");
@@ -33,17 +32,17 @@ ActivityWrapper.prototype = {
     debug("Wrapping " + JSON.stringify(aMessage));
     let handler = Cc["@mozilla.org/dom/activities/request-handler;1"]
                     .createInstance(Ci.nsIDOMMozActivityRequestHandler);
     handler.wrappedJSObject._id = aMessage.id;
 
     // options is an nsIDOMActivityOptions object.
     var options = handler.wrappedJSObject._options;
     options.wrappedJSObject._name = aMessage.payload.name;
-    options.wrappedJSObject._data = ObjectWrapper.wrap(aMessage.payload.data, aWindow);
+    options.wrappedJSObject._data = Cu.cloneInto(aMessage.payload.data, aWindow);
 
     // When the activity window is closed, fire an error to notify the activity
     // caller of the situation.
     // We don't need to check whether the activity itself already sent
     // back something since ActivitiesService.jsm takes care of that.
     let util = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
                       .getInterface(Ci.nsIDOMWindowUtils);
     let innerWindowID = util.currentInnerWindowID;
--- a/dom/alarm/AlarmsManager.js
+++ b/dom/alarm/AlarmsManager.js
@@ -12,17 +12,16 @@ function debug(aStr) {
     dump("AlarmsManager: " + aStr + "\n");
 }
 
 const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/DOMRequestHelper.jsm");
-Cu.import("resource://gre/modules/ObjectWrapper.jsm");
 
 const ALARMSMANAGER_CONTRACTID = "@mozilla.org/alarmsManager;1";
 const ALARMSMANAGER_CID        = Components.ID("{fea1e884-9b05-11e1-9b64-87a7016c3860}");
 const nsIDOMMozAlarmsManager   = Ci.nsIDOMMozAlarmsManager;
 const nsIClassInfo             = Ci.nsIClassInfo;
 
 function AlarmsManager()
 {
@@ -129,17 +128,17 @@ AlarmsManager.prototype = {
           let alarm = { "id":              aAlarm.id,
                         "date":            aAlarm.date,
                         "respectTimezone": aAlarm.ignoreTimezone ?
                                              "ignoreTimezone" : "honorTimezone",
                         "data":            aAlarm.data };
           alarms.push(alarm);
         });
         Services.DOMRequest.fireSuccess(request,
-                                        ObjectWrapper.wrap(alarms, this._window));
+                                        Cu.cloneInto(alarms, this._window));
         break;
 
       case "AlarmsManager:Add:Return:KO":
         Services.DOMRequest.fireError(request, json.errorMsg);
         break;
 
       case "AlarmsManager:GetAll:Return:KO":
         Services.DOMRequest.fireError(request, json.errorMsg);
--- a/dom/apps/src/InterAppMessagePort.js
+++ b/dom/apps/src/InterAppMessagePort.js
@@ -11,17 +11,16 @@
 
 "use strict";
 
 const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
 
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/DOMRequestHelper.jsm");
-Cu.import("resource://gre/modules/ObjectWrapper.jsm");
 
 const DEBUG = false;
 function debug(aMsg) {
   dump("-- InterAppMessagePort: " + Date.now() + ": " + aMsg + "\n");
 }
 
 XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
                                    "@mozilla.org/childprocessmessagemanager;1",
@@ -170,17 +169,17 @@ InterAppMessagePort.prototype = {
       if (DEBUG) debug("start() has been called. Don't need to start again.");
       return;
     }
 
     this.start();
   },
 
   _dispatchMessage: function _dispatchMessage(aMessage) {
-    let wrappedMessage = ObjectWrapper.wrap(aMessage, this._window);
+    let wrappedMessage = Cu.cloneInto(aMessage, this._window);
     if (DEBUG) {
       debug("_dispatchMessage: wrappedMessage: " +
             JSON.stringify(wrappedMessage));
     }
 
     let event = new this._window
                     .MozInterAppMessageEvent("message",
                                              { data: wrappedMessage });
--- a/dom/apps/src/Webapps.js
+++ b/dom/apps/src/Webapps.js
@@ -5,17 +5,16 @@
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cu = Components.utils;
 const Cr = Components.results;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/DOMRequestHelper.jsm");
-Cu.import("resource://gre/modules/ObjectWrapper.jsm");
 Cu.import("resource://gre/modules/AppsUtils.jsm");
 Cu.import("resource://gre/modules/BrowserElementPromptService.jsm");
 
 XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
                                    "@mozilla.org/childprocessmessagemanager;1",
                                    "nsIMessageSender");
 
 function convertAppsArray(aApps, aWindow) {
@@ -272,17 +271,17 @@ let manifestCache = {
   // Gets an entry from the cache, and populates the cache if needed.
   get: function mcache_get(aManifestURL, aManifest, aWindow, aInnerWindowID) {
     if (!(aManifestURL in this._cache)) {
       this._cache[aManifestURL] = { };
     }
 
     let winObjs = this._cache[aManifestURL];
     if (!(aInnerWindowID in winObjs)) {
-      winObjs[aInnerWindowID] = ObjectWrapper.wrap(aManifest, aWindow);
+      winObjs[aInnerWindowID] = Cu.cloneInto(aManifest, aWindow);
     }
 
     return winObjs[aInnerWindowID];
   },
 
   // Invalidates an entry in the cache.
   evict: function mcache_evict(aManifestURL, aInnerWindowID) {
     if (aManifestURL in this._cache) {
@@ -376,18 +375,17 @@ WebappsApplication.prototype = {
     return manifestCache.get(this.manifestURL,
                              this._manifest,
                              this._window,
                              this.innerWindowID);
   },
 
   get updateManifest() {
     return this.updateManifest =
-      this._updateManifest ? ObjectWrapper.wrap(this._updateManifest,
-                                                this._window)
+      this._updateManifest ? Cu.cloneInto(this._updateManifest, this._window)
                            : null;
   },
 
   set onprogress(aCallback) {
     this._onprogress = aCallback;
   },
 
   get onprogress() {
--- a/dom/inputmethod/MozKeyboard.js
+++ b/dom/inputmethod/MozKeyboard.js
@@ -5,17 +5,16 @@
 "use strict";
 
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cu = Components.utils;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/ObjectWrapper.jsm");
 Cu.import("resource://gre/modules/DOMRequestHelper.jsm");
 
 XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
   "@mozilla.org/childprocessmessagemanager;1", "nsIMessageSender");
 
 XPCOMUtils.defineLazyServiceGetter(this, "tm",
   "@mozilla.org/thread-manager;1", "nsIThreadManager");
 
@@ -170,30 +169,30 @@ MozKeyboard.prototype = {
       if (!handler || !(handler instanceof Ci.nsIDOMEventListener))
         return;
 
       let detail = {
         "detail": msgJson
       };
 
       let evt = new this._window.CustomEvent("focuschanged",
-          ObjectWrapper.wrap(detail, this._window));
+          Cu.cloneInto(detail, this._window));
       handler.handleEvent(evt);
     } else if (msg.name == "Keyboard:SelectionChange") {
       let msgJson = msg.json;
 
       this._selectionStart = msgJson.selectionStart;
       this._selectionEnd = msgJson.selectionEnd;
 
       let handler = this._selectionHandler;
       if (!handler || !(handler instanceof Ci.nsIDOMEventListener))
         return;
 
       let evt = new this._window.CustomEvent("selectionchange",
-          ObjectWrapper.wrap({}, this._window));
+          Cu.cloneInto({}, this._window));
       handler.handleEvent(evt);
     }
   },
 
   observe: function mozKeyboardObserve(subject, topic, data) {
     let wId = subject.QueryInterface(Ci.nsISupportsPRUint64).data;
     if (wId == this.innerWindowID)
       this.uninit();
@@ -408,17 +407,17 @@ MozInputMethod.prototype = {
         this._layouts[data.type] > 1 :
         false;
 
       this._inputcontext = new MozInputContext(data);
       this._inputcontext.init(this._window);
     }
 
     let event = new this._window.Event("inputcontextchange",
-                                       ObjectWrapper.wrap({}, this._window));
+                                       Cu.cloneInto({}, this._window));
     this.__DOM_IMPL__.dispatchEvent(event);
   },
 
   setActive: function mozInputMethodSetActive(isActive) {
     if (WindowMap.isActive(this._window) === isActive) {
       return;
     }
 
@@ -547,17 +546,17 @@ MozInputContext.prototype = {
         resolver.resolve(json.text);
         break;
       case "Keyboard:GetText:Result:Error":
         resolver.reject(json.error);
         break;
       case "Keyboard:SetSelectionRange:Result:OK":
       case "Keyboard:ReplaceSurroundingText:Result:OK":
         resolver.resolve(
-          ObjectWrapper.wrap(json.selectioninfo, this._window));
+          Cu.cloneInto(json.selectioninfo, this._window));
         break;
       case "Keyboard:SequenceError":
         // Occurs when a new element got focus, but the inputContext was
         // not invalidated yet...
         resolver.reject("InputContext has expired");
         break;
       case "Keyboard:SetComposition:Result:OK": // Fall through.
       case "Keyboard:EndComposition:Result:OK":
@@ -601,17 +600,17 @@ MozInputContext.prototype = {
   },
 
   _fireEvent: function ic_fireEvent(eventName, aDetail) {
     let detail = {
       detail: aDetail
     };
 
     let event = new this._window.Event(eventName,
-                                       ObjectWrapper.wrap(aDetail, this._window));
+                                       Cu.cloneInto(aDetail, this._window));
     this.__DOM_IMPL__.dispatchEvent(event);
   },
 
   // tag name of the input field
   get type() {
     return this._context.type;
   },
 
--- a/dom/ipc/PreallocatedProcessManager.cpp
+++ b/dom/ipc/PreallocatedProcessManager.cpp
@@ -304,17 +304,17 @@ PreallocatedProcessManagerImpl::PublishS
   MOZ_ASSERT(NS_IsMainThread());
 
   if (Preferences::GetBool("dom.ipc.processPriorityManager.testMode")) {
     AutoJSContext cx;
     nsCOMPtr<nsIMessageBroadcaster> ppmm =
       do_GetService("@mozilla.org/parentprocessmessagemanager;1");
     nsresult rv = ppmm->BroadcastAsyncMessage(
       NS_LITERAL_STRING("TEST-ONLY:nuwa-add-new-process"),
-      JS::NullHandleValue, JS::NullHandleValue, cx, 1);
+      JSVAL_NULL, JSVAL_NULL, cx, 1);
   }
 
   if (!mNuwaForkWaitTasks.IsEmpty()) {
     mNuwaForkWaitTasks.ElementAt(0)->Cancel();
     mNuwaForkWaitTasks.RemoveElementAt(0);
   }
 
   mSpareProcesses.AppendElement(aContent);
@@ -357,17 +357,17 @@ PreallocatedProcessManagerImpl::OnNuwaRe
                                              hal::PROCESS_PRIORITY_MASTER);
   mIsNuwaReady = true;
   if (Preferences::GetBool("dom.ipc.processPriorityManager.testMode")) {
     AutoJSContext cx;
     nsCOMPtr<nsIMessageBroadcaster> ppmm =
       do_GetService("@mozilla.org/parentprocessmessagemanager;1");
     nsresult rv = ppmm->BroadcastAsyncMessage(
       NS_LITERAL_STRING("TEST-ONLY:nuwa-ready"),
-      JS::NullHandleValue, JS::NullHandleValue, cx, 1);
+      JSVAL_NULL, JSVAL_NULL, cx, 1);
   }
   NuwaFork();
 }
 
 bool
 PreallocatedProcessManagerImpl::PreallocatedProcessReady()
 {
   return !mSpareProcesses.IsEmpty();
--- a/dom/ipc/preload.js
+++ b/dom/ipc/preload.js
@@ -20,17 +20,16 @@ const BrowserElementIsPreloaded = true;
   Cu.import("resource://gre/modules/AppsUtils.jsm");
   Cu.import("resource://gre/modules/BrowserElementPromptService.jsm");
   Cu.import("resource://gre/modules/CSPUtils.jsm");
   Cu.import("resource://gre/modules/DOMRequestHelper.jsm");
   Cu.import("resource://gre/modules/FileUtils.jsm");
   Cu.import("resource://gre/modules/Geometry.jsm");
   Cu.import("resource://gre/modules/IndexedDBHelper.jsm");
   Cu.import("resource://gre/modules/NetUtil.jsm");
-  Cu.import("resource://gre/modules/ObjectWrapper.jsm");
   Cu.import("resource://gre/modules/Services.jsm");
   Cu.import("resource://gre/modules/SettingsDB.jsm");
   Cu.import("resource://gre/modules/SettingsQueue.jsm");
   Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
   Cc["@mozilla.org/appshell/appShellService;1"].getService(Ci["nsIAppShellService"]);
   Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci["nsIWindowMediator"]);
   Cc["@mozilla.org/AppsService;1"].getService(Ci["nsIAppsService"]);
--- a/dom/ipc/tests/mochitest.ini
+++ b/dom/ipc/tests/mochitest.ini
@@ -1,2 +1,2 @@
 [test_NuwaProcessCreation.html]
-run-if = toolkit == 'gonk'
+skip-if = true # re-enable when nuwa is enabled.
--- a/dom/locales/en-US/chrome/security/csp.properties
+++ b/dom/locales/en-US/chrome/security/csp.properties
@@ -20,19 +20,19 @@ errorWas = error was: "%1$S"
 # %1$S is the report URI that could not be parsed
 couldNotParseReportURI = couldn't parse report URI: %1$S
 # LOCALIZATION NOTE (couldNotProcessUnknownDirective):
 # %1$S is the unknown directive
 couldNotProcessUnknownDirective = Couldn't process unknown directive '%1$S'
 # LOCALIZATION NOTE (ignoringUnknownOption):
 # %1$S is the option that could not be understood
 ignoringUnknownOption = Ignoring unknown option %1$S
-# LOCALIZATION NOTE (reportURInotHttpsOrHttp):
+# LOCALIZATION NOTE (reportURInotHttpsOrHttp2):
 # %1$S is the ETLD of the report URI that is not HTTP or HTTPS
-reportURInotHttpsOrHttp = The report URI (%1$) should be an HTTP or HTTPS URI.
+reportURInotHttpsOrHttp2 = The report URI (%1$S) should be an HTTP or HTTPS URI.
 # LOCALIZATION NOTE (pageCannotSendReportsTo):
 # %1$S is the URI of the page with the policy
 # %2$S is the report URI that could not be used
 pageCannotSendReportsTo = page on %1$S cannot send reports to %2$S
 allowOrDefaultSrcRequired = 'allow' or 'default-src' directive required but not present.  Reverting to "default-src 'none'"
 # LOCALIZATION NOTE (failedToParseUnrecognizedSource):
 # %1$S is the CSP Source that could not be parsed
 failedToParseUnrecognizedSource = Failed to parse unrecognized source %1$S
--- a/dom/messages/SystemMessageManager.js
+++ b/dom/messages/SystemMessageManager.js
@@ -7,17 +7,16 @@
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cu = Components.utils;
 const Cr = Components.results;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/DOMRequestHelper.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/ObjectWrapper.jsm");
 
 const kSystemMessageInternalReady = "system-message-internal-ready";
 
 XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
                                    "@mozilla.org/childprocessmessagemanager;1",
                                    "nsISyncMessageSender");
 
 function debug(aMsg) {
@@ -89,17 +88,17 @@ SystemMessageManager.prototype = {
         aMessage = wrapper.wrapMessage(aMessage, this._window);
         wrapped = true;
         debug("wrapped = " + aMessage);
       }
     }
 
     aDispatcher.handler
       .handleMessage(wrapped ? aMessage
-                             : ObjectWrapper.wrap(aMessage, this._window));
+                             : Cu.cloneInto(aMessage, this._window));
 
     // We need to notify the parent one of the system messages has been handled,
     // so the parent can release the CPU wake lock it took on our behalf.
     cpmm.sendAsyncMessage("SystemMessageManager:HandleMessagesDone",
                           { type: aType,
                             manifest: this._manifest,
                             uri: this._uri,
                             handledCount: 1 });
--- a/dom/network/src/NetworkStatsManager.js
+++ b/dom/network/src/NetworkStatsManager.js
@@ -7,17 +7,16 @@
 const DEBUG = false;
 function debug(s) { dump("-*- NetworkStatsManager: " + s + "\n"); }
 
 const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/DOMRequestHelper.jsm");
-Cu.import("resource://gre/modules/ObjectWrapper.jsm");
 
 // Ensure NetworkStatsService and NetworkStatsDB are loaded in the parent process
 // to receive messages from the child processes.
 let appInfo = Cc["@mozilla.org/xre/app-info;1"];
 let isParentProcess = !appInfo || appInfo.getService(Ci.nsIXULRuntime)
                         .processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
 if (isParentProcess) {
   Cu.import("resource://gre/modules/NetworkStatsService.jsm");
--- a/dom/nfc/nsNfc.js
+++ b/dom/nfc/nsNfc.js
@@ -127,17 +127,17 @@ MozNFCPeer.prototype = {
     return this._nfcContentHelper.writeNDEF(this._window, records, this.session);
   },
 
   sendFile: function sendFile(blob) {
     let data = {
       "blob": blob.slice()
     };
     return this._nfcContentHelper.sendFile(this._window,
-                                           ObjectWrapper.wrap(data, this._window),
+                                           Cu.cloneInto(data, this._window),
                                            this.session);
   },
 
   classID: Components.ID("{c1b2bcf0-35eb-11e3-aa6e-0800200c9a66}"),
   contractID: "@mozilla.org/nfc/NFCPeer;1",
   QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports,
                                          Ci.nsIDOMGlobalPropertyInitializer]),
 };
@@ -153,17 +153,17 @@ function mozNfc() {
   } catch(e) {
     debug("No NFC support.")
   }
 }
 mozNfc.prototype = {
   _nfcContentHelper: null,
   _window: null,
   _wrap: function _wrap(obj) {
-    return ObjectWrapper.wrap(obj, this._window);
+    return Cu.cloneInto(obj, this._window);
   },
 
   init: function init(aWindow) {
     debug("mozNfc init called");
     this._window = aWindow;
   },
 
   // Only System Process can call the following interfaces
@@ -272,18 +272,17 @@ mozNfc.prototype = {
     return eventType;
   },
 
   firePeerEvent: function firePeerEvent(evt, sessionToken) {
     let peerEvent = (NFC_PEER_EVENT_READY === evt) ? "peerready" : "peerlost";
     let detail = {
       "detail":sessionToken
     };
-    let event = new this._window.CustomEvent(peerEvent,
-      ObjectWrapper.wrap(detail, this._window));
+    let event = new this._window.CustomEvent(peerEvent, this._wrap(detail);
     this.__DOM_IMPL__.dispatchEvent(event);
   },
 
   classID: Components.ID("{6ff2b290-2573-11e3-8224-0800200c9a66}"),
   contractID: "@mozilla.org/navigatorNfc;1",
   QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports,
                                          Ci.nsIDOMGlobalPropertyInitializer]),
 };
--- a/dom/settings/SettingsManager.js
+++ b/dom/settings/SettingsManager.js
@@ -32,17 +32,17 @@ function SettingsLock(aSettingsManager) 
 }
 
 SettingsLock.prototype = {
   get closed() {
     return !this._open;
   },
 
   _wrap: function _wrap(obj) {
-    return ObjectWrapper.wrap(obj, this._settingsManager._window);
+    return Cu.cloneInto(obj, this._settingsManager._window);
   },
 
   process: function process() {
     let lock = this;
     let store = lock._transaction.objectStore(SETTINGSSTORE_NAME);
 
     while (!lock._requests.isEmpty()) {
       let info = lock._requests.dequeue();
@@ -252,17 +252,17 @@ function SettingsManager() {
   this._settingsDB = new SettingsDB();
   this._settingsDB.init();
 }
 
 SettingsManager.prototype = {
   _callbacks: null,
 
   _wrap: function _wrap(obj) {
-    return ObjectWrapper.wrap(obj, this._window);
+    return Cu.cloneInto(obj, this._window);
   },
 
   nextTick: function nextTick(aCallback, thisObj) {
     if (thisObj)
       aCallback = aCallback.bind(thisObj);
 
     Services.tm.currentThread.dispatch(aCallback, Ci.nsIThread.DISPATCH_NORMAL);
   },
--- a/dom/system/gonk/NetworkUtils.cpp
+++ b/dom/system/gonk/NetworkUtils.cpp
@@ -12,16 +12,17 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 
 #include "NetworkUtils.h"
 
 #include <android/log.h>
 #include <cutils/properties.h>
+#include <limits>
 #include "mozilla/dom/network/NetUtils.h"
 
 #define _DEBUG 0
 
 #define WARN(args...)   __android_log_print(ANDROID_LOG_WARN,  "NetworlUtils", ## args)
 #define ERROR(args...)  __android_log_print(ANDROID_LOG_ERROR,  "NetworkUtils", ## args)
 
 #if _DEBUG
@@ -527,17 +528,17 @@ void NetworkUtils::disableAlarm(CommandC
   doCommand(command, aChain, aCallback);
 }
 
 void NetworkUtils::setQuota(CommandChain* aChain,
                             CommandCallback aCallback,
                             NetworkResultOptions& aResult)
 {
   char command[MAX_COMMAND_SIZE];
-  snprintf(command, MAX_COMMAND_SIZE - 1, "bandwidth setiquota %s %lld", GET_CHAR(mIfname), atoll("0xffffffffffffffff"));
+  snprintf(command, MAX_COMMAND_SIZE - 1, "bandwidth setiquota %s %lld", GET_CHAR(mIfname), LLONG_MAX);
 
   doCommand(command, aChain, aCallback);
 }
 
 void NetworkUtils::removeQuota(CommandChain* aChain,
                                CommandCallback aCallback,
                                NetworkResultOptions& aResult)
 {
--- a/mobile/android/base/BrowserApp.java
+++ b/mobile/android/base/BrowserApp.java
@@ -2477,17 +2477,21 @@ abstract public class BrowserApp extends
                 openUrlAndStopEditing(url, true);
             }
         }
     }
 
     // HomePager.OnUrlOpenListener
     @Override
     public void onUrlOpen(String url, EnumSet<OnUrlOpenListener.Flags> flags) {
-        if (!maybeSwitchToTab(url, flags)) {
+        if (flags.contains(OnUrlOpenListener.Flags.OPEN_WITH_INTENT)) {
+            Intent intent = new Intent(Intent.ACTION_VIEW);
+            intent.setData(Uri.parse(url));
+            startActivity(intent);
+        } else if (!maybeSwitchToTab(url, flags)) {
             openUrlAndStopEditing(url);
         }
     }
 
     // BrowserSearch.OnSearchListener
     @Override
     public void onSearch(SearchEngine engine, String text) {
         recordSearch(engine, "barsuggest");
--- a/mobile/android/base/Tabs.java
+++ b/mobile/android/base/Tabs.java
@@ -2,16 +2,17 @@
  * 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/. */
 
 package org.mozilla.gecko;
 
 import org.mozilla.gecko.db.BrowserDB;
 import org.mozilla.gecko.favicons.Favicons;
+import org.mozilla.gecko.fxa.FirefoxAccounts;
 import org.mozilla.gecko.mozglue.JNITarget;
 import org.mozilla.gecko.mozglue.RobocopTarget;
 import org.mozilla.gecko.sync.setup.SyncAccounts;
 import org.mozilla.gecko.util.GeckoEventListener;
 import org.mozilla.gecko.util.ThreadUtils;
 
 import org.json.JSONObject;
 
@@ -73,17 +74,19 @@ public class Tabs implements GeckoEventL
 
     private Context mAppContext;
     private ContentObserver mContentObserver;
 
     private final Runnable mPersistTabsRunnable = new Runnable() {
         @Override
         public void run() {
             try {
-                boolean syncIsSetup = SyncAccounts.syncAccountsExist(getAppContext());
+                final Context context = getAppContext();
+                boolean syncIsSetup = SyncAccounts.syncAccountsExist(context) ||
+                                      FirefoxAccounts.firefoxAccountsExist(context);
                 if (syncIsSetup) {
                     TabsAccessor.persistLocalTabs(getContentResolver(), getTabsInOrder());
                 }
             } catch (SecurityException se) {} // will fail without android.permission.GET_ACCOUNTS
         }
     };
 
     private Tabs() {
--- a/mobile/android/base/android-services.mozbuild
+++ b/mobile/android/base/android-services.mozbuild
@@ -558,16 +558,17 @@ sync_java_files = [
     'fxa/activities/FxAccountStatusActivity.java',
     'fxa/activities/FxAccountUpdateCredentialsActivity.java',
     'fxa/activities/FxAccountVerifiedAccountActivity.java',
     'fxa/authenticator/AndroidFxAccount.java',
     'fxa/authenticator/FxAccountAuthenticator.java',
     'fxa/authenticator/FxAccountAuthenticatorService.java',
     'fxa/authenticator/FxAccountLoginDelegate.java',
     'fxa/authenticator/FxAccountLoginException.java',
+    'fxa/FirefoxAccounts.java',
     'fxa/login/BaseRequestDelegate.java',
     'fxa/login/Cohabiting.java',
     'fxa/login/Doghouse.java',
     'fxa/login/Engaged.java',
     'fxa/login/FxAccountLoginStateMachine.java',
     'fxa/login/FxAccountLoginTransition.java',
     'fxa/login/Married.java',
     'fxa/login/Separated.java',
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/fxa/FirefoxAccounts.java
@@ -0,0 +1,46 @@
+/* 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/. */
+
+package org.mozilla.gecko.fxa;
+
+import android.accounts.Account;
+import android.accounts.AccountManager;
+import android.content.Context;
+
+/**
+ * Simple public accessors for Firefox account objects.
+ */
+public class FirefoxAccounts {
+  /**
+   * Return true if at least one Firefox account exists.
+   *
+   * @param context Android context.
+   * @return true if at least one Firefox account exists.
+   */
+  public static boolean firefoxAccountsExist(final Context context) {
+    return getFirefoxAccounts(context).length > 0;
+  }
+
+  /**
+   * Return Firefox accounts.
+   *
+   * @param context Android context.
+   * @return Firefox account objects.
+   */
+  public static Account[] getFirefoxAccounts(final Context context) {
+    return AccountManager.get(context).getAccountsByType(FxAccountConstants.ACCOUNT_TYPE);
+  }
+
+  /**
+   * @param context Android context.
+   * @return the configured Firefox account if one exists, or null otherwise.
+   */
+  public static Account getFirefoxAccount(final Context context) {
+    Account[] accounts = getFirefoxAccounts(context);
+    if (accounts.length > 0) {
+      return accounts[0];
+    }
+    return null;
+  }
+}
\ No newline at end of file
--- a/mobile/android/base/fxa/activities/FxAccountAbstractActivity.java
+++ b/mobile/android/base/fxa/activities/FxAccountAbstractActivity.java
@@ -1,18 +1,18 @@
 /* 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/. */
 
 package org.mozilla.gecko.fxa.activities;
 
 import org.mozilla.gecko.background.common.log.Logger;
 import org.mozilla.gecko.background.fxa.FxAccountAgeLockoutHelper;
+import org.mozilla.gecko.fxa.FirefoxAccounts;
 import org.mozilla.gecko.fxa.authenticator.AndroidFxAccount;
-import org.mozilla.gecko.fxa.authenticator.FxAccountAuthenticator;
 import org.mozilla.gecko.sync.setup.activities.ActivityUtils;
 
 import android.accounts.Account;
 import android.app.Activity;
 import android.content.Intent;
 import android.os.SystemClock;
 import android.view.View;
 import android.view.View.OnClickListener;
@@ -40,22 +40,22 @@ public abstract class FxAccountAbstractA
   /**
    * Many Firefox Accounts activities shouldn't display if an account already
    * exists or if account creation is locked out due to an age verification
    * check failing (getting started, create account, sign in). This function
    * redirects as appropriate.
    */
   protected void redirectIfAppropriate() {
     if (cannotResumeWhenAccountsExist || cannotResumeWhenNoAccountsExist) {
-      Account accounts[] = FxAccountAuthenticator.getFirefoxAccounts(this);
-      if (cannotResumeWhenAccountsExist && accounts.length > 0) {
+      final Account account = FirefoxAccounts.getFirefoxAccount(this);
+      if (cannotResumeWhenAccountsExist && account != null) {
         redirectToActivity(FxAccountStatusActivity.class);
         return;
       }
-      if (cannotResumeWhenNoAccountsExist && accounts.length < 1) {
+      if (cannotResumeWhenNoAccountsExist && account == null) {
         redirectToActivity(FxAccountGetStartedActivity.class);
         return;
       }
     }
     if (cannotResumeWhenLockedOut) {
       if (FxAccountAgeLockoutHelper.isLockedOut(SystemClock.elapsedRealtime())) {
         this.setResult(RESULT_CANCELED);
         redirectToActivity(FxAccountCreateAccountNotAllowedActivity.class);
@@ -131,15 +131,15 @@ public abstract class FxAccountAbstractA
       }
     });
   }
 
   /**
    * Helper to fetch (unique) Android Firefox Account if one exists, or return null.
    */
   protected AndroidFxAccount getAndroidFxAccount() {
-    Account accounts[] = FxAccountAuthenticator.getFirefoxAccounts(this);
-    if (accounts.length < 1 || accounts[0] == null) {
+    Account account = FirefoxAccounts.getFirefoxAccount(this);
+    if (account == null) {
       return null;
     }
-    return new AndroidFxAccount(this, accounts[0]);
+    return new AndroidFxAccount(this, account);
   }
 }
--- a/mobile/android/base/fxa/activities/FxAccountAbstractSetupActivity.java
+++ b/mobile/android/base/fxa/activities/FxAccountAbstractSetupActivity.java
@@ -16,16 +16,17 @@ import org.mozilla.gecko.background.fxa.
 import org.mozilla.gecko.background.fxa.PasswordStretcher;
 import org.mozilla.gecko.fxa.FxAccountConstants;
 import org.mozilla.gecko.fxa.activities.FxAccountSetupTask.ProgressDisplay;
 import org.mozilla.gecko.fxa.authenticator.AndroidFxAccount;
 import org.mozilla.gecko.fxa.login.Engaged;
 import org.mozilla.gecko.fxa.login.State;
 import org.mozilla.gecko.sync.SyncConfiguration;
 import org.mozilla.gecko.sync.setup.Constants;
+import org.mozilla.gecko.sync.setup.activities.ActivityUtils;
 
 import android.accounts.AccountManager;
 import android.content.Intent;
 import android.text.Editable;
 import android.text.InputType;
 import android.text.TextWatcher;
 import android.util.Patterns;
 import android.view.KeyEvent;
@@ -77,32 +78,47 @@ abstract public class FxAccountAbstractS
           showPasswordButton.setText(R.string.fxaccount_password_hide);
           showPasswordButton.setBackgroundDrawable(getResources().getDrawable(R.drawable.fxaccount_password_button_hide_background));
           showPasswordButton.setTextColor(getResources().getColor(R.color.fxaccount_password_hide_textcolor));
         }
       }
     });
   }
 
+  protected void linkifyPolicy() {
+    TextView policyView = (TextView) ensureFindViewById(null, R.id.policy, "policy links");
+    final String linkTerms = getString(R.string.fxaccount_link_tos);
+    final String linkPrivacy = getString(R.string.fxaccount_link_pn);
+    final String linkedTOS = "<a href=\"" + linkTerms + "\">" + getString(R.string.fxaccount_policy_linktos) + "</a>";
+    final String linkedPN = "<a href=\"" + linkPrivacy + "\">" + getString(R.string.fxaccount_policy_linkprivacy) + "</a>";
+    policyView.setText(getString(R.string.fxaccount_create_account_policy_text, linkedTOS, linkedPN));
+    final boolean underlineLinks = true;
+    ActivityUtils.linkifyTextView(policyView, underlineLinks);
+  }
+
   protected void hideRemoteError() {
     remoteErrorTextView.setVisibility(View.INVISIBLE);
   }
 
   protected void showRemoteError(Exception e, int defaultResourceId) {
     if (e instanceof IOException) {
       remoteErrorTextView.setText(R.string.fxaccount_remote_error_COULD_NOT_CONNECT);
     } else if (e instanceof FxAccountClientRemoteException) {
-      remoteErrorTextView.setText(((FxAccountClientRemoteException) e).getErrorMessageStringResource());
+      showClientRemoteException((FxAccountClientRemoteException) e);
     } else {
       remoteErrorTextView.setText(defaultResourceId);
     }
     Logger.warn(LOG_TAG, "Got exception; showing error message: " + remoteErrorTextView.getText().toString(), e);
     remoteErrorTextView.setVisibility(View.VISIBLE);
   }
 
+  protected void showClientRemoteException(final FxAccountClientRemoteException e) {
+    remoteErrorTextView.setText(e.getErrorMessageStringResource());
+  }
+
   protected void addListeners() {
     TextChangedListener textChangedListener = new TextChangedListener();
     EditorActionListener editorActionListener = new EditorActionListener();
     FocusChangeListener focusChangeListener = new FocusChangeListener();
 
     emailEdit.addTextChangedListener(textChangedListener);
     emailEdit.setOnEditorActionListener(editorActionListener);
     emailEdit.setOnFocusChangeListener(focusChangeListener);
--- a/mobile/android/base/fxa/activities/FxAccountConfirmAccountActivity.java
+++ b/mobile/android/base/fxa/activities/FxAccountConfirmAccountActivity.java
@@ -12,16 +12,17 @@ import org.mozilla.gecko.background.comm
 import org.mozilla.gecko.background.fxa.FxAccountClient;
 import org.mozilla.gecko.background.fxa.FxAccountClient10.RequestDelegate;
 import org.mozilla.gecko.background.fxa.FxAccountClient20;
 import org.mozilla.gecko.background.fxa.FxAccountClientException.FxAccountClientRemoteException;
 import org.mozilla.gecko.fxa.authenticator.AndroidFxAccount;
 import org.mozilla.gecko.fxa.login.Engaged;
 import org.mozilla.gecko.fxa.login.State;
 import org.mozilla.gecko.fxa.login.State.StateLabel;
+import org.mozilla.gecko.sync.setup.activities.ActivityUtils;
 
 import android.content.Context;
 import android.os.Bundle;
 import android.view.View;
 import android.view.View.OnClickListener;
 import android.widget.TextView;
 import android.widget.Toast;
 
@@ -51,16 +52,24 @@ public class FxAccountConfirmAccountActi
     Logger.debug(LOG_TAG, "onCreate(" + icicle + ")");
 
     super.onCreate(icicle);
     setContentView(R.layout.fxaccount_confirm_account);
 
     verificationLinkTextView = (TextView) ensureFindViewById(null, R.id.verification_link_text, "verification link text");
     resendLink = ensureFindViewById(null, R.id.resend_confirmation_email_link, "resend confirmation email link");
     resendLink.setOnClickListener(this);
+
+    View backToBrowsingButton = ensureFindViewById(null, R.id.button, "back to browsing button");
+    backToBrowsingButton.setOnClickListener(new OnClickListener() {
+      @Override
+      public void onClick(View v) {
+        ActivityUtils.openURLInFennec(v.getContext(), null);
+      }
+    });
   }
 
   @Override
   public void onResume() {
     super.onResume();
     this.fxAccount = getAndroidFxAccount();
     if (fxAccount == null) {
       Logger.warn(LOG_TAG, "Could not get Firefox Account.");
--- a/mobile/android/base/fxa/activities/FxAccountCreateAccountActivity.java
+++ b/mobile/android/base/fxa/activities/FxAccountCreateAccountActivity.java
@@ -18,24 +18,27 @@ import org.mozilla.gecko.background.fxa.
 import org.mozilla.gecko.background.fxa.FxAccountClient10.RequestDelegate;
 import org.mozilla.gecko.background.fxa.FxAccountClient20;
 import org.mozilla.gecko.background.fxa.FxAccountClient20.LoginResponse;
 import org.mozilla.gecko.background.fxa.FxAccountClientException.FxAccountClientRemoteException;
 import org.mozilla.gecko.background.fxa.PasswordStretcher;
 import org.mozilla.gecko.background.fxa.QuickPasswordStretcher;
 import org.mozilla.gecko.fxa.FxAccountConstants;
 import org.mozilla.gecko.fxa.activities.FxAccountSetupTask.FxAccountCreateAccountTask;
-import org.mozilla.gecko.sync.setup.activities.ActivityUtils;
 
 import android.app.AlertDialog;
 import android.app.Dialog;
 import android.content.DialogInterface;
 import android.content.Intent;
 import android.os.Bundle;
 import android.os.SystemClock;
+import android.text.Spannable;
+import android.text.Spanned;
+import android.text.method.LinkMovementMethod;
+import android.text.style.ClickableSpan;
 import android.view.View;
 import android.view.View.OnClickListener;
 import android.widget.Button;
 import android.widget.CheckBox;
 import android.widget.EditText;
 import android.widget.ListView;
 import android.widget.ProgressBar;
 import android.widget.TextView;
@@ -59,87 +62,131 @@ public class FxAccountCreateAccountActiv
    */
   @Override
   public void onCreate(Bundle icicle) {
     Logger.debug(LOG_TAG, "onCreate(" + icicle + ")");
 
     super.onCreate(icicle);
     setContentView(R.layout.fxaccount_create_account);
 
-    TextView policyView = (TextView) ensureFindViewById(null, R.id.policy, "policy links");
-    final String linkTerms = getString(R.string.fxaccount_link_tos);
-    final String linkPrivacy = getString(R.string.fxaccount_link_pn);
-    final String linkedTOS = "<a href=\"" + linkTerms + "\">" + getString(R.string.fxaccount_policy_linktos) + "</a>";
-    final String linkedPN = "<a href=\"" + linkPrivacy + "\">" + getString(R.string.fxaccount_policy_linkprivacy) + "</a>";
-    policyView.setText(getString(R.string.fxaccount_create_account_policy_text, linkedTOS, linkedPN));
-    final boolean underlineLinks = true;
-    ActivityUtils.linkifyTextView(policyView, underlineLinks);
-
     emailEdit = (EditText) ensureFindViewById(null, R.id.email, "email edit");
     passwordEdit = (EditText) ensureFindViewById(null, R.id.password, "password edit");
     showPasswordButton = (Button) ensureFindViewById(null, R.id.show_password, "show password button");
     yearEdit = (EditText) ensureFindViewById(null, R.id.year_edit, "year edit");
     remoteErrorTextView = (TextView) ensureFindViewById(null, R.id.remote_error, "remote error text view");
     button = (Button) ensureFindViewById(null, R.id.button, "create account button");
     progressBar = (ProgressBar) ensureFindViewById(null, R.id.progress, "progress bar");
     chooseCheckBox = (CheckBox) ensureFindViewById(null, R.id.choose_what_to_sync_checkbox, "choose what to sync check box");
     selectedEngines = new HashMap<String, Boolean>();
 
     createCreateAccountButton();
     createYearEdit();
     addListeners();
     updateButtonState();
     createShowPasswordButton();
+    linkifyPolicy();
     createChooseCheckBox();
 
     View signInInsteadLink = ensureFindViewById(null, R.id.sign_in_instead_link, "sign in instead link");
     signInInsteadLink.setOnClickListener(new OnClickListener() {
       @Override
       public void onClick(View v) {
-        Intent intent = new Intent(FxAccountCreateAccountActivity.this, FxAccountSignInActivity.class);
-        intent.putExtra("email", emailEdit.getText().toString());
-        intent.putExtra("password", passwordEdit.getText().toString());
-        // Per http://stackoverflow.com/a/8992365, this triggers a known bug with
-        // the soft keyboard not being shown for the started activity. Why, Android, why?
-        intent.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
-        startActivityForResult(intent, CHILD_REQUEST_CODE);
+        final String email = emailEdit.getText().toString();
+        final String password = passwordEdit.getText().toString();
+        doSigninInstead(email, password);
       }
     });
 
     // Only set email/password in onCreate; we don't want to overwrite edited values onResume.
     if (getIntent() != null && getIntent().getExtras() != null) {
       Bundle bundle = getIntent().getExtras();
       emailEdit.setText(bundle.getString("email"));
       passwordEdit.setText(bundle.getString("password"));
     }
   }
 
+  protected void doSigninInstead(final String email, final String password) {
+    Intent intent = new Intent(this, FxAccountSignInActivity.class);
+    if (email != null) {
+      intent.putExtra("email", email);
+    }
+    if (password != null) {
+      intent.putExtra("password", password);
+    }
+    // Per http://stackoverflow.com/a/8992365, this triggers a known bug with
+    // the soft keyboard not being shown for the started activity. Why, Android, why?
+    intent.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
+    startActivityForResult(intent, CHILD_REQUEST_CODE);
+  }
+
+  @Override
+  protected void showClientRemoteException(final FxAccountClientRemoteException e) {
+    if (!e.isAccountAlreadyExists()) {
+      super.showClientRemoteException(e);
+      return;
+    }
+
+    // This horrible bit of special-casing is because we want this error message to
+    // contain a clickable, extra chunk of text, but we don't want to pollute
+    // the exception class with Android specifics.
+    final String clickablePart = getString(R.string.fxaccount_sign_in_button_label);
+    final String message = getString(e.getErrorMessageStringResource(), clickablePart);
+    final int clickableStart = message.lastIndexOf(clickablePart);
+    final int clickableEnd = clickableStart + clickablePart.length();
+
+    final Spannable span = Spannable.Factory.getInstance().newSpannable(message);
+    span.setSpan(new ClickableSpan() {
+      @Override
+      public void onClick(View widget) {
+        // Pass through the email address that already existed.
+        String email = e.body.getString("email");
+        if (email == null) {
+            email = emailEdit.getText().toString();
+        }
+        final String password = passwordEdit.getText().toString();
+        doSigninInstead(email, password);
+      }
+    }, clickableStart, clickableEnd, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+    remoteErrorTextView.setMovementMethod(LinkMovementMethod.getInstance());
+    remoteErrorTextView.setText(span);
+  }
+
   /**
    * We might have switched to the SignIn activity; if that activity
    * succeeds, feed its result back to the authenticator.
    */
   @Override
   public void onActivityResult(int requestCode, int resultCode, Intent data) {
     Logger.debug(LOG_TAG, "onActivityResult: " + requestCode);
     if (requestCode != CHILD_REQUEST_CODE || resultCode != RESULT_OK) {
       super.onActivityResult(requestCode, resultCode, data);
       return;
     }
     this.setResult(resultCode, data);
     this.finish();
   }
 
-  protected void createYearEdit() {
+  /**
+   * Return years to display in picker.
+   *
+   * @return 1990 or earlier, 1991, 1992, up to five years before current year.
+   *         (So, if it is currently 2014, up to 2009.)
+   */
+  protected String[] getYearItems() {
     int year = Calendar.getInstance().get(Calendar.YEAR);
     LinkedList<String> years = new LinkedList<String>();
-    for (int i = year - 5; i >= 1951; i--) {
+    years.add(getResources().getString(R.string.fxaccount_create_account_1990_or_earlier));
+    for (int i = 1991; i <= year - 5; i++) {
       years.add(Integer.toString(i));
     }
-    years.add(getResources().getString(R.string.fxaccount_create_account_1950_or_earlier));
-    yearItems = years.toArray(new String[0]);
+    return years.toArray(new String[0]);
+  }
+
+  protected void createYearEdit() {
+    yearItems = getYearItems();
 
     yearEdit.setOnClickListener(new OnClickListener() {
       @Override
       public void onClick(View v) {
         android.content.DialogInterface.OnClickListener listener = new Dialog.OnClickListener() {
           @Override
           public void onClick(DialogInterface dialog, int which) {
             yearEdit.setText(yearItems[which]);
--- a/mobile/android/base/fxa/activities/FxAccountGetStartedActivity.java
+++ b/mobile/android/base/fxa/activities/FxAccountGetStartedActivity.java
@@ -5,18 +5,18 @@
 package org.mozilla.gecko.fxa.activities;
 
 import java.util.Locale;
 
 import org.mozilla.gecko.AppConstants;
 import org.mozilla.gecko.R;
 import org.mozilla.gecko.background.common.log.Logger;
 import org.mozilla.gecko.background.fxa.FxAccountAgeLockoutHelper;
+import org.mozilla.gecko.fxa.FirefoxAccounts;
 import org.mozilla.gecko.fxa.FxAccountConstants;
-import org.mozilla.gecko.fxa.authenticator.FxAccountAuthenticator;
 import org.mozilla.gecko.sync.Utils;
 import org.mozilla.gecko.sync.setup.activities.ActivityUtils;
 
 import android.accounts.AccountAuthenticatorActivity;
 import android.content.Intent;
 import android.os.Bundle;
 import android.os.SystemClock;
 import android.view.View;
@@ -59,17 +59,17 @@ public class FxAccountGetStartedActivity
 
   @Override
   public void onResume() {
     super.onResume();
 
     Intent intent = null;
     if (FxAccountAgeLockoutHelper.isLockedOut(SystemClock.elapsedRealtime())) {
       intent = new Intent(this, FxAccountCreateAccountNotAllowedActivity.class);
-    } else if (FxAccountAuthenticator.firefoxAccountsExist(this)) {
+    } else if (FirefoxAccounts.firefoxAccountsExist(this)) {
       intent = new Intent(this, FxAccountStatusActivity.class);
     }
     if (intent != null) {
       this.setAccountAuthenticatorResult(null);
       setResult(RESULT_CANCELED);
       // Per http://stackoverflow.com/a/8992365, this triggers a known bug with
       // the soft keyboard not being shown for the started activity. Why, Android, why?
       intent.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
@@ -80,25 +80,31 @@ public class FxAccountGetStartedActivity
   }
 
   /**
    * We started the CreateAccount activity for a result; this returns it to the
    * authenticator.
    */
   @Override
   public void onActivityResult(int requestCode, int resultCode, Intent data) {
-    Logger.debug(LOG_TAG, "onActivityResult: " + requestCode);
+    Logger.debug(LOG_TAG, "onActivityResult: " + requestCode + ", " + resultCode);
     if (requestCode != CHILD_REQUEST_CODE) {
       super.onActivityResult(requestCode, resultCode, data);
       return;
     }
+
+    this.setResult(requestCode, data);
     if (data != null) {
       this.setAccountAuthenticatorResult(data.getExtras());
+
+      // We want to drop ourselves off the back stack if the user successfully
+      // created or signed in to an account. We can easily determine this by
+      // checking for the presence of response data.
+      this.finish();
     }
-    this.setResult(requestCode, data);
   }
 
   protected void linkifyOldFirefoxLink() {
     TextView oldFirefox = (TextView) findViewById(R.id.old_firefox);
     String text = getResources().getString(R.string.fxaccount_getting_started_old_firefox);
     String VERSION = AppConstants.MOZ_APP_VERSION;
     String OS = AppConstants.OS_TARGET;
     // We'll need to adjust this when we have active locale switching.
--- a/mobile/android/base/fxa/activities/FxAccountSignInActivity.java
+++ b/mobile/android/base/fxa/activities/FxAccountSignInActivity.java
@@ -54,19 +54,20 @@ public class FxAccountSignInActivity ext
     button = (Button) ensureFindViewById(null, R.id.button, "sign in button");
     progressBar = (ProgressBar) ensureFindViewById(null, R.id.progress, "progress bar");
 
     minimumPasswordLength = 1; // Minimal restriction on passwords entered to sign in.
     createSignInButton();
     addListeners();
     updateButtonState();
     createShowPasswordButton();
+    linkifyPolicy();
 
-    View signInInsteadLink = ensureFindViewById(null, R.id.create_account_link, "create account instead link");
-    signInInsteadLink.setOnClickListener(new OnClickListener() {
+    View createAccountInsteadLink = ensureFindViewById(null, R.id.create_account_link, "create account instead link");
+    createAccountInsteadLink.setOnClickListener(new OnClickListener() {
       @Override
       public void onClick(View v) {
         Intent intent = new Intent(FxAccountSignInActivity.this, FxAccountCreateAccountActivity.class);
         intent.putExtra("email", emailEdit.getText().toString());
         intent.putExtra("password", passwordEdit.getText().toString());
         // Per http://stackoverflow.com/a/8992365, this triggers a known bug with
         // the soft keyboard not being shown for the started activity. Why, Android, why?
         intent.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
--- a/mobile/android/base/fxa/activities/FxAccountVerifiedAccountActivity.java
+++ b/mobile/android/base/fxa/activities/FxAccountVerifiedAccountActivity.java
@@ -3,45 +3,43 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 package org.mozilla.gecko.fxa.activities;
 
 import org.mozilla.gecko.R;
 import org.mozilla.gecko.background.common.log.Logger;
 import org.mozilla.gecko.fxa.authenticator.AndroidFxAccount;
 import org.mozilla.gecko.fxa.login.State;
+import org.mozilla.gecko.sync.setup.activities.ActivityUtils;
 
 import android.os.Bundle;
-import android.widget.TextView;
+import android.view.View;
+import android.view.View.OnClickListener;
 
 /**
  * Activity which displays "Account verified" success screen.
  */
 public class FxAccountVerifiedAccountActivity extends FxAccountAbstractActivity {
   private static final String LOG_TAG = FxAccountVerifiedAccountActivity.class.getSimpleName();
 
   protected AndroidFxAccount fxAccount;
 
-  protected TextView emailText;
-
   public FxAccountVerifiedAccountActivity() {
     super(CANNOT_RESUME_WHEN_NO_ACCOUNTS_EXIST);
   }
 
   /**
    * {@inheritDoc}
    */
   @Override
   public void onCreate(Bundle icicle) {
     Logger.debug(LOG_TAG, "onCreate(" + icicle + ")");
 
     super.onCreate(icicle);
     setContentView(R.layout.fxaccount_account_verified);
-
-    emailText = (TextView) ensureFindViewById(null, R.id.email, "email text");
   }
 
   @Override
   public void onResume() {
     super.onResume();
     this.fxAccount = getAndroidFxAccount();
     if (fxAccount == null) {
       Logger.warn(LOG_TAG, "Could not get Firefox Account.");
@@ -51,11 +49,18 @@ public class FxAccountVerifiedAccountAct
     }
     State state = fxAccount.getState();
     if (!state.verified) {
       Logger.warn(LOG_TAG, "Firefox Account is not verified; not displaying verified account activity.");
       setResult(RESULT_CANCELED);
       finish();
       return;
     }
-    emailText.setText(fxAccount.getEmail());
+
+    View backToBrowsingButton = ensureFindViewById(null, R.id.button, "back to browsing button");
+    backToBrowsingButton.setOnClickListener(new OnClickListener() {
+      @Override
+      public void onClick(View v) {
+        ActivityUtils.openURLInFennec(v.getContext(), null);
+      }
+    });
   }
 }
--- a/mobile/android/base/fxa/authenticator/FxAccountAuthenticator.java
+++ b/mobile/android/base/fxa/authenticator/FxAccountAuthenticator.java
@@ -112,29 +112,9 @@ public class FxAccountAuthenticator exte
   @Override
   public Bundle updateCredentials(AccountAuthenticatorResponse response,
       Account account, String authTokenType, Bundle options)
           throws NetworkErrorException {
     Logger.debug(LOG_TAG, "updateCredentials");
 
     return null;
   }
-
-  /**
-   * Return Firefox Accounts.
-   *
-   * @param context Android context.
-   * @return Firefox Account objects.
-   */
-  public static Account[] getFirefoxAccounts(final Context context) {
-    return AccountManager.get(context).getAccountsByType(FxAccountConstants.ACCOUNT_TYPE);
-  }
-
-  /**
-   * Return true if at least one Firefox Account exists.
-   *
-   * @param context Android context.
-   * @return true if at least one Firefox Account exists.
-   */
-  public static boolean firefoxAccountsExist(final Context context) {
-    return getFirefoxAccounts(context).length > 0;
-  }
 }
--- a/mobile/android/base/home/DynamicPanel.java
+++ b/mobile/android/base/home/DynamicPanel.java
@@ -101,17 +101,17 @@ public class DynamicPanel extends HomeFr
         }
     }
 
     @Override
     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
         switch(mPanelConfig.getLayoutType()) {
             case FRAME:
                 final PanelDatasetHandler datasetHandler = new PanelDatasetHandler();
-                mLayout = new FramePanelLayout(getActivity(), mPanelConfig, datasetHandler);
+                mLayout = new FramePanelLayout(getActivity(), mPanelConfig, datasetHandler, mUrlOpenListener);
                 break;
 
             default:
                 throw new IllegalStateException("Unrecognized layout type in DynamicPanel");
         }
 
         Log.d(LOGTAG, "Created layout of type: " + mPanelConfig.getLayoutType());
 
--- a/mobile/android/base/home/FramePanelLayout.java
+++ b/mobile/android/base/home/FramePanelLayout.java
@@ -1,30 +1,31 @@
 /* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
  * 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/. */
 
 package org.mozilla.gecko.home;
 
+import org.mozilla.gecko.home.HomePager.OnUrlOpenListener;
 import org.mozilla.gecko.home.HomeConfig.PanelConfig;
 import org.mozilla.gecko.home.HomeConfig.ViewConfig;
 
 import android.content.Context;
 import android.util.Log;
 import android.view.View;
 
 class FramePanelLayout extends PanelLayout {
     private static final String LOGTAG = "GeckoFramePanelLayout";
 
     private final View mChildView;
     private final ViewConfig mChildConfig;
 
-    public FramePanelLayout(Context context, PanelConfig panelConfig, DatasetHandler datasetHandler) {
-        super(context, panelConfig, datasetHandler);
+    public FramePanelLayout(Context context, PanelConfig panelConfig, DatasetHandler datasetHandler, OnUrlOpenListener urlOpenListener) {
+        super(context, panelConfig, datasetHandler, urlOpenListener);
 
         // This layout can only hold one view so we simply
         // take the first defined view from PanelConfig.
         mChildConfig = panelConfig.getViewAt(0);
         if (mChildConfig == null) {
             throw new IllegalStateException("FramePanelLayout requires a view in PanelConfig");
         }
 
--- a/mobile/android/base/home/HomeListView.java
+++ b/mobile/android/base/home/HomeListView.java
@@ -25,17 +25,17 @@ import android.widget.ListView;
  */
 public class HomeListView extends ListView
                           implements OnItemLongClickListener {
 
     // ContextMenuInfo associated with the currently long pressed list item.
     private HomeContextMenuInfo mContextMenuInfo;
 
     // On URL open listener
-    private OnUrlOpenListener mUrlOpenListener;
+    protected OnUrlOpenListener mUrlOpenListener;
 
     // Top divider
     private boolean mShowTopDivider;
 
     // ContextMenuInfo maker
     private ContextMenuInfoFactory mContextMenuInfoFactory;
 
     public HomeListView(Context context) {
--- a/mobile/android/base/home/HomePager.java
+++ b/mobile/android/base/home/HomePager.java
@@ -63,17 +63,18 @@ public class HomePager extends ViewPager
     static final String LIST_TAG_READING_LIST = "reading_list";
     static final String LIST_TAG_TOP_SITES = "top_sites";
     static final String LIST_TAG_MOST_RECENT = "most_recent";
     static final String LIST_TAG_LAST_TABS = "last_tabs";
     static final String LIST_TAG_BROWSER_SEARCH = "browser_search";
 
     public interface OnUrlOpenListener {
         public enum Flags {
-            ALLOW_SWITCH_TO_TAB
+            ALLOW_SWITCH_TO_TAB,
+            OPEN_WITH_INTENT
         }
 
         public void onUrlOpen(String url, EnumSet<Flags> flags);
     }
 
     public interface OnNewTabsListener {
         public void onNewTabs(String[] urls);
     }
--- a/mobile/android/base/home/PanelLayout.java
+++ b/mobile/android/base/home/PanelLayout.java
@@ -1,15 +1,16 @@
 /* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
  * 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/. */
 
 package org.mozilla.gecko.home;
 
+import org.mozilla.gecko.home.HomePager.OnUrlOpenListener;
 import org.mozilla.gecko.home.HomeConfig.PanelConfig;
 import org.mozilla.gecko.home.HomeConfig.ViewConfig;
 
 import android.content.Context;
 import android.database.Cursor;
 import android.text.TextUtils;
 import android.util.Log;
 import android.view.View;
@@ -53,16 +54,17 @@ import java.util.List;
  * {@code PanelLayout} subclasses are free to have any type of views to arrange
  * the panel views in different ways.
  */
 abstract class PanelLayout extends FrameLayout {
     private static final String LOGTAG = "GeckoPanelLayout";
 
     private final List<ViewEntry> mViewEntries;
     private final DatasetHandler mDatasetHandler;
+    private final OnUrlOpenListener mUrlOpenListener;
 
     /**
      * To be used by panel views to express that they are
      * backed by datasets.
      */
     public interface DatasetBacked {
         public void setDataset(Cursor cursor);
     }
@@ -81,20 +83,25 @@ abstract class PanelLayout extends Frame
         /**
          * Releases any resources associated with a previously loaded
          * dataset. It will do nothing if the dataset with the given ID
          * hasn't been loaded before.
          */
         public void resetDataset(String datasetId);
     }
 
-    public PanelLayout(Context context, PanelConfig panelConfig, DatasetHandler datasetHandler) {
+    public interface PanelView {
+        public void setOnUrlOpenListener(OnUrlOpenListener listener);
+    }
+
+    public PanelLayout(Context context, PanelConfig panelConfig, DatasetHandler datasetHandler, OnUrlOpenListener urlOpenListener) {
         super(context);
         mViewEntries = new ArrayList<ViewEntry>();
         mDatasetHandler = datasetHandler;
+        mUrlOpenListener = urlOpenListener;
     }
 
     /**
      * Delivers the dataset as a {@code Cursor} to be bound to the
      * panel views backed by it. This is used by the {@code DatasetHandler}
      * in response to a dataset request.
      */
     public final void deliverDataset(String datasetId, Cursor cursor) {
@@ -150,16 +157,18 @@ abstract class PanelLayout extends Frame
 
             default:
                 throw new IllegalStateException("Unrecognized view type in " + getClass().getSimpleName());
         }
 
         final ViewEntry entry = new ViewEntry(view, viewConfig);
         mViewEntries.add(entry);
 
+        ((PanelView) view).setOnUrlOpenListener(mUrlOpenListener);
+
         return view;
     }
 
     /**
      * Dispose any dataset references associated with the
      * given view.
      */
     protected final void disposePanelView(View view) {
@@ -223,9 +232,9 @@ abstract class PanelLayout extends Frame
         public View getView() {
             return mView;
         }
 
         public String getDatasetId() {
             return mViewConfig.getDatasetId();
         }
     }
-}
\ No newline at end of file
+}
--- a/mobile/android/base/home/PanelListView.java
+++ b/mobile/android/base/home/PanelListView.java
@@ -2,39 +2,46 @@
  * 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/. */
 
 package org.mozilla.gecko.home;
 
 import org.mozilla.gecko.R;
 import org.mozilla.gecko.home.HomeConfig.ViewConfig;
+import org.mozilla.gecko.home.HomePager.OnUrlOpenListener;
 import org.mozilla.gecko.home.PanelLayout.DatasetBacked;
+import org.mozilla.gecko.home.PanelLayout.PanelView;
+import org.mozilla.gecko.db.BrowserContract.HomeItems;
 
 import android.content.Context;
 import android.database.Cursor;
 import android.support.v4.widget.CursorAdapter;
 import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
+import android.widget.AdapterView;
+
+import java.util.EnumSet;
 
 public class PanelListView extends HomeListView
-                           implements DatasetBacked {
+                           implements DatasetBacked, PanelView {
 
     private static final String LOGTAG = "GeckoPanelListView";
 
     private final PanelListAdapter mAdapter;
     private final ViewConfig mViewConfig;
 
     public PanelListView(Context context, ViewConfig viewConfig) {
         super(context);
         mViewConfig = viewConfig;
         mAdapter = new PanelListAdapter(context);
         setAdapter(mAdapter);
+        setOnItemClickListener(new PanelListItemClickListener());
     }
 
     @Override
     public void setDataset(Cursor cursor) {
         Log.d(LOGTAG, "Setting dataset: " + mViewConfig.getDatasetId());
         mAdapter.swapCursor(cursor);
     }
 
@@ -49,9 +56,24 @@ public class PanelListView extends HomeL
             row.updateFromCursor(cursor);
         }
 
         @Override
         public View newView(Context context, Cursor cursor, ViewGroup parent) {
             return LayoutInflater.from(parent.getContext()).inflate(R.layout.panel_list_row, parent, false);
         }
     }
-}
\ No newline at end of file
+
+    private class PanelListItemClickListener implements AdapterView.OnItemClickListener {
+        @Override
+        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+            Cursor cursor = mAdapter.getCursor();
+            if (cursor == null || !cursor.moveToPosition(position)) {
+                throw new IllegalStateException("Couldn't move cursor to position " + position);
+            }
+
+            int urlIndex = cursor.getColumnIndexOrThrow(HomeItems.URL);
+            final String url = cursor.getString(urlIndex);
+
+            mUrlOpenListener.onUrlOpen(url, EnumSet.of(OnUrlOpenListener.Flags.OPEN_WITH_INTENT));
+        }
+    }
+}
--- a/mobile/android/base/locales/en-US/android_strings.dtd
+++ b/mobile/android/base/locales/en-US/android_strings.dtd
@@ -61,17 +61,17 @@
      We can't use android plural forms, sadly. See bug #753859. -->
 <!ENTITY num_tabs2 "&formatD; tabs">
 <!ENTITY new_tab_opened "New tab opened">
 
 <!ENTITY settings "Settings">
 <!ENTITY settings_title "Settings">
 <!ENTITY pref_category_advanced "Advanced">
 <!ENTITY pref_category_customize "Customize">
-<!ENTITY pref_category_search2 "Search settings">
+<!ENTITY pref_category_search3 "Search">
 <!ENTITY pref_category_display "Display">
 <!ENTITY pref_category_privacy_short "Privacy">
 <!ENTITY pref_category_vendor "&vendorShortName;">
 <!ENTITY pref_category_datareporting "Data choices">
 <!ENTITY pref_category_installed_search_engines "Installed search engines">
 <!ENTITY pref_category_add_search_providers "Add more search providers">
 <!ENTITY pref_category_search_restore_defaults "Restore search engines">
 <!ENTITY pref_search_restore_defaults "Restore defaults">
--- a/mobile/android/base/locales/en-US/sync_strings.dtd
+++ b/mobile/android/base/locales/en-US/sync_strings.dtd
@@ -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/. -->
 
 <!-- Don't localize these. They're here until they have
      a better place to live. -->
 <!ENTITY syncBrand.fullName.label "Firefox Sync">
 <!ENTITY syncBrand.shortName.label "Sync">
 
-<!ENTITY fxaccountBrand.fullName.label "Firefox Account">
-
 <!-- Main titles. -->
 <!ENTITY sync.app.name.label '&syncBrand.fullName.label;'>
 <!ENTITY sync.title.connect.label 'Connect to &syncBrand.shortName.label;'>
 <!ENTITY sync.title.adddevice.label 'Add a &syncBrand.fullName.label; Account'>
 <!ENTITY sync.title.pair.label 'Pair a Device'>
 
 <!-- J-PAKE Key Screen -->
 <!ENTITY sync.subtitle.connect.label 'To activate your new device, select “Set up &syncBrand.shortName.label;” on the device.'>
@@ -67,20 +65,20 @@
 <!ENTITY sync.configure.engines.title.passwords 'Passwords'>
 <!ENTITY sync.configure.engines.title.history 'History'>
 <!ENTITY sync.configure.engines.title.tabs 'Tabs'>
 
 <!-- Common text -->
 <!ENTITY sync.button.cancel.label 'Cancel'>
 <!ENTITY sync.button.connect.label 'Connect'>
 <!ENTITY sync.button.ok.label 'OK'>
-  
+
 <!-- Account strings -->
-<!ENTITY sync.account.label.label '&syncBrand.fullName.label;'>
-  
+<!ENTITY sync.account.label '&syncBrand.fullName.label; (deprecated)'>
+
 <!-- Bookmark folder strings -->
 <!ENTITY bookmarks.folder.menu.label 'Bookmarks Menu'>
 <!ENTITY bookmarks.folder.places.label ''>
 <!ENTITY bookmarks.folder.tags.label 'Tags'>
 <!ENTITY bookmarks.folder.toolbar.label 'Bookmarks Toolbar'>
 <!ENTITY bookmarks.folder.unfiled.label 'Unsorted Bookmarks'>
 <!ENTITY bookmarks.folder.desktop.label 'Desktop Bookmarks'>
 <!ENTITY bookmarks.folder.mobile.label 'Mobile Bookmarks'>
@@ -102,116 +100,119 @@
 <!ENTITY sync.title.send.tab.label 'Send Tab To Devices'>
 <!ENTITY sync.button.send.label 'Send'>
 <!ENTITY sync.button.set.up.sync.label 'Set up &syncBrand.shortName.label;'>
 <!ENTITY sync.title.redirect.to.set.up.sync.label 'Set up &syncBrand.shortName.label; to send tabs'>
 <!ENTITY sync.text.redirect.to.set.up.sync.label 'Set up &syncBrand.fullName.label; on your device to send tabs to other devices.'>
 <!ENTITY sync.text.tab.sent.label 'Your tab was sent!'>
 <!ENTITY sync.text.tab.not.sent.label 'There was a problem sending your tab.'>
 
-<!-- Firefox Account strings -->
-
-<!-- Localization note: this is the brand title, shown at the top of most screens. -->
-<!ENTITY firefox_accounts 'Firefox Accounts'>
-
-<!-- Localization note: this refers to a single Firefox Account, shown
-     at the top of the account status activity. That activity allows
-     to configure the current Firefox Account. -->
-<!ENTITY firefox_account 'Firefox Account'>
+<!-- Firefox account strings. -->
 
 <!-- Localization note: these describe icons and graphics, and are
      consumed by assistive devices. -->
-<!ENTITY fxaccount_checkbox_contentDescription 'Firefox Accounts checkbox graphic'>
-<!ENTITY fxaccount_icon_contentDescription 'Firefox Accounts icon'>
-<!ENTITY fxaccount_intro_contentDescription 'Firefox Accounts introduction graphics'>
-<!ENTITY fxaccount_mail_contentDescription 'Firefox Accounts envelope graphic'>
+<!ENTITY fxaccount_checkbox_contentDescription2 'Firefox accounts checkbox graphic'>
+<!ENTITY fxaccount_icon_contentDescription2 'Firefox accounts icon'>
+<!ENTITY fxaccount_intro_contentDescription2 'Firefox accounts introduction graphics'>
+<!ENTITY fxaccount_mail_contentDescription2 'Firefox accounts envelope graphic'>
 
 <!-- Localization note: these are shown in all screens that query the
      user for an email address and password. Hide and show are button
      labels. -->
 <!ENTITY fxaccount_email_hint 'Email'>
 <!ENTITY fxaccount_password_hint 'Password'>
 <!ENTITY fxaccount_password_hide 'Hide'>
 <!ENTITY fxaccount_password_show 'Show'>
 
+<!-- Localization note: these are shown in screens after the user has
+     created or signed in to an account, and take the user back to
+     Firefox. -->
+<!ENTITY fxaccount_back_to_browsing 'Back to browsing'>
+
 <!ENTITY fxaccount_policy_linktos 'Terms of Service'>
 <!ENTITY fxaccount_policy_linkprivacy 'Privacy Notice'>
 
 <!ENTITY fxaccount_getting_started_welcome_to_sync 'Welcome to &syncBrand.shortName.label;'>
 <!ENTITY fxaccount_getting_started_description 'Sign in to sync your tabs, bookmarks, passwords &amp; more.'>
 <!ENTITY fxaccount_getting_started_get_started 'Get started'>
 <!ENTITY fxaccount_getting_started_old_firefox 'Using an older version of &syncBrand.shortName.label;?'>
 
-<!ENTITY fxaccount_create_account_sub_header 'Create an account'>
+<!-- Localization note: the Firefox below should not change with the
+     particular version of Firefox installed (Release, Beta, Aurora,
+     etc).  The account remains a "Firefox" account. -->
+<!ENTITY fxaccount_create_account_header 'Create a Firefox account'>
 <!ENTITY fxaccount_create_account_password_length_restriction 'Must be at least 8 characters'>
 <!ENTITY fxaccount_create_account_year_of_birth 'Year of birth'>
 <!-- Localization note: &formatS1; is fxaccount_policy_linktos, &formatS2; is fxaccount_policy_linkprivacy, both hyperlinked. -->
 <!ENTITY fxaccount_create_account_policy_text 'By proceeding, I agree to the &formatS1; and &formatS2; of Firefox online services.'>
 <!ENTITY fxaccount_create_account_button 'Next'>
 <!ENTITY fxaccount_create_account_choose_what_to_sync 'Choose what to sync'>
 <!ENTITY fxaccount_create_account_sign_in_instead 'Already have an account? Sign in'>
-<!ENTITY fxaccount_create_account_1950_or_earlier '1950 or earlier'>
+<!ENTITY fxaccount_create_account_1990_or_earlier '1990 or earlier'>
 <!ENTITY fxaccount_create_account_unknown_error 'Could not create account'>
 
 <!ENTITY fxaccount_account_create_not_allowed 'Cannot create account'>
 <!ENTITY fxaccount_account_create_not_allowed_you_must_meet_certain_age_requirements 'You must meet certain age requirements to create an account.'>
 <!ENTITY fxaccount_account_create_not_allowed_learn_more 'Learn more'>
 
 <!ENTITY fxaccount_confirm_account_header 'Confirm your account'>
-<!-- Localization note: &formatS; is the Firefox Account's email address. -->
+<!-- Localization note: &formatS; is the Firefox account's email address. -->
 <!ENTITY fxaccount_confirm_account_verification_link 'A verification link has been sent to &formatS;'>
 <!ENTITY fxaccount_confirm_account_resend_email 'Resend email'>
-<!ENTITY fxaccount_confirm_account_verification_link_sent 'Sent fresh verification link'>
-<!ENTITY fxaccount_confirm_account_verification_link_not_sent 'Couldn\&apos;t send a fresh verification link'>
+<!ENTITY fxaccount_confirm_account_verification_link_sent2 'Verification email sent'>
+<!ENTITY fxaccount_confirm_account_verification_link_not_sent2 'Couldn\&apos;t send verification email'>
 
 <!ENTITY fxaccount_sign_in_sub_header 'Sign in'>
 <!ENTITY fxaccount_sign_in_button_label 'Sign in'>
 <!ENTITY fxaccount_sign_in_forgot_password 'Forgot password?'>
 <!ENTITY fxaccount_sign_in_create_account_instead 'Create an account'>
 <!ENTITY fxaccount_sign_in_unknown_error 'Could not sign in'>
 
 <!ENTITY fxaccount_account_verified_sub_header 'Account verified'>
-<!ENTITY fxaccount_account_verified_description 'You are now ready to use &syncBrand.shortName.label;.'>
+<!ENTITY fxaccount_account_verified_description2 'Your data will begin syncing momentarily.'>
 
-<!ENTITY fxaccount_update_credentials_sub_header 'Sign in to continue'>
+<!ENTITY fxaccount_update_credentials_header 'Sign in'>
 <!ENTITY fxaccount_update_credentials_button_label 'Sign in'>
 <!ENTITY fxaccount_update_credentials_unknown_error 'Could not sign in'>
 
+<!ENTITY fxaccount_status_header 'Firefox account'>
 <!ENTITY fxaccount_status_sync '&syncBrand.shortName.label;'>
 <!ENTITY fxaccount_status_sync_enabled '&syncBrand.shortName.label;: enabled'>
-<!ENTITY fxaccount_status_needs_verification 'Your account needs to be verified. Tap to verify.'>
+<!ENTITY fxaccount_status_needs_verification2 'Your account needs to be verified. Tap to resend verification email.'>
 <!ENTITY fxaccount_status_needs_credentials 'Cannot connect. Tap to sign in.'>
 <!ENTITY fxaccount_status_needs_upgrade 'You need to upgrade &brandShortName; to sign in.'>
 <!ENTITY fxaccount_status_bookmarks 'Bookmarks'>
 <!ENTITY fxaccount_status_history 'History'>
 <!ENTITY fxaccount_status_passwords 'Passwords'>
 <!ENTITY fxaccount_status_tabs 'Open tabs'>
 <!ENTITY fxaccount_status_legal 'Legal' >
 
 <!-- Localization note: this is the name shown by the Android system
-     itself for a Firefox Account. It should be singular. -->
-<!ENTITY fxaccount_label '&fxaccountBrand.fullName.label;'>
+     itself for a Firefox account. Don't localize this. -->
+<!ENTITY fxaccount_account_type_label 'Firefox'>
 
 <!-- Localization note: these are shown by the Android system itself,
      when the user navigates to the Android > Accounts > [Firefox
-     Account] Screen. The link takes the user to the Firefox Account
+     Account] Screen. The link takes the user to the Firefox account
      status activity, which lets them manage their Firefox
-     Account. -->
+     account. -->
 <!ENTITY fxaccount_options_title '&syncBrand.shortName.label; Options'>
 <!ENTITY fxaccount_options_configure_title 'Configure &syncBrand.shortName.label;'>
 
 <!-- Localization note: these error messages are shown after a request
      has been made to the remote server, and an error of some type has
      been returned. -->
 <!ENTITY fxaccount_remote_error_UPGRADE_REQUIRED 'You need to upgrade Firefox'>
-<!ENTITY fxaccount_remote_error_ATTEMPT_TO_CREATE_AN_ACCOUNT_THAT_ALREADY_EXISTS 'Account already exists'>
+
+<!-- Localization note: the format string will be fxaccount_sign_in_button_label, linkified. -->
+<!ENTITY fxaccount_remote_error_ATTEMPT_TO_CREATE_AN_ACCOUNT_THAT_ALREADY_EXISTS_2 'Account already exists. &formatS1;'>
 <!ENTITY fxaccount_remote_error_ATTEMPT_TO_ACCESS_AN_ACCOUNT_THAT_DOES_NOT_EXIST 'Invalid email or password'>
 <!ENTITY fxaccount_remote_error_INCORRECT_PASSWORD 'Invalid email or password'>
 <!ENTITY fxaccount_remote_error_ATTEMPT_TO_OPERATE_ON_AN_UNVERIFIED_ACCOUNT 'Account is not verified'>
 <!ENTITY fxaccount_remote_error_CLIENT_HAS_SENT_TOO_MANY_REQUESTS 'Server busy, try again soon'>
 <!ENTITY fxaccount_remote_error_SERVICE_TEMPORARILY_UNAVAILABLE_TO_DUE_HIGH_LOAD 'Server busy, try again soon'>
 <!ENTITY fxaccount_remote_error_UNKNOWN_ERROR 'There was a problem'>
 <!ENTITY fxaccount_remote_error_COULD_NOT_CONNECT 'Cannot connect to network'>
 
-<!ENTITY fxaccount_sync_sign_in_error_notification_title '&syncBrand.fullName.label; is not connected'>
+<!ENTITY fxaccount_sync_sign_in_error_notification_title2 '&syncBrand.shortName.label; is not connected'>
 <!-- Note to translators: the format string below will be replaced
-     with the Firefox Account's email address. -->
-<!ENTITY fxaccount_sync_sign_in_error_notification_text 'Tap to sign in to &formatS;'>
+     with the Firefox account's email address. -->
+<!ENTITY fxaccount_sync_sign_in_error_notification_text2 'Tap to sign in as &formatS;'>
--- a/mobile/android/base/preferences/SyncPreference.java
+++ b/mobile/android/base/preferences/SyncPreference.java
@@ -10,16 +10,18 @@ import org.mozilla.gecko.sync.setup.Sync
 import org.mozilla.gecko.sync.setup.activities.SetupSyncActivity;
 
 import android.content.Context;
 import android.content.Intent;
 import android.preference.Preference;
 import android.util.AttributeSet;
 
 class SyncPreference extends Preference {
+    private static final boolean DEFAULT_TO_FXA = false;
+
     private Context mContext;
 
     public SyncPreference(Context context, AttributeSet attrs) {
         super(context, attrs);
         mContext = context;
     }
 
     private void openSync11Settings() {
@@ -35,11 +37,26 @@ class SyncPreference extends Preference 
     private void launchFxASetup() {
         Intent intent = new Intent(mContext, FxAccountGetStartedActivity.class);
         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
         mContext.startActivity(intent);
     }
 
     @Override
     protected void onClick() {
-        openSync11Settings();
+        // If we're not defaulting to FxA, just do what we've always done.
+        if (!DEFAULT_TO_FXA) {
+            openSync11Settings();
+            return;
+        }
+
+        // If there's a legacy Sync account (or a pickled one on disk),
+        // open the settings page.
+        if (SyncAccounts.syncAccountsExist(mContext)) {
+            SyncAccounts.openSyncSettings(mContext);
+            return;
+        }
+
+        // Otherwise, launch the FxA "Get started" activity, which will
+        // dispatch to the right location.
+        launchFxASetup();
     }
 }
--- a/mobile/android/base/resources/layout/fxaccount_account_verified.xml
+++ b/mobile/android/base/resources/layout/fxaccount_account_verified.xml
@@ -8,47 +8,38 @@
     android:layout_width="fill_parent"
     android:layout_height="fill_parent"
     android:fillViewport="true" >
 
     <LinearLayout style="@style/FxAccountMiddle" >
 
         <TextView
             style="@style/FxAccountHeaderItem"
-            android:text="@string/firefox_accounts" >
-        </TextView>
-
-        <TextView
-            style="@style/FxAccountSubHeaderItem"
             android:text="@string/fxaccount_account_verified_sub_header" >
         </TextView>
 
         <ImageView
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_gravity="center_horizontal"
             android:layout_marginBottom="45dp"
             android:contentDescription="@string/fxaccount_checkbox_contentDescription"
             android:src="@drawable/fxaccount_checkbox" >
         </ImageView>
 
         <TextView
             style="@style/FxAccountTextItem"
-            android:layout_marginBottom="15dp"
+            android:layout_marginBottom="40dp"
             android:text="@string/fxaccount_account_verified_description"
-            android:textSize="18sp" >
-        </TextView>
+            android:textSize="18sp" />
 
-        <TextView
-            android:id="@+id/email"
-            style="@style/FxAccountTextItem"
-            android:layout_marginBottom="45dp"
-            android:textSize="20sp"
-            android:textStyle="bold" >
-        </TextView>
+        <Button
+            android:id="@+id/button"
+            style="@style/FxAccountButton"
+            android:text="@string/fxaccount_back_to_browsing" />
 
         <LinearLayout style="@style/FxAccountSpacer" />
 
         <ImageView
             style="@style/FxAccountIcon"
             android:contentDescription="@string/fxaccount_icon_contentDescription" />
     </LinearLayout>
 
--- a/mobile/android/base/resources/layout/fxaccount_confirm_account.xml
+++ b/mobile/android/base/resources/layout/fxaccount_confirm_account.xml
@@ -10,41 +10,40 @@
     android:fillViewport="true" >
 
     <LinearLayout style="@style/FxAccountMiddle" >
 
         <LinearLayout style="@style/FxAccountSpacer" />
 
         <TextView
             style="@style/FxAccountHeaderItem"
-            android:text="@string/firefox_accounts" >
-        </TextView>
-
-        <TextView
-            style="@style/FxAccountSubHeaderItem"
             android:text="@string/fxaccount_confirm_account_header" >
         </TextView>
 
         <ImageView
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_gravity="center_horizontal"
-            android:layout_marginBottom="45dp"
+            android:layout_marginBottom="40dp"
             android:background="@android:color/transparent"
             android:contentDescription="@string/fxaccount_mail_contentDescription"
             android:src="@drawable/fxaccount_mail" >
         </ImageView>
 
         <TextView
             android:id="@+id/verification_link_text"
             style="@style/FxAccountTextItem"
-            android:layout_marginBottom="15dp"
+            android:layout_marginBottom="40dp"
             android:text="@string/fxaccount_confirm_account_verification_link"
-            android:textSize="18sp" >
-        </TextView>
+            android:textSize="18sp" />
+
+        <Button
+            android:id="@+id/button"
+            style="@style/FxAccountButton"
+            android:text="@string/fxaccount_back_to_browsing" />
 
         <TextView
             android:id="@+id/resend_confirmation_email_link"
             style="@style/FxAccountLinkItem"
             android:text="@string/fxaccount_confirm_account_resend_email" />
 
         <LinearLayout style="@style/FxAccountSpacer" />
 
--- a/mobile/android/base/resources/layout/fxaccount_create_account.xml
+++ b/mobile/android/base/resources/layout/fxaccount_create_account.xml
@@ -13,62 +13,65 @@
     <LinearLayout
         android:id="@+id/create_account_view"
         style="@style/FxAccountMiddle" >
 
         <LinearLayout style="@style/FxAccountSpacer" />
 
         <TextView
             style="@style/FxAccountHeaderItem"
-            android:text="@string/firefox_accounts" />
-
-        <TextView
-            style="@style/FxAccountSubHeaderItem"
-            android:text="@string/fxaccount_create_account_sub_header" />
+            android:text="@string/fxaccount_create_account_header" />
 
         <include layout="@layout/fxaccount_email_password_view" />
 
         <TextView
             style="@style/FxAccountTextItem"
             android:layout_marginTop="10dp"
-            android:text="@string/fxaccount_create_account_password_length_restriction" />
+            android:text="@string/fxaccount_create_account_password_length_restriction"
+            android:textColor="@color/fxaccount_textColorSubdued" />
 
         <!-- Per http://stackoverflow.com/questions/2359176/android-edittext-onclicklistener, not allowing focus allows us to highjack the click. -->
 
         <EditText
             android:id="@+id/year_edit"
             style="@style/FxAccountEditItem"
-            android:layout_marginTop="10dp"
             android:drawableRight="@drawable/fxaccount_ddarrow_inactive"
             android:focusable="false"
             android:hint="@string/fxaccount_create_account_year_of_birth"
             android:inputType="none" />
 
         <TextView
             android:id="@+id/policy"
             style="@style/FxAccountLinkifiedItem"
+            android:layout_marginBottom="0dp"
             android:layout_marginTop="10dp"
             android:text="@string/fxaccount_create_account_policy_text"
             android:textColorLink="@color/fxaccount_linkified_textColorLinkSubdued" />
 
         <TextView
             android:id="@+id/remote_error"
             style="@style/FxAccountErrorItem" />
 
-        <FrameLayout style="@style/FxAccountButtonLayout" >
+        <RelativeLayout
+            style="@style/FxAccountButtonLayout"
+            android:layout_marginBottom="10dp" >
 
             <ProgressBar
                 android:id="@+id/progress"
-                style="@style/FxAccountProgress" />
+                style="@style/FxAccountProgress"
+                android:layout_alignBottom="@id/button"
+                android:layout_alignLeft="@id/button"
+                android:layout_alignRight="@id/button"
+                android:layout_alignTop="@id/button" />
 
             <Button
                 android:id="@+id/button"
                 style="@style/FxAccountButton"
                 android:text="@string/fxaccount_create_account_button" />
-        </FrameLayout>
+        </RelativeLayout>
 
         <CheckBox
             android:id="@+id/choose_what_to_sync_checkbox"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_gravity="center_horizontal"
             android:layout_margin="0dp"
             android:text="@string/fxaccount_create_account_choose_what_to_sync" />
--- a/mobile/android/base/resources/layout/fxaccount_create_account_not_allowed.xml
+++ b/mobile/android/base/resources/layout/fxaccount_create_account_not_allowed.xml
@@ -12,21 +12,16 @@
     <LinearLayout
         android:id="@+id/create_account_not_allowed_view"
         style="@style/FxAccountMiddle" >
 
         <LinearLayout style="@style/FxAccountSpacer" />
 
         <TextView
             style="@style/FxAccountHeaderItem"
-            android:text="@string/firefox_accounts" >
-        </TextView>
-
-        <TextView
-            style="@style/FxAccountSubHeaderItem"
             android:text="@string/fxaccount_account_create_not_allowed" >
         </TextView>
 
         <TextView
             style="@style/FxAccountTextItem"
             android:layout_marginBottom="45dp"
             android:layout_marginTop="45dp"
             android:text="@string/fxaccount_account_create_not_allowed_you_must_meet_certain_age_requirements" >
@@ -39,9 +34,9 @@
 
         <LinearLayout style="@style/FxAccountSpacer" />
 
         <ImageView
             style="@style/FxAccountIcon"
             android:contentDescription="@string/fxaccount_icon_contentDescription" />
     </LinearLayout>
 
-</ScrollView>
\ No newline at end of file
+</ScrollView>
--- a/mobile/android/base/resources/layout/fxaccount_sign_in.xml
+++ b/mobile/android/base/resources/layout/fxaccount_sign_in.xml
@@ -13,39 +13,39 @@
     <LinearLayout
         android:id="@+id/sign_in_view"
         style="@style/FxAccountMiddle" >
 
         <LinearLayout style="@style/FxAccountSpacer" />
 
         <TextView
             style="@style/FxAccountHeaderItem"
-            android:text="@string/firefox_accounts" />
-
-        <TextView
-            style="@style/FxAccountSubHeaderItem"
             android:text="@string/fxaccount_sign_in_sub_header" />
 
         <include layout="@layout/fxaccount_email_password_view" />
 
         <TextView
             android:id="@+id/remote_error"
             style="@style/FxAccountErrorItem" />
 
-        <FrameLayout style="@style/FxAccountButtonLayout" >
+        <RelativeLayout style="@style/FxAccountButtonLayout" >
 
             <ProgressBar
                 android:id="@+id/progress"
-                style="@style/FxAccountProgress" />
+                style="@style/FxAccountProgress"
+                android:layout_alignBottom="@id/button"
+                android:layout_alignLeft="@id/button"
+                android:layout_alignRight="@id/button"
+                android:layout_alignTop="@id/button" />
 
             <Button
                 android:id="@+id/button"
                 style="@style/FxAccountButton"
                 android:text="@string/fxaccount_sign_in_button_label" />
-        </FrameLayout>
+        </RelativeLayout>
 
         <LinearLayout
             android:layout_width="fill_parent"
             android:layout_height="wrap_content"
             android:layout_marginTop="10dp"
             android:orientation="horizontal" >
 
             <TextView
@@ -60,16 +60,23 @@
                 android:id="@+id/create_account_link"
                 style="@style/FxAccountLinkItem"
                 android:layout_gravity="right"
                 android:layout_weight="1"
                 android:gravity="right"
                 android:text="@string/fxaccount_sign_in_create_account_instead" />
         </LinearLayout>
 
+        <TextView
+            android:id="@+id/policy"
+            style="@style/FxAccountLinkifiedItem"
+            android:layout_marginTop="10dp"
+            android:text="@string/fxaccount_create_account_policy_text"
+            android:textColorLink="@color/fxaccount_linkified_textColorLinkSubdued" />
+
         <LinearLayout style="@style/FxAccountSpacer" />
 
         <ImageView
             style="@style/FxAccountIcon"
             android:contentDescription="@string/fxaccount_icon_contentDescription" />
     </LinearLayout>
 
-</ScrollView>
+</ScrollView>
\ No newline at end of file
--- a/mobile/android/base/resources/layout/fxaccount_status.xml
+++ b/mobile/android/base/resources/layout/fxaccount_status.xml
@@ -11,36 +11,30 @@
     android:fillViewport="true" >
 
     <LinearLayout
         android:id="@+id/existing_user"
         style="@style/FxAccountMiddle" >
 
         <TextView
             style="@style/FxAccountHeaderItem"
-            android:text="@string/firefox_account" >
+            android:text="@string/fxaccount_status_header" >
         </TextView>
 
         <TextView
             android:id="@+id/email"
-            style="@style/FxAccountSubHeaderItem" >
+            style="@style/FxAccountTextItem" >
         </TextView>
 
         <TextView
             android:id="@+id/sync_status_text"
             style="@style/FxAccountHeaderItem"
             android:text="@string/fxaccount_status_sync" >
         </TextView>
 
-        <LinearLayout
-            android:id="@+id/spacer1"
-            android:layout_width="fill_parent"
-            android:layout_height="20dp"
-            android:orientation="vertical" />
-
         <ViewFlipper
             android:id="@+id/connection_status_view"
             style="@style/FxAccountTextItem"
             android:layout_width="fill_parent"
             android:layout_height="wrap_content" >
 
             <TextView
                 android:id="@+id/needs_upgrade_view"
@@ -105,22 +99,16 @@
             style="@style/FxAccountCheckBox"
             android:text="@string/fxaccount_status_passwords" />
 
         <TextView
             style="@style/FxAccountHeaderItem"
             android:text="@string/fxaccount_status_legal" >
         </TextView>
 
-        <LinearLayout
-            android:id="@+id/spacer2"
-            android:layout_width="fill_parent"
-            android:layout_height="20dp"
-            android:orientation="vertical" />
-
         <TextView
             android:id="@+id/fxaccount_status_linktos"
             style="@style/FxAccountLinkifiedItem"
             android:text="@string/fxaccount_policy_linktos" />
 
         <TextView
             android:id="@+id/fxaccount_status_linkprivacy"
             style="@style/FxAccountLinkifiedItem"
--- a/mobile/android/base/resources/layout/fxaccount_update_credentials.xml
+++ b/mobile/android/base/resources/layout/fxaccount_update_credentials.xml
@@ -13,45 +13,45 @@
     <LinearLayout
         android:id="@+id/update_credentials_view"
         style="@style/FxAccountMiddle" >
 
         <LinearLayout style="@style/FxAccountSpacer" />
 
         <TextView
             style="@style/FxAccountHeaderItem"
-            android:text="@string/firefox_accounts" />
-
-        <TextView
-            style="@style/FxAccountSubHeaderItem"
-            android:text="@string/fxaccount_update_credentials_sub_header" />
+            android:text="@string/fxaccount_update_credentials_header" />
 
         <include layout="@layout/fxaccount_email_password_view" />
 
         <TextView
             android:id="@+id/remote_error"
             style="@style/FxAccountErrorItem" />
 
-        <FrameLayout style="@style/FxAccountButtonLayout" >
+        <RelativeLayout style="@style/FxAccountButtonLayout" >
 
             <ProgressBar
                 android:id="@+id/progress"
-                style="@style/FxAccountProgress" />
+                style="@style/FxAccountProgress"
+                android:layout_alignBottom="@id/button"
+                android:layout_alignLeft="@id/button"
+                android:layout_alignRight="@id/button"
+                android:layout_alignTop="@id/button" />
 
             <Button
                 android:id="@+id/button"
                 style="@style/FxAccountButton"
                 android:text="@string/fxaccount_update_credentials_button_label" />
-        </FrameLayout>
+        </RelativeLayout>
 
         <TextView
             android:id="@+id/forgot_password_link"
             style="@style/FxAccountLinkifiedItem"
             android:text="@string/fxaccount_sign_in_forgot_password" />
 
         <LinearLayout style="@style/FxAccountSpacer" />
 
         <ImageView
             style="@style/FxAccountIcon"
             android:contentDescription="@string/fxaccount_icon_contentDescription" />
     </LinearLayout>
 
-</ScrollView>
+</ScrollView>
\ No newline at end of file
--- a/mobile/android/base/resources/values/fxaccount_colors.xml
+++ b/mobile/android/base/resources/values/fxaccount_colors.xml
@@ -1,18 +1,16 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!-- 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/. -->
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android">
-  <color name="fxaccount_error_dark">#FDEBE5</color>
-  <color name="fxaccount_error_light">#E24B03</color>
-
-  <color name="fxaccount_textColor">#3c454d</color>
+  <color name="fxaccount_textColor">#424f59</color>
+  <color name="fxaccount_textColorSubdued">#c0c9d0</color>
 
   <color name="fxaccount_linkified_textColor">#c0c9d0</color>
   <color name="fxaccount_linkified_textColorLink">#0096dd</color>
   <color name="fxaccount_linkified_textColorLinkSubdued">#c0c9d0</color>
 
   <color name="fxaccount_error">#d63920</color>
   <color name="fxaccount_button_textColor">#ffffff</color>
   <color name="fxaccount_button_background_active">#e66000</color>
--- a/mobile/android/base/resources/values/fxaccount_styles.xml
+++ b/mobile/android/base/resources/values/fxaccount_styles.xml
@@ -25,22 +25,16 @@
         <item name="android:orientation">vertical</item>
         <item name="android:layout_width">fill_parent</item>
         <item name="android:layout_height">0dp</item>
         <item name="android:layout_weight">1</item>
     </style>
 
     <style name="FxAccountHeaderItem" parent="@style/FxAccountTextItem">
         <item name="android:textSize">28sp</item>
-        <item name="android:layout_margin">0dp</item>
-    </style>
-
-    <style name="FxAccountSubHeaderItem" parent="@style/FxAccountTextItem">
-        <item name="android:textSize">24sp</item>
-        <item name="android:layout_marginTop">20dp</item>
         <item name="android:layout_marginBottom">20dp</item>
     </style>
 
     <style name="FxAccountTextItem" parent="@android:style/TextAppearance.Medium">
         <item name="android:textColor">@color/fxaccount_textColor</item>
         <item name="android:layout_width">fill_parent</item>
         <item name="android:layout_height">wrap_content</item>
         <item name="android:gravity">center_horizontal</item>
@@ -98,16 +92,17 @@
         <item name="android:layout_marginBottom">10dp</item>
         <item name="android:layout_marginTop">10dp</item>
         <item name="android:layout_height">wrap_content</item>
         <item name="android:gravity">center_horizontal</item>
         <item name="android:background">@drawable/fxaccount_textview_error_background</item>
         <item name="android:padding">5dp</item>
         <item name="android:text">Error</item>
         <item name="android:textColor">@android:color/white</item>
+        <item name="android:textColorLink">@android:color/white</item>
         <item name="android:textSize">18sp</item>
         <item name="android:visibility">invisible</item>
     </style>
 
     <style name="FxAccountProgress">
         <item name="android:layout_width">fill_parent</item>
         <item name="android:layout_height">fill_parent</item>
         <item name="android:background">@drawable/fxaccount_button_background</item>
--- a/mobile/android/base/resources/xml-v11/preferences_customize.xml
+++ b/mobile/android/base/resources/xml-v11/preferences_customize.xml
@@ -4,46 +4,45 @@
    - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
 
 <!-- Changes should be mirrored to preferences_customize_tablet.xml. -->
 
 <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
                   xmlns:gecko="http://schemas.android.com/apk/res-auto"
                   android:enabled="false">
 
+    <PreferenceScreen android:title="@string/pref_category_home"
+                      android:fragment="org.mozilla.gecko.preferences.GeckoPreferenceFragment" >
+            <extra android:name="resource"
+                   android:value="preferences_home" />
+    </PreferenceScreen>
+
      <PreferenceScreen android:title="@string/pref_category_search"
                        android:fragment="org.mozilla.gecko.preferences.GeckoPreferenceFragment" >
          <extra android:name="resource"
                 android:value="preferences_search"/>
      </PreferenceScreen>
 
-
-    <PreferenceScreen android:title="@string/pref_category_home"
-                      android:fragment="org.mozilla.gecko.preferences.GeckoPreferenceFragment" >
-            <extra android:name="resource"
-                   android:value="preferences_home" />
-    </PreferenceScreen>
+    <ListPreference android:key="android.not_a_preference.restoreSession3"
+                    android:title="@string/pref_restore"
+                    android:defaultValue="quit"
+                    android:entries="@array/pref_restore_entries"
+                    android:entryValues="@array/pref_restore_values"
+                    android:persistent="true" />
 
     <org.mozilla.gecko.preferences.AndroidImportPreference
                   android:key="android.not_a_preference.import_android"
                   gecko:entries="@array/pref_import_android_entries"
                   gecko:entryKeys="@array/pref_import_android_keys"
                   gecko:initialValues="@array/pref_import_android_values"
                   android:title="@string/pref_import_android"
                   android:positiveButtonText="@string/bookmarkhistory_button_import"
                   android:negativeButtonText="@string/button_cancel"
                   android:persistent="false" />
 
-    <ListPreference android:key="android.not_a_preference.restoreSession3"
-                    android:title="@string/pref_restore"
-                    android:defaultValue="quit"
-                    android:entries="@array/pref_restore_entries"
-                    android:entryValues="@array/pref_restore_values"
-                    android:persistent="true" />
-
    <ListPreference android:key="app.update.autodownload"
                    android:title="@string/pref_update_autodownload"
                    android:entries="@array/pref_update_autodownload_entries"
                    android:entryValues="@array/pref_update_autodownload_values"
                    android:persistent="false" />
 
 </PreferenceScreen>
 
--- a/mobile/android/base/resources/xml-v11/preferences_customize_tablet.xml
+++ b/mobile/android/base/resources/xml-v11/preferences_customize_tablet.xml
@@ -11,45 +11,45 @@
                   xmlns:gecko="http://schemas.android.com/apk/res-auto"
                   android:title="@string/pref_category_customize"
                   android:enabled="false">
 
     <org.mozilla.gecko.preferences.SyncPreference android:key="android.not_a_preference.sync"
                                                   android:title="@string/pref_sync"
                                                   android:persistent="false" />
 
+    <PreferenceScreen android:title="@string/pref_category_home"
+                      android:fragment="org.mozilla.gecko.preferences.GeckoPreferenceFragment" >
+            <extra android:name="resource"
+                   android:value="preferences_home" />
+    </PreferenceScreen>
+
     <PreferenceScreen android:title="@string/pref_category_search"
                       android:fragment="org.mozilla.gecko.preferences.GeckoPreferenceFragment" >
         <extra android:name="resource"
                android:value="preferences_search"/>
     </PreferenceScreen>
 
-    <PreferenceScreen android:title="@string/pref_category_home"
-                      android:fragment="org.mozilla.gecko.preferences.GeckoPreferenceFragment" >
-            <extra android:name="resource"
-                   android:value="preferences_home" />
-    </PreferenceScreen>
+    <ListPreference android:key="android.not_a_preference.restoreSession3"
+                    android:title="@string/pref_restore"
+                    android:defaultValue="quit"
+                    android:entries="@array/pref_restore_entries"
+                    android:entryValues="@array/pref_restore_values"
+                    android:persistent="true" />
 
     <org.mozilla.gecko.preferences.AndroidImportPreference
             android:key="android.not_a_preference.import_android"
             gecko:entries="@array/pref_import_android_entries"
             gecko:entryKeys="@array/pref_import_android_keys"
             gecko:initialValues="@array/pref_import_android_values"
             android:title="@string/pref_import_android"
             android:positiveButtonText="@string/bookmarkhistory_button_import"
             android:negativeButtonText="@string/button_cancel"
             android:persistent="false" />
 
-    <ListPreference android:key="android.not_a_preference.restoreSession3"
-                    android:title="@string/pref_restore"
-                    android:defaultValue="quit"
-                    android:entries="@array/pref_restore_entries"
-                    android:entryValues="@array/pref_restore_values"
-                    android:persistent="true" />
-
     <ListPreference android:key="app.update.autodownload"
                     android:title="@string/pref_update_autodownload"
                     android:entries="@array/pref_update_autodownload_entries"
                     android:entryValues="@array/pref_update_autodownload_values"
                     android:persistent="false" />
 
 </PreferenceScreen>
 
--- a/mobile/android/base/resources/xml/preferences_customize.xml
+++ b/mobile/android/base/resources/xml/preferences_customize.xml
@@ -2,52 +2,54 @@
 <!-- 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/. -->
 
 <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
                   xmlns:gecko="http://schemas.android.com/apk/res-auto"
                   android:enabled="false">
 
+    <PreferenceScreen android:title="@string/pref_category_home" >
+        <intent android:action="android.intent.action.VIEW"
+                android:targetPackage="@string/android_package_name"
+                android:targetClass="org.mozilla.gecko.preferences.GeckoPreferences" >
+            <extra
+                android:name="resource"
+                android:value="preferences_home" />
+        </intent>
+    </PreferenceScreen>
+
     <PreferenceScreen android:title="@string/pref_category_search" >
         <intent android:action="android.intent.action.VIEW"
                 android:targetPackage="@string/android_package_name"
                 android:targetClass="org.mozilla.gecko.preferences.GeckoPreferences" >
             <extra
                 android:name="resource"
                 android:value="preferences_search" />
         </intent>
     </PreferenceScreen>
 
-    <PreferenceScreen android:title="@string/pref_category_home" >
-        <intent android:action="android.intent.action.VIEW"
-                android:targetPackage="@string/android_package_name"
-                android:targetClass="org.mozilla.gecko.preferences.GeckoPreferences" >
-            <extra
-                android:name="resource"
-                android:value="preferences_home" />
-        </intent>
-    </PreferenceScreen>
+    <ListPreference android:key="android.not_a_preference.restoreSession3"
+                    android:title="@string/pref_restore"
+                    android:defaultValue="quit"
+                    android:entries="@array/pref_restore_entries"
+                    android:entryValues="@array/pref_restore_values"
+                    android:persistent="true" />
+
 
     <org.mozilla.gecko.preferences.AndroidImportPreference
                   android:key="android.not_a_preference.import_android"
                   gecko:entries="@array/pref_import_android_entries"
                   gecko:entryKeys="@array/pref_import_android_keys"
                   gecko:initialValues="@array/pref_import_android_values"
                   android:title="@string/pref_import_android"
                   android:positiveButtonText="@string/bookmarkhistory_button_import"
                   android:negativeButtonText="@string/button_cancel"
                   android:persistent="false" />
 
-    <ListPreference android:key="android.not_a_preference.restoreSession3"
-                    android:title="@string/pref_restore"
-                    android:defaultValue="quit"
-                    android:entries="@array/pref_restore_entries"
-                    android:entryValues="@array/pref_restore_values"
-                    android:persistent="true" />
 
    <ListPreference android:key="app.update.autodownload"
                    android:title="@string/pref_update_autodownload"
                    android:entries="@array/pref_update_autodownload_entries"
                    android:entryValues="@array/pref_update_autodownload_values"
                    android:persistent="false" />
 
 </PreferenceScreen>
--- a/mobile/android/base/strings.xml.in
+++ b/mobile/android/base/strings.xml.in
@@ -88,17 +88,17 @@
   <string name="media_play">&media_play;</string>
   <string name="media_pause">&media_pause;</string>
   <string name="media_stop">&media_stop;</string>
 
   <string name="settings">&settings;</string>
   <string name="settings_title">&settings_title;</string>
   <string name="pref_category_advanced">&pref_category_advanced;</string>
   <string name="pref_category_customize">&pref_category_customize;</string>
-  <string name="pref_category_search">&pref_category_search2;</string>
+  <string name="pref_category_search">&pref_category_search3;</string>
   <string name="pref_category_display">&pref_category_display;</string>
   <string name="pref_category_privacy_short">&pref_category_privacy_short;</string>
   <string name="pref_category_vendor">&pref_category_vendor;</string>
   <string name="pref_category_datareporting">&pref_category_datareporting;</string>
   <string name="pref_category_installed_search_engines">&pref_category_installed_search_engines;</string>
   <string name="pref_category_add_search_providers">&pref_category_add_search_providers;</string>
   <string name="pref_category_search_restore_defaults">&pref_category_search_restore_defaults;</string>
   <string name="pref_search_restore_defaults">&pref_search_restore_defaults;</string>
--- a/mobile/android/base/sync/setup/activities/ActivityUtils.java
+++ b/mobile/android/base/sync/setup/activities/ActivityUtils.java
@@ -43,21 +43,32 @@ public class ActivityUtils {
   public static String validateSyncKey(String key) throws InvalidSyncKeyException {
     String charKey = key.trim().replace("-", "").toLowerCase(Locale.US);
     if (!charKey.matches("^[abcdefghijkmnpqrstuvwxyz23456789]{26}$")) {
       throw new InvalidSyncKeyException();
     }
     return charKey;
   }
 
+  /**
+   * Open a URL in Fennec, if one is provided; or just open Fennec.
+   *
+   * @param context Android context.
+   * @param url to visit, or null to just open Fennec.
+   */
   public static void openURLInFennec(final Context context, final String url) {
-    final Intent intent = new Intent(Intent.ACTION_VIEW);
+    Intent intent;
+    if (url != null) {
+      intent = new Intent(Intent.ACTION_VIEW);
+      intent.setData(Uri.parse(url));
+    } else {
+      intent = new Intent(Intent.ACTION_MAIN);
+    }
     intent.setClassName(GlobalConstants.BROWSER_INTENT_PACKAGE, GlobalConstants.BROWSER_INTENT_CLASS);
     intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-    intent.setData(Uri.parse(url));
     context.startActivity(intent);
   }
 
   /**
    * Open a clicked span in Fennec with the provided URL.
    */
   public static class FennecClickableSpan extends ClickableSpan {
     private final String url;
@@ -110,19 +121,19 @@ public class ActivityUtils {
 
     // Create spans.
     final Spanned spanned = Html.fromHtml(textView.getText().toString());
 
     // Replace the spans with Fennec-launching links.
     SpannableString replaced = new SpannableString(spanned);
     URLSpan[] spans = replaced.getSpans(0, replaced.length(), URLSpan.class);
     for (URLSpan span : spans) {
-        final int start = replaced.getSpanStart(span);
-        final int end = replaced.getSpanEnd(span);
-        final int flags = replaced.getSpanFlags(span);
+      final int start = replaced.getSpanStart(span);
+      final int end = replaced.getSpanEnd(span);
+      final int flags = replaced.getSpanFlags(span);
 
-        replaced.removeSpan(span);
-        replaced.setSpan(new FennecClickableSpan(span.getURL(), underlining), start, end, flags);
+      replaced.removeSpan(span);
+      replaced.setSpan(new FennecClickableSpan(span.getURL(), underlining), start, end, flags);
     }
 
     textView.setText(replaced);
   }
 }
--- a/mobile/android/base/sync/setup/activities/SetupSuccessActivity.java
+++ b/mobile/android/base/sync/setup/activities/SetupSuccessActivity.java
@@ -1,20 +1,18 @@
 /* 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/. */
 
 package org.mozilla.gecko.sync.setup.activities;
 
 import org.mozilla.gecko.R;
-import org.mozilla.gecko.background.common.GlobalConstants;
 import org.mozilla.gecko.sync.setup.Constants;
 import org.mozilla.gecko.sync.setup.SyncAccounts;
 
-import android.content.Intent;
 import android.os.Bundle;
 import android.view.View;
 import android.widget.TextView;
 
 public class SetupSuccessActivity extends SyncActivity {
   private TextView setupSubtitle;
 
   @Override
@@ -37,13 +35,11 @@ public class SetupSuccessActivity extend
   }
 
   /* Click Handlers */
   public void settingsClickHandler(View target) {
     SyncAccounts.openSyncSettings(this);
   }
 
   public void launchBrowser(View target) {
-    Intent intent = new Intent(Intent.ACTION_MAIN);
-    intent.setClassName(GlobalConstants.BROWSER_INTENT_PACKAGE, GlobalConstants.BROWSER_INTENT_CLASS);
-    startActivity(intent);
+    ActivityUtils.openURLInFennec(this, null);
   }
 }
--- a/mobile/android/base/tests/testSettingsMenuItems.java
+++ b/mobile/android/base/tests/testSettingsMenuItems.java
@@ -26,20 +26,20 @@ public class testSettingsMenuItems exten
      * where defaultValue is optional, and there can be multiple options.
      *
      * These menu items are the ones that are always present - to test menu items that differ
      * based on build (e.g., release vs. nightly), add the items in <code>addConditionalSettings</code>. 
      */
 
     // Customize menu items.
     String[][] OPTIONS_CUSTOMIZE = {
-        { "Search settings", "", "Show search suggestions", "Installed search engines"},
         { "Home", "", "Panels" },
+        { "Search", "", "Show search suggestions", "Installed search engines"},
+        { "Tabs", "Don't restore after quitting " + BRAND_NAME, "Always restore", "Don't restore after quitting " + BRAND_NAME },
         { "Import from Android", "", "Bookmarks", "History", "Import" },
-        { "Tabs", "Don't restore after quitting " + BRAND_NAME, "Always restore", "Don't restore after quitting " + BRAND_NAME },
     };
 
     // Display menu items.
     String[][] OPTIONS_DISPLAY = {
         { "Text size" },
         { "Title bar", "Show page title", "Show page title", "Show page address" },
         { "Advanced" },
         { "Character encoding", "Don't show menu", "Show menu", "Don't show menu" },
--- a/mobile/android/services/strings.xml.in
+++ b/mobile/android/services/strings.xml.in
@@ -60,17 +60,17 @@
   <string name="sync_configure_engines_title_tabs">&sync.configure.engines.title.tabs;</string>
 
   <!-- Common text -->
   <string name="sync_button_cancel">&sync.button.cancel.label;</string>
   <string name="sync_button_connect">&sync.button.connect.label;</string>
   <string name="sync_button_ok">&sync.button.ok.label;</string>
 
   <!-- Account strings -->
-  <string name="sync_account_label">&sync.account.label.label;</string>
+  <string name="sync_account_label">&sync.account.label;</string>
 
   <!-- Bookmark folder strings -->
   <string name="bookmarks_folder_menu">&bookmarks.folder.menu.label;</string>
   <string name="bookmarks_folder_places">&bookmarks.folder.places.label;</string>
   <string name="bookmarks_folder_tags">&bookmarks.folder.tags.label;</string>
   <string name="bookmarks_folder_toolbar">&bookmarks.folder.toolbar.label;</string>
   <string name="bookmarks_folder_unfiled">&bookmarks.folder.unfiled.label;</string>
   <string name="bookmarks_folder_desktop">&bookmarks.folder.desktop.label;</string>
@@ -93,100 +93,101 @@
   <string name="sync_title_send_tab">&sync.title.send.tab.label;</string>
   <string name="sync_button_send">&sync.button.send.label;</string>
   <string name="sync_button_set_up_sync">&sync.button.set.up.sync.label;</string>
   <string name="sync_title_redirect_to_set_up_sync">&sync.title.redirect.to.set.up.sync.label;</string>
   <string name="sync_text_redirect_to_set_up_sync">&sync.text.redirect.to.set.up.sync.label;</string>
   <string name="sync_text_tab_sent">&sync.text.tab.sent.label;</string>
   <string name="sync_text_tab_not_sent">&sync.text.tab.not.sent.label;</string>
 
-<!-- Firefox Account strings. -->
-<string name="firefox_accounts">&firefox_accounts;</string>
-<string name="firefox_account">&firefox_account;</string>
+<!-- Firefox account strings. -->
 
-<!-- Firefox Account links. -->
+<!-- Firefox account links. -->
 <!-- https://support.mozilla.org/1/mobile/%VERSION%/%OS%/%LOCALE%/old-sync -->
 <string name="fxaccount_link_old_firefox">https://support.mozilla.org/1/mobile/&formatS1;/&formatS2;/&formatS3;/old-sync</string>
 <string name="fxaccount_link_create_not_allowed">http://www.consumer.ftc.gov/articles/0031-protecting-your-childs-privacy-online</string>
 <string name="fxaccount_link_tos">https://accounts.firefox.com/legal/terms</string>
 <string name="fxaccount_link_pn">https://accounts.firefox.com/legal/privacy</string>
 <string name="fxaccount_link_forgot_password">https://accounts.firefox.com/reset_password</string>
 
-<string name="fxaccount_checkbox_contentDescription">&fxaccount_checkbox_contentDescription;</string>
-<string name="fxaccount_icon_contentDescription">&fxaccount_icon_contentDescription;</string>
-<string name="fxaccount_intro_contentDescription">&fxaccount_intro_contentDescription;</string>
-<string name="fxaccount_mail_contentDescription">&fxaccount_mail_contentDescription;</string>
+<string name="fxaccount_checkbox_contentDescription">&fxaccount_checkbox_contentDescription2;</string>
+<string name="fxaccount_icon_contentDescription">&fxaccount_icon_contentDescription2;</string>
+<string name="fxaccount_intro_contentDescription">&fxaccount_intro_contentDescription2;</string>
+<string name="fxaccount_mail_contentDescription">&fxaccount_mail_contentDescription2;</string>
 
 <string name="fxaccount_email_hint">&fxaccount_email_hint;</string>
 <string name="fxaccount_password_hint">&fxaccount_password_hint;</string>
 <string name="fxaccount_password_hide">&fxaccount_password_hide;</string>
 <string name="fxaccount_password_show">&fxaccount_password_show;</string>
 
+<string name="fxaccount_back_to_browsing">&fxaccount_back_to_browsing;</string>
+
 <string name="fxaccount_policy_linktos">&fxaccount_policy_linktos;</string>
 <string name="fxaccount_policy_linkprivacy">&fxaccount_policy_linkprivacy;</string>
 
 <string name="fxaccount_getting_started_welcome_to_sync">&fxaccount_getting_started_welcome_to_sync;</string>
 <string name="fxaccount_getting_started_description">&fxaccount_getting_started_description;</string>
 <string name="fxaccount_getting_started_get_started">&fxaccount_getting_started_get_started;</string>
 <string name="fxaccount_getting_started_old_firefox">&fxaccount_getting_started_old_firefox;</string>
 
-<string name="fxaccount_create_account_sub_header">&fxaccount_create_account_sub_header;</string>
+<string name="fxaccount_create_account_header">&fxaccount_create_account_header;</string>
 <string name="fxaccount_create_account_password_length_restriction">&fxaccount_create_account_password_length_restriction;</string>
 <string name="fxaccount_create_account_year_of_birth">&fxaccount_create_account_year_of_birth;</string>
 
 <string name="fxaccount_create_account_policy_text">&fxaccount_create_account_policy_text;</string>
 <string name="fxaccount_create_account_button">&fxaccount_create_account_button;</string>
 <string name="fxaccount_create_account_choose_what_to_sync">&fxaccount_create_account_choose_what_to_sync;</string>
 <string name="fxaccount_create_account_sign_in_instead">&fxaccount_create_account_sign_in_instead;</string>
-<string name="fxaccount_create_account_1950_or_earlier">&fxaccount_create_account_1950_or_earlier;</string>
+<string name="fxaccount_create_account_1990_or_earlier">&fxaccount_create_account_1990_or_earlier;</string>
 <string name="fxaccount_create_account_unknown_error">&fxaccount_create_account_unknown_error;</string>
 
 <string name="fxaccount_account_create_not_allowed">&fxaccount_account_create_not_allowed;</string>
 <string name="fxaccount_account_create_not_allowed_you_must_meet_certain_age_requirements">&fxaccount_account_create_not_allowed_you_must_meet_certain_age_requirements;</string>
 <string name="fxaccount_account_create_not_allowed_learn_more">&fxaccount_account_create_not_allowed_learn_more;</string>
 
 <string name="fxaccount_confirm_account_header">&fxaccount_confirm_account_header;</string>
 <string name="fxaccount_confirm_account_verification_link">&fxaccount_confirm_account_verification_link;</string>
 <string name="fxaccount_confirm_account_resend_email">&fxaccount_confirm_account_resend_email;</string>
-<string name="fxaccount_confirm_account_verification_link_sent">&fxaccount_confirm_account_verification_link_sent;</string>
-<string name="fxaccount_confirm_account_verification_link_not_sent">&fxaccount_confirm_account_verification_link_not_sent;</string>
+<string name="fxaccount_confirm_account_verification_link_sent">&fxaccount_confirm_account_verification_link_sent2;</string>
+<string name="fxaccount_confirm_account_verification_link_not_sent">&fxaccount_confirm_account_verification_link_not_sent2;</string>
 
 <string name="fxaccount_sign_in_sub_header">&fxaccount_sign_in_sub_header;</string>
 <string name="fxaccount_sign_in_button_label">&fxaccount_sign_in_button_label;</string>
 <string name="fxaccount_sign_in_forgot_password">&fxaccount_sign_in_forgot_password;</string>
 <string name="fxaccount_sign_in_create_account_instead">&fxaccount_sign_in_create_account_instead;</string>
 <string name="fxaccount_sign_in_unknown_error">&fxaccount_sign_in_unknown_error;</string>
 
 <string name="fxaccount_account_verified_sub_header">&fxaccount_account_verified_sub_header;</string>
-<string name="fxaccount_account_verified_description">&fxaccount_account_verified_description;</string>
+<string name="fxaccount_account_verified_description">&fxaccount_account_verified_description2;</string>
 
-<string name="fxaccount_update_credentials_sub_header">&fxaccount_update_credentials_sub_header;</string>
+<string name="fxaccount_update_credentials_header">&fxaccount_update_credentials_header;</string>
 <string name="fxaccount_update_credentials_button_label">&fxaccount_update_credentials_button_label;</string>
 <string name="fxaccount_update_credentials_unknown_error">&fxaccount_update_credentials_unknown_error;</string>
 
+<string name="fxaccount_status_header">&fxaccount_status_header;</string>
 <string name="fxaccount_status_sync">&fxaccount_status_sync;</string>
 <string name="fxaccount_status_sync_enabled">&fxaccount_status_sync_enabled;</string>
-<string name="fxaccount_status_needs_verification">&fxaccount_status_needs_verification;</string>
+<string name="fxaccount_status_needs_verification">&fxaccount_status_needs_verification2;</string>
 <string name="fxaccount_status_needs_credentials">&fxaccount_status_needs_credentials;</string>
 <string name="fxaccount_status_needs_upgrade">&fxaccount_status_needs_upgrade;</string>
 <string name="fxaccount_status_bookmarks">&fxaccount_status_bookmarks;</string>
 <string name="fxaccount_status_history">&fxaccount_status_history;</string>
 <string name="fxaccount_status_passwords">&fxaccount_status_passwords;</string>
 <string name="fxaccount_status_tabs">&fxaccount_status_tabs;</string>
 <string name="fxaccount_status_legal">&fxaccount_status_legal;</string>
 
-<string name="fxaccount_label">&fxaccount_label;</string>
+<string name="fxaccount_label">&fxaccount_account_type_label;</string>
 
 <string name="fxaccount_options_title">&fxaccount_options_title;</string>
 <string name="fxaccount_options_configure_title">&fxaccount_options_configure_title;</string>
 
 <string name="fxaccount_remote_error_UPGRADE_REQUIRED">&fxaccount_remote_error_UPGRADE_REQUIRED;</string>
-<string name="fxaccount_remote_error_ATTEMPT_TO_CREATE_AN_ACCOUNT_THAT_ALREADY_EXISTS">&fxaccount_remote_error_ATTEMPT_TO_CREATE_AN_ACCOUNT_THAT_ALREADY_EXISTS;</string>
+<string name="fxaccount_remote_error_ATTEMPT_TO_CREATE_AN_ACCOUNT_THAT_ALREADY_EXISTS">&fxaccount_remote_error_ATTEMPT_TO_CREATE_AN_ACCOUNT_THAT_ALREADY_EXISTS_2;</string>
 <string name="fxaccount_remote_error_ATTEMPT_TO_ACCESS_AN_ACCOUNT_THAT_DOES_NOT_EXIST">&fxaccount_remote_error_ATTEMPT_TO_ACCESS_AN_ACCOUNT_THAT_DOES_NOT_EXIST;</string>
 <string name="fxaccount_remote_error_INCORRECT_PASSWORD">&fxaccount_remote_error_INCORRECT_PASSWORD;</string>
 <string name="fxaccount_remote_error_ATTEMPT_TO_OPERATE_ON_AN_UNVERIFIED_ACCOUNT">&fxaccount_remote_error_ATTEMPT_TO_OPERATE_ON_AN_UNVERIFIED_ACCOUNT;</string>
 <string name="fxaccount_remote_error_CLIENT_HAS_SENT_TOO_MANY_REQUESTS">&fxaccount_remote_error_CLIENT_HAS_SENT_TOO_MANY_REQUESTS;</string>
 <string name="fxaccount_remote_error_SERVICE_TEMPORARILY_UNAVAILABLE_TO_DUE_HIGH_LOAD">&fxaccount_remote_error_SERVICE_TEMPORARILY_UNAVAILABLE_TO_DUE_HIGH_LOAD;</string>
 <string name="fxaccount_remote_error_UNKNOWN_ERROR">&fxaccount_remote_error_UNKNOWN_ERROR;</string>
 <string name="fxaccount_remote_error_COULD_NOT_CONNECT">&fxaccount_remote_error_COULD_NOT_CONNECT;</string>
 
-<string name="fxaccount_sync_sign_in_error_notification_title">&fxaccount_sync_sign_in_error_notification_title;</string>
-<string name="fxaccount_sync_sign_in_error_notification_text">&fxaccount_sync_sign_in_error_notification_text;</string>
+<string name="fxaccount_sync_sign_in_error_notification_title">&fxaccount_sync_sign_in_error_notification_title2;</string>
+<string name="fxaccount_sync_sign_in_error_notification_text">&fxaccount_sync_sign_in_error_notification_text2;</string>
--- a/security/manager/boot/src/nsSTSPreloadList.errors
+++ b/security/manager/boot/src/nsSTSPreloadList.errors
@@ -1,14 +1,15 @@
 alpha.irccloud.com: could not connect to host
 api.mega.co.nz: could not connect to host
 api.recurly.com: did not receive HSTS header
 api.simple.com: did not receive HSTS header
 apis.google.com: did not receive HSTS header (error ignored - included regardless)
 appengine.google.com: did not receive HSTS header (error ignored - included regardless)
+bassh.net: did not receive HSTS header
 bcrook.com: max-age too low: 86400
 betnet.fr: could not connect to host
 bigshinylock.minazo.net: could not connect to host
 braintreegateway.com: did not receive HSTS header
 braintreepayments.com: did not receive HSTS header
 browserid.org: did not receive HSTS header
 business.medbank.com.mt: did not receive HSTS header
 carlolly.co.uk: did not receive HSTS header
@@ -50,17 +51,16 @@ id.atlassian.com: did not receive HSTS h
 in.xero.com: max-age too low: 3600
 iop.intuit.com: max-age too low: 86400
 irccloud.com: did not receive HSTS header
 jitsi.org: did not receive HSTS header
 jottit.com: did not receive HSTS header
 kiwiirc.com: max-age too low: 5256000
 ledgerscope.net: did not receive HSTS header
 liberty.lavabit.com: could not connect to host
-lifeguard.aecom.com: max-age too low: 3600
 lists.mayfirst.org: did not receive HSTS header
 lumi.do: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]"  nsresult: "0x80004005 (NS_ERROR_FAILURE)"  location: "JS frame :: /builds/slave/m-cen-l64-hsts-000000000000000/getHSTSPreloadList.js :: processStsHeader :: line 125"  data: no]
 mail.google.com: did not receive HSTS header (error ignored - included regardless)
 market.android.com: did not receive HSTS header (error ignored - included regardless)
 medium.com: max-age too low: 2592000
 my.alfresco.com: did not receive HSTS header
 mydigipass.com: did not receive HSTS header
 neonisi.com: could not connect to host
@@ -97,16 +97,17 @@ ssl.google-analytics.com: did not receiv
 ssl.panoramio.com: did not receive HSTS header
 sunshinepress.org: could not connect to host
 surfeasy.com: did not receive HSTS header
 talk.google.com: did not receive HSTS header (error ignored - included regardless)
 talkgadget.google.com: did not receive HSTS header (error ignored - included regardless)
 translate.googleapis.com: did not receive HSTS header (error ignored - included regardless)
 uprotect.it: could not connect to host
 wallet.google.com: did not receive HSTS header (error ignored - included regardless)
+webmail.mayfirst.org: did not receive HSTS header
 whonix.org: did not receive HSTS header
 www.cueup.com: did not receive HSTS header
 www.developer.mydigipass.com: could not connect to host
 www.dropcam.com: max-age too low: 2592000
 www.elanex.biz: did not receive HSTS header
 www.getcloak.com: max-age too low: 2678400
 www.gmail.com: did not receive HSTS header
 www.googlemail.com: did not receive HSTS header
--- a/security/manager/boot/src/nsSTSPreloadList.inc
+++ b/security/manager/boot/src/nsSTSPreloadList.inc
@@ -3,17 +3,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /*****************************************************************************/
 /* This is an automatically generated file. If you're not                    */
 /* nsSiteSecurityService.cpp, you shouldn't be #including it.     */
 /*****************************************************************************/
 
 #include <stdint.h>
-const PRTime gPreloadListExpirationTime = INT64_C(1401534344234000);
+const PRTime gPreloadListExpirationTime = INT64_C(1402139146259000);
 
 class nsSTSPreload
 {
   public:
     const char *mHost;
     const bool mIncludeSubdomains;
 };
 
@@ -25,17 +25,16 @@ static const nsSTSPreload kSTSPreloadLis
   { "api.xero.com", false },
   { "apis.google.com", true },
   { "app.recurly.com", false },
   { "app.yinxiang.com", false },
   { "appengine.google.com", false },
   { "appseccalifornia.org", true },
   { "arivo.com.br", true },
   { "bank.simple.com", false },
-  { "bassh.net", true },
   { "bccx.com", true },
   { "bitbucket.org", false },
   { "blog.cyveillance.com", true },
   { "blog.linode.com", false },
   { "blog.lookout.com", false },
   { "blog.torproject.org", false },
   { "blueseed.co", false },
   { "bugzilla.mozilla.org", true },
@@ -100,16 +99,17 @@ static const nsSTSPreload kSTSPreloadLis
   { "inertianetworks.com", true },
   { "intercom.io", false },
   { "itriskltd.com", true },
   { "keyerror.com", true },
   { "kinsights.com", false },
   { "lastpass.com", false },
   { "launchkey.com", true },
   { "library.linode.com", false },
+  { "lifeguard.aecom.com", false },
   { "linode.com", false },
   { "linx.net", false },
   { "lockify.com", true },
   { "logentries.com", false },
   { "login.persona.org", true },
   { "login.sapo.pt", true },
   { "login.xero.com", false },
   { "logotype.se", true },
@@ -178,17 +178,16 @@ static const nsSTSPreload kSTSPreloadLis
   { "tent.io", true },
   { "therapynotes.com", false },
   { "torproject.org", false },
   { "translate.googleapis.com", true },
   { "twitter.com", false },
   { "ubertt.org", true },
   { "wallet.google.com", true },
   { "webmail.gigahost.dk", false },
-  { "webmail.mayfirst.org", false },
   { "webmail.onlime.ch", false },
   { "wiki.python.org", true },
   { "wiz.biz", true },
   { "writeapp.me", false },
   { "www.apollo-auto.com", true },
   { "www.braintreepayments.com", false },
   { "www.cyveillance.com", true },
   { "www.entropia.de", false },
--- a/services/common/hawk.js
+++ b/services/common/hawk.js
@@ -189,13 +189,17 @@ HawkClient.prototype = {
     };
 
     let extra = {
       now: this.now(),
       localtimeOffsetMsec: this.localtimeOffsetMsec,
     };
 
     let request = new HAWKAuthenticatedRESTRequest(uri, credentials, extra);
-    request[method](payloadObj, onComplete);
+    if (method == "post" || method == "put") {
+      request[method](payloadObj, onComplete);
+    } else {
+      request[method](onComplete);
+    }
 
     return deferred.promise;
   }
 }
--- a/services/common/rest.js
+++ b/services/common/rest.js
@@ -758,26 +758,32 @@ this.HAWKAuthenticatedRESTRequest =
   this.now = extra.now || Date.now();
   this.localtimeOffsetMsec = extra.localtimeOffsetMsec || 0;
   this._log.trace("local time, offset: " + this.now + ", " + (this.localtimeOffsetMsec));
 };
 HAWKAuthenticatedRESTRequest.prototype = {
   __proto__: RESTRequest.prototype,
 
   dispatch: function dispatch(method, data, onComplete, onProgress) {
+    let contentType = "text/plain";
+    if (method == "POST" || method == "PUT") {
+      contentType = "application/json";
+    }
     if (this.credentials) {
       let options = {
         now: this.now,
         localtimeOffsetMsec: this.localtimeOffsetMsec,
         credentials: this.credentials,
         payload: data && JSON.stringify(data) || "",
-        contentType: "application/json; charset=utf-8",
+        contentType: contentType,
       };
       let header = CryptoUtils.computeHAWK(this.uri, method, options);
       this.setHeader("Authorization", header.field);
       this._log.trace("hawk auth header: " + header.field);
     }
 
+    this.setHeader("Content-Type", contentType);
+
     return RESTRequest.prototype.dispatch.call(
       this, method, data, onComplete, onProgress
     );
   }
 };
--- a/services/common/tests/unit/head_helpers.js
+++ b/services/common/tests/unit/head_helpers.js
@@ -173,12 +173,11 @@ function uninstallFakePAC() {
   Cm.nsIComponentRegistrar.unregisterFactory(CID, PACSystemSettings);
 }
 
 // We want to ensure the legacy provider is used for most of these tests; the
 // tests that know how to deal with the Firefox Accounts identity hack things
 // to ensure that still works.
 function setDefaultIdentityConfig() {
   Cu.import("resource://gre/modules/Services.jsm");
-  Services.prefs.setBoolPref("identity.fxaccounts.enabled", false);
-//  Services.prefs.setBoolPref("services.sync.fxaccounts.enabled", false);
+  Services.prefs.setBoolPref("services.sync.fxaccounts.enabled", false);
 }
 setDefaultIdentityConfig();
--- a/services/fxaccounts/FxAccounts.jsm
+++ b/services/fxaccounts/FxAccounts.jsm
@@ -380,25 +380,16 @@ InternalMethods.prototype = {
     return this.fxAccountsClient.resendVerificationEmail(data.sessionToken);
   },
 
   notifyObservers: function(topic) {
     log.debug("Notifying observers of " + topic);
     Services.obs.notifyObservers(null, topic, null);
   },
 
-  /**
-   * Give xpcshell tests an override point for duration testing. This is
-   * necessary because the tests need to manipulate the date in order to
-   * simulate certificate expiration.
-   */
-  now: function() {
-    return Date.now();
-  },
-
   pollEmailStatus: function pollEmailStatus(sessionToken, why) {
     let myGenerationCount = this.generationCount;
     log.debug("entering pollEmailStatus: " + why + " " + myGenerationCount);
     if (why == "start") {
       // If we were already polling, stop and start again.  This could happen
       // if the user requested the verification email to be resent while we
       // were already polling for receipt of an earlier email.
       this.pollTimeRemaining = this.POLL_SESSION;
@@ -484,16 +475,30 @@ this.FxAccounts = function(mockInternal)
   if (mockInternal) {
     // Exposes the internal object for testing only.
     this.internal = internal;
   }
 }
 this.FxAccounts.prototype = Object.freeze({
   version: DATA_FORMAT_VERSION,
 
+  now: function() {
+    if (this.internal) {
+      return this.internal.now();
+    }
+    return internal.now();
+  },
+
+  get localtimeOffsetMsec() {
+    if (this.internal) {
+      return this.internal.localtimeOffsetMsec;
+    }
+    return internal.localtimeOffsetMsec;
+  },
+
   // set() makes sure that polling is happening, if necessary.
   // get() does not wait for verification, and returns an object even if
   // unverified. The caller of get() must check .verified .
   // The "fxaccounts:onverified" event will fire only when the verified
   // state goes from false to true, so callers must register their observer
   // and then call get(). In particular, it will not fire when the account
   // was found to be verified in a previous boot: if our stored state says
   // the account is verified, the event will never fire. So callers must do:
@@ -615,17 +620,16 @@ this.FxAccounts.prototype = Object.freez
   getKeys: function() {
     return internal.getKeys();
   },
 
   whenVerified: function(userData) {
     return internal.whenVerified(userData);
   },
 
-
   /**
    * Sign the current user out.
    *
    * @return Promise
    *         The promise is rejected if a storage error occurs.
    */
   signOut: function signOut() {
     return internal.signOut();
@@ -633,17 +637,36 @@ this.FxAccounts.prototype = Object.freez
 
   // Return the URI of the remote UI flows.
   getAccountsURI: function() {
     let url = Services.urlFormatter.formatURLPref("identity.fxaccounts.remote.uri");
     if (!/^https:/.test(url)) { // Comment to un-break emacs js-mode highlighting
       throw new Error("Firefox Accounts server must use HTTPS");
     }
     return url;
+  },
+
+  // Returns a promise that resolves with the URL to use to force a re-signin
+  // of the current account.
+  promiseAccountsForceSigninURI: function() {
+    let url = Services.urlFormatter.formatURLPref("identity.fxaccounts.remote.force_auth.uri");
+    if (!/^https:/.test(url)) { // Comment to un-break emacs js-mode highlighting
+      throw new Error("Firefox Accounts server must use HTTPS");
+    }
+    // but we need to append the email address onto a query string.
+    return this.getSignedInUser().then(accountData => {
+      if (!accountData) {
+        return null;
+      }
+      let newQueryPortion = url.indexOf("?") == -1 ? "?" : "&";
+      newQueryPortion += "email=" + encodeURIComponent(accountData.email);
+      return url + newQueryPortion;
+    });
   }
+
 });
 
 /**
  * JSONStorage constructor that creates instances that may set/get
  * to a specified file, in a directory that will be created if it
  * doesn't exist.
  *
  * @param options {
--- a/services/sync/Weave.js
+++ b/services/sync/Weave.js
@@ -61,34 +61,16 @@ WeaveService.prototype = {
   ensureLoaded: function () {
     Components.utils.import("resource://services-sync/main.js");
 
     // Side-effect of accessing the service is that it is instantiated.
     Weave.Service;
   },
 
   get fxAccountsEnabled() {
-    // first check if Firefox accounts is available at all.  This is so we can
-    // get this landed without forcing Fxa to be used (and require nightly
-    // testers to manually set this pref)
-    // Once we decide we want Fxa to be available, we just remove this block
-    // (although a fly in this ointment is tests - it might be that we must
-    // just set this as a pref with a default of true)
-    let fxAccountsAvailable;
-    try {
-      fxAccountsAvailable = Services.prefs.getBoolPref("identity.fxaccounts.enabled");
-    } catch (_) {
-    }
-    if (!fxAccountsAvailable) {
-      // Currently we don't support toggling this pref after initialization, so
-      // inject the pref value as a regular boolean.
-      delete this.fxAccountsEnabled;
-      this.fxAccountsEnabled = false;
-      return false;
-    }
     // work out what identity manager to use.  This is stored in a preference;
     // if the preference exists, we trust it.
     let fxAccountsEnabled;
     try {
       fxAccountsEnabled = Services.prefs.getBoolPref("services.sync.fxaccounts.enabled");
     } catch (_) {
       // That pref doesn't exist - so let's assume this is a first-run.
       // If sync already appears configured, we assume it's for the legacy
--- a/services/sync/modules/browserid_identity.js
+++ b/services/sync/modules/browserid_identity.js
@@ -41,16 +41,25 @@ function deriveKeyBundle(kB) {
   let out = CryptoUtils.hkdf(kB, undefined,
                              "identity.mozilla.com/picl/v1/oldsync", 2*32);
   let bundle = new BulkKeyBundle();
   // [encryptionKey, hmacKey]
   bundle.keyPair = [out.slice(0, 32), out.slice(32, 64)];
   return bundle;
 }
 
+/*
+  General authentication error for abstracting authentication
+  errors from multiple sources (e.g., from FxAccounts, TokenServer)
+    'message' is a string with a description of the error
+*/
+function AuthenticationError(message) {
+  this.message = message || "";
+}
+
 this.BrowserIDManager = function BrowserIDManager() {
   this._fxaService = fxAccounts;
   this._tokenServerClient = new TokenServerClient();
   // will be a promise that resolves when we are ready to authenticate
   this.whenReadyToAuthenticate = null;
   this._log = Log.repository.getLogger("Sync.BrowserIDManager");
   this._log.addAppender(new Log.DumpAppender());
   this._log.Level = Log.Level[Svc.Prefs.get("log.logger.identity")] || Log.Level.Error;
@@ -81,16 +90,17 @@ this.BrowserIDManager.prototype = {
     } catch (e) {
       return false;
     }
   },
 
   initialize: function() {
     Services.obs.addObserver(this, fxAccountsCommon.ONLOGIN_NOTIFICATION, false);
     Services.obs.addObserver(this, fxAccountsCommon.ONLOGOUT_NOTIFICATION, false);
+    Services.obs.addObserver(this, "weave:service:logout:finish", false);
     return this.initializeWithCurrentIdentity();
   },
 
   initializeWithCurrentIdentity: function(isInitialSync=false) {
     this._log.trace("initializeWithCurrentIdentity");
     Components.utils.import("resource://services-sync/main.js");
 
     // Reset the world before we do anything async.
@@ -140,18 +150,17 @@ this.BrowserIDManager.prototype = {
           Svc.Prefs.set("firstSync", "resetClient");
           Services.obs.notifyObservers(null, "weave:service:setup-complete", null);
           Weave.Utils.nextTick(Weave.Service.sync, Weave.Service);
         }
       }).then(null, err => {
         this._shouldHaveSyncKeyBundle = true; // but we probably don't have one...
         this.whenReadyToAuthenticate.reject(err);
         // report what failed...
-        this._log.error("Background fetch for key bundle failed: " + err);
-        throw err;
+        this._log.error("Background fetch for key bundle failed: " + err.message);
       });
       // and we are done - the fetch continues on in the background...
     }).then(null, err => {
       this._log.error("Processing logged in account: " + err.message);
     });
   },
 
   observe: function (subject, topic, data) {
@@ -163,16 +172,24 @@ this.BrowserIDManager.prototype = {
     case fxAccountsCommon.ONLOGOUT_NOTIFICATION:
       Components.utils.import("resource://services-sync/main.js");
       // Setting .username calls resetCredentials which drops the key bundle
       // and resets _shouldHaveSyncKeyBundle.
       this.username = "";
       this._account = null;
       Weave.Service.logout();
       break;
+
+    case "weave:service:logout:finish":
+      // This signals an auth error with the storage server,
+      // or that the user unlinked her account from the browser.
+      // Either way, we clear our auth token. In the case of an
+      // auth error, this will force the fetch of a new one.
+      this._token = null;
+      break;
     }
   },
 
    /**
    * Compute the sha256 of the message bytes.  Return bytes.
    */
   _sha256: function(message) {
     let hasher = Cc["@mozilla.org/security/hash;1"]
@@ -189,21 +206,21 @@ this.BrowserIDManager.prototype = {
   _computeXClientState: function(kBbytes) {
     return CommonUtils.bytesAsHex(this._sha256(kBbytes).slice(0, 16), false);
   },
 
   /**
    * Provide override point for testing token expiration.
    */
   _now: function() {
-    return this._fxaService.internal.now()
+    return this._fxaService.now()
   },
 
   get _localtimeOffsetMsec() {
-    return this._fxaService.internal.localtimeOffsetMsec;
+    return this._fxaService.localtimeOffsetMsec;
   },
 
   get account() {
     return this._account;
   },
 
   /**
    * Sets the active account name.
@@ -359,20 +376,22 @@ this.BrowserIDManager.prototype = {
       return null;
     }
     return userData;
   },
 
   _fetchSyncKeyBundle: function() {
     // Fetch a sync token for the logged in user from the token server.
     return this._fxaService.getKeys().then(userData => {
-      // unlikely, but if the logged in user somehow changed between these
-      // calls we better fail.
-      if (!userData || userData.email !== this.account) {
-        throw new Error("The currently logged-in user has changed.");
+      // Unlikely, but if the logged in user somehow changed between these
+      // calls we better fail. TODO: add tests for these
+      if (!userData) {
+        throw new AuthenticationError("No userData in _fetchSyncKeyBundle");
+      } else if (userData.email !== this.account) {
+        throw new AuthenticationError("Unexpected user change in _fetchSyncKeyBundle");
       }
       return this._fetchTokenForUser(userData).then(token => {
         this._token = token;
         // Set the username to be the uid returned by the token server.
         this.username = this._token.uid.toString();
         // both Jelly and FxAccounts give us kA/kB as hex.
         let kB = Utils.hexToBytes(userData.kB);
         this._syncKeyBundle = deriveKeyBundle(kB);
@@ -392,39 +411,64 @@ this.BrowserIDManager.prototype = {
     let headers = {"X-Client-State": this._computeXClientState(kBbytes)};
     log.info("Fetching Sync token from: " + tokenServerURI);
 
     function getToken(tokenServerURI, assertion) {
       let deferred = Promise.defer();
       let cb = function (err, token) {
         if (err) {
           log.info("TokenServerClient.getTokenFromBrowserIDAssertion() failed with: " + err.message);
-          return deferred.reject(err);
+          return deferred.reject(new AuthenticationError(err.message));
         } else {
           return deferred.resolve(token);
         }
       };
 
       client.getTokenFromBrowserIDAssertion(tokenServerURI, assertion, cb, headers);
       return deferred.promise;
     }
 
-    let audience = Services.io.newURI(tokenServerURI, null, null).prePath;
+    function getAssertion() {
+      let audience = Services.io.newURI(tokenServerURI, null, null).prePath;
+      return fxAccounts.getAssertion(audience).then(null, err => {
+        if (err.code === 401) {
+          throw new AuthenticationError("Unable to get assertion for user");
+        } else {
+          throw err;
+        }
+      });
+    };
+
     // wait until the account email is verified and we know that
     // getAssertion() will return a real assertion (not null).
     return this._fxaService.whenVerified(userData)
-      .then(() => this._fxaService.getAssertion(audience))
+      .then(() => getAssertion())
       .then(assertion => getToken(tokenServerURI, assertion))
       .then(token => {
-        token.expiration = this._now() + (token.duration * 1000);
+        // TODO: Make it be only 80% of the duration, so refresh the token
+        // before it actually expires. This is to avoid sync storage errors
+        // otherwise, we get a nasty notification bar briefly. Bug 966568.
+        token.expiration = this._now() + (token.duration * 1000) * 0.80;
         return token;
       })
       .then(null, err => {
-        Cu.reportError("Failed to fetch token: " + err);
-        // XXX - TODO - work out how to set sync to an error state.
+        // TODO: write tests to make sure that different auth error cases are handled here
+        // properly: auth error getting assertion, auth error getting token (invalid generation
+        // and client-state error)
+        if (err instanceof AuthenticationError) {
+          this._log.error("Authentication error in _fetchTokenForUser: " + err.message);
+          // Drop the sync key bundle, but still expect to have one.
+          // This will arrange for us to be in the right 'currentAuthState'
+          // such that UI will show the right error.
+          this._shouldHaveSyncKeyBundle = true;
+          this._syncKeyBundle = null;
+          Weave.Status.login = this.currentAuthState;
+          Services.obs.notifyObservers(null, "weave:service:login:error", null);
+        }
+        throw err;
       });
   },
 
   _fetchTokenForLoggedInUserSync: function() {
     let cb = Async.makeSpinningCallback();
 
     this._fxaService.getSignedInUser().then(userData => {
       this._fetchTokenForUser(userData).then(token => {
--- a/services/sync/tests/unit/test_browserid_identity.js
+++ b/services/sync/tests/unit/test_browserid_identity.js
@@ -131,23 +131,31 @@ add_test(function test_resourceAuthentic
   let fxa = new MockFxAccounts();
   fxa._now_is = now;
   fxa.internal.fxAccountsClient = fxaClient;
 
   // Picked up by the signed-in user module
   do_check_eq(fxa.internal.now(), now);
   do_check_eq(fxa.internal.localtimeOffsetMsec, localtimeOffsetMsec);
 
+  do_check_eq(fxa.now(), now);
+  do_check_eq(fxa.localtimeOffsetMsec, localtimeOffsetMsec);
+
   // Mocks within mocks...
   configureFxAccountIdentity(browseridManager, identityConfig);
   browseridManager._fxaService = fxa;
+
   do_check_eq(browseridManager._fxaService.internal.now(), now);
   do_check_eq(browseridManager._fxaService.internal.localtimeOffsetMsec,
       localtimeOffsetMsec);
 
+  do_check_eq(browseridManager._fxaService.now(), now);
+  do_check_eq(browseridManager._fxaService.localtimeOffsetMsec,
+      localtimeOffsetMsec);
+
   let request = new SyncStorageRequest("https://example.net/i/like/pie/");
   let authenticator = browseridManager.getResourceAuthenticator();
   let output = authenticator(request, 'GET');
   dump("output" + JSON.stringify(output));
   let authHeader = output.headers.authorization;
   do_check_true(authHeader.startsWith('Hawk'));
 
   // Skew correction is applied in the header and we're within the two-minute
--- a/testing/marionette/client/marionette/atoms/b2g_update_test.js
+++ b/testing/marionette/client/marionette/atoms/b2g_update_test.js
@@ -48,17 +48,17 @@ function getContentWindow() {
 }
 
 function sendContentEvent(type, detail) {
   detail = detail || {};
   detail.type = type;
 
   let content = getContentWindow();
   shell.sendEvent(content, "mozContentEvent",
-                   ObjectWrapper.wrap(detail, content));
+                   Cu.cloneInto(detail, content));
   return true;
 }
 
 function addChromeEventListener(type, listener) {
   let content = getContentWindow();
   content.addEventListener("mozChromeEvent", function chromeListener(evt) {
     if (!evt.detail || evt.detail.type !== type) {
       return;
--- a/testing/mochitest/b2g.json
+++ b/testing/mochitest/b2g.json
@@ -170,17 +170,16 @@
     "content/html/content/test/test_iframe_sandbox_popups_inheritance.html":"multiple concurrent window.open()s fail on B2G",
     "content/html/content/test/test_iframe_sandbox_modal.html":"modal tests fail on B2G",
 
     "content/html/content/test/test_iframe_sandbox_plugins.html":"plugins not supported",
     "content/html/content/test/test_object_plugin_nav.html":"plugins not supported",
     "content/html/document/test/test_bug741266.html":"needs control of popup window size",
     "docshell/test/navigation/test_popup-navigates-children.html":"Needs multiple window.open support, also uses docshelltreenode",
     "docshell/test/test_bug590573.html":"queryinterfaces into webnavigation, might suffer from something similar as bug 823022",
-    "docshell/test/navigation/test_bug430723.html":"apz race condition, see bug 965351",
     "dom/devicestorage/ipc/test_ipc.html":"nested ipc not working",
 
     "dom/indexedDB/ipc/test_ipc.html":"nested ipc not working",
     "dom/indexedDB/test/test_lowDiskSpace.html":"this needs probably modification for notifyObserversInParentProcess to be similar as pushPermissions",
 
     "content/base/test/test_object.html":"needs plugin support",
     "content/base/test/test_bug827160.html": "needs plugin support",
 
@@ -263,17 +262,16 @@
     "dom/browser-element/mochitest/test_browserElement_oop_TargetBlank.html":"",
     "dom/events/test/test_bug226361.xhtml":"",
     "dom/events/test/test_bug238987.html":"",
     "dom/events/test/test_bug409604.html":"",
     "dom/events/test/test_bug457672.html":"",
     "dom/events/test/test_bug574663.html":"",
     "dom/events/test/test_bug607464.html":"",
     "dom/events/test/test_wheel_default_action.html":"",
-    "dom/events/test/test_bug946632.html":"apz race condition, see bug 965351",
 
     "dom/file/test/test_progress_events.html":"All of these fail fairly regularly with: UnknownError: The operation failed for reasons unrelated to the database itself and not covered by any other error code. at http://mochi.test:8888/tests/dom/file/test/helpers.js:126",
     "dom/file/test/test_request_readyState.html":"",
     "dom/file/test/test_stream_tracking.html":"",
     "dom/file/test/test_append_read_data.html":"",
     "dom/file/test/test_archivereader.html":"",
     "dom/file/test/test_archivereader_nonUnicode.html":"",
     "dom/file/test/test_archivereader_zip_in_zip.html":"",
@@ -367,17 +365,16 @@
     "layout/base/tests/test_bug603550.html":"Components.classes[@mozilla.org/widget/dragservice;1] is undefined",
     "layout/base/tests/test_bug629838.html":"depends on plugins support",
     "layout/base/tests/test_mozPaintCount.html":"depends on plugins support",
     "layout/forms/test/test_bug348236.html":"select form control popup",
     "layout/forms/test/test_bug446663.html":"needs copy support",
     "layout/forms/test/test_bug571352.html":"shift-click multi-select not working?",
     "layout/forms/test/test_textarea_resize.html":"resizing textarea not available in b2g",
     "layout/forms/test/test_bug903715.html":"select elements don't use an in-page popup in B2G",
-    "layout/forms/test/test_bug564115.html":"apz race condition, see bug 965351",
     "layout/generic/test/test_bug392746.html":"ctrl mouse select not working in b2g",
     "layout/generic/test/test_bug791616.html":"Target should not have scrolled - got 114.10000610351562, expected 115.39999389648438",
     "layout/generic/test/test_invalidate_during_plugin_paint.html":"plugins not supported",
     "layout/generic/test/test_plugin_focus.html":"plugins not supported",
     "layout/generic/test/test_plugin_mouse_coords.html":"plugins not supported",
     "layout/generic/test/test_selection_expanding.html":"mouse selection not working",
 
     "layout/style/test/test_transitions_per_property.html":"times out, needs more time + various failures",
--- a/toolkit/devtools/apps/tests/test_webapps_actor.html
+++ b/toolkit/devtools/apps/tests/test_webapps_actor.html
@@ -86,16 +86,17 @@ var steps = [
     // Because of wrapping issues, we can't use SpecialPowers.Cu.import to load
     // devtools jsm into mochitest scope. We end up not receiving
     // DebuggerClient.addListener callback arguments...
     let scriptUrl = SimpleTest.getTestFileURL("debugger-protocol-helper.js");
     mm = SpecialPowers.loadChromeScript(scriptUrl);
     installTestApp = function (url, appId, callback) {
       let installResponse, appObject;
       let installedEvent = false;
+      mm.sendAsyncMessage("install", {url: url, appId: appId});
       mm.addMessageListener("installed", function onInstalled(aResponse) {
         mm.removeMessageListener("installed", onInstalled);
         ok(true, "install request replied");
         installResponse = aResponse;
         checkEnd();
       });
       mm.addMessageListener("installed-event", function onInstalledEvent(aResponse) {
         mm.removeMessageListener("installed-event", onInstalledEvent);
@@ -107,17 +108,16 @@ var steps = [
         appObject = evt.application;
         ok(true, "mozApps.mgmt install event fired");
         checkEnd();
       };
       function checkEnd() {
         if (appObject && installResponse && installedEvent)
           callback(installResponse, appObject);
       }
-      mm.sendAsyncMessage("install", {url: url, appId: appId});
     };
     SpecialPowers.autoConfirmAppInstall(next);
   },
   function() {
     ok(true, "== TEST == Install packaged app");
     let appId = "test-app-id";
     let url = SimpleTest.getTestFileURL("data/app.zip");
     installTestApp(url, appId,