Merge inbound to m-c.
authorRyan VanderMeulen <ryanvm@gmail.com>
Tue, 04 Mar 2014 17:12:58 -0500
changeset 171831 e5b09585215f0c8e066a6255bed90918a1439e70
parent 171767 46c3b9de467a52ad99e761aa09191b4515bc49c6 (current diff)
parent 171830 c0805ed62585e519412fddcf5f35d623b05702b9 (diff)
child 171844 a9780d2f2b86f8aac4dc83409ddef76d070fb73c
child 171951 1fba6d21db7176579c34ea7ad3636f8bba25dbb0
push id26340
push userryanvm@gmail.com
push dateTue, 04 Mar 2014 22:12:36 +0000
treeherdermozilla-central@e5b09585215f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone30.0a1
first release with
nightly linux32
e5b09585215f / 30.0a1 / 20140305030201 / files
nightly linux64
e5b09585215f / 30.0a1 / 20140305030201 / files
nightly mac
e5b09585215f / 30.0a1 / 20140305030201 / files
nightly win32
e5b09585215f / 30.0a1 / 20140305030201 / files
nightly win64
e5b09585215f / 30.0a1 / 20140305030201 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge inbound to m-c.
browser/base/content/test/general/blockNoPlugins.xml
browser/base/content/test/general/blockPluginHard.xml
browser/base/content/test/general/blockPluginVulnerableNoUpdate.xml
browser/base/content/test/general/blockPluginVulnerableUpdatable.xml
browser/base/content/test/general/browser_CTP_context_menu.js
browser/base/content/test/general/browser_CTP_crashreporting.js
browser/base/content/test/general/browser_CTP_data_urls.js
browser/base/content/test/general/browser_CTP_drag_drop.js
browser/base/content/test/general/browser_CTP_hide_overlay.js
browser/base/content/test/general/browser_CTP_multi_allow.js
browser/base/content/test/general/browser_CTP_nonplugins.js
browser/base/content/test/general/browser_CTP_notificationBar.js
browser/base/content/test/general/browser_CTP_outsideScrollArea.js
browser/base/content/test/general/browser_CTP_resize.js
browser/base/content/test/general/browser_bug743421.js
browser/base/content/test/general/browser_bug744745.js
browser/base/content/test/general/browser_bug752516.js
browser/base/content/test/general/browser_bug787619.js
browser/base/content/test/general/browser_bug797677.js
browser/base/content/test/general/browser_bug812562.js
browser/base/content/test/general/browser_bug818118.js
browser/base/content/test/general/browser_bug820497.js
browser/base/content/test/general/browser_clearplugindata.html
browser/base/content/test/general/browser_clearplugindata.js
browser/base/content/test/general/browser_clearplugindata_noage.html
browser/base/content/test/general/browser_pageInfo_plugins.js
browser/base/content/test/general/browser_pluginCrashCommentAndURL.js
browser/base/content/test/general/browser_pluginnotification.js
browser/base/content/test/general/browser_pluginplaypreview.js
browser/base/content/test/general/browser_pluginplaypreview2.js
browser/base/content/test/general/browser_plugins_added_dynamically.js
browser/base/content/test/general/pluginCrashCommentAndURL.html
browser/base/content/test/general/plugin_add_dynamically.html
browser/base/content/test/general/plugin_alternate_content.html
browser/base/content/test/general/plugin_big.html
browser/base/content/test/general/plugin_both.html
browser/base/content/test/general/plugin_both2.html
browser/base/content/test/general/plugin_bug744745.html
browser/base/content/test/general/plugin_bug749455.html
browser/base/content/test/general/plugin_bug752516.html
browser/base/content/test/general/plugin_bug787619.html
browser/base/content/test/general/plugin_bug797677.html
browser/base/content/test/general/plugin_bug820497.html
browser/base/content/test/general/plugin_clickToPlayAllow.html
browser/base/content/test/general/plugin_clickToPlayDeny.html
browser/base/content/test/general/plugin_data_url.html
browser/base/content/test/general/plugin_hidden_to_visible.html
browser/base/content/test/general/plugin_outsideScrollArea.html
browser/base/content/test/general/plugin_overlayed.html
browser/base/content/test/general/plugin_positioned.html
browser/base/content/test/general/plugin_small.html
browser/base/content/test/general/plugin_syncRemoved.html
browser/base/content/test/general/plugin_test.html
browser/base/content/test/general/plugin_test2.html
browser/base/content/test/general/plugin_test3.html
browser/base/content/test/general/plugin_two_types.html
browser/base/content/test/general/plugin_unknown.html
content/base/src/Makefile.in
dom/events/nsDOMTextEvent.cpp
dom/events/nsDOMTextEvent.h
dom/events/nsIPrivateTextEvent.h
dom/events/nsIPrivateTextRange.h
dom/events/nsPrivateTextRange.cpp
dom/events/nsPrivateTextRange.h
gfx/ycbcr/Makefile.in
intl/uconv/src/Makefile.in
media/libsoundtouch/src/Makefile.in
media/libspeex_resampler/src/Makefile.in
toolkit/devtools/server/actors/webapps.js
toolkit/devtools/server/actors/webbrowser.js
toolkit/devtools/server/main.js
xpcom/string/src/Makefile.in
--- a/CLOBBER
+++ b/CLOBBER
@@ -17,9 +17,9 @@
 #
 # Modifying this file will now automatically clobber the buildbot machines \o/
 #
 
 # Are you updating CLOBBER because you think it's needed for your WebIDL
 # changes to stick? As of bug 928195, this shouldn't be necessary! Please
 # don't change CLOBBER for WebIDL changes any more.
 
-Update CLOBBER for bug 939672 moves file location and requires clobber build.
+Update CLOBBER for bug 978784 because it touches the ICU build system.
--- a/accessible/src/jsat/AccessFu.css
+++ b/accessible/src/jsat/AccessFu.css
@@ -33,17 +33,16 @@
   font-weight: 700;
   color: orange;
   background-color: black;
   border-radius: 0.25em;
 }
 
 #announce-box:not(.showing) {
   opacity: 0.0;
-  margin: 0.1em;
   -moz-transition: opacity 0.4s linear;
 }
 
 #announce-box.showing {
   opacity: 1.0;
   -moz-transition: opacity 0.2s linear;
 }
 
--- a/accessible/src/jsat/AccessFu.jsm
+++ b/accessible/src/jsat/AccessFu.jsm
@@ -129,31 +129,41 @@ this.AccessFu = {
     Utils.win.addEventListener('TabOpen', this);
     Utils.win.addEventListener('TabClose', this);
     Utils.win.addEventListener('TabSelect', this);
 
     if (this.readyCallback) {
       this.readyCallback();
       delete this.readyCallback;
     }
+
+    if (Utils.MozBuildApp !== 'mobile/android') {
+      this.announce(
+        Utils.stringBundle.GetStringFromName('screenReaderStarted'));
+    }
   },
 
   /**
    * Disable AccessFu and return to default interaction mode.
    */
   _disable: function _disable() {
     if (!this._enabled)
       return;
 
     this._enabled = false;
 
     Logger.info('Disabled');
 
     Utils.win.document.removeChild(this.stylesheet.get());
 
+    if (Utils.MozBuildApp !== 'mobile/android') {
+      this.announce(
+        Utils.stringBundle.GetStringFromName('screenReaderStopped'));
+    }
+
     for each (let mm in Utils.AllMessageManagers) {
       mm.sendAsyncMessage('AccessFu:Stop');
       this._removeMessageListeners(mm);
     }
 
     this.Input.stop();
     Output.stop();
     TouchAdapter.stop();
@@ -363,18 +373,17 @@ this.AccessFu = {
   },
 
   showCurrent: function showCurrent(aMove) {
     let mm = Utils.getMessageManager(Utils.CurrentBrowser);
     mm.sendAsyncMessage('AccessFu:ShowCurrent', { move: aMove });
   },
 
   announce: function announce(aAnnouncement) {
-    this._output(Presentation.announce(aAnnouncement),
-                 Utils.CurrentBrowser);
+    this._output(Presentation.announce(aAnnouncement), Utils.CurrentBrowser);
   },
 
   // So we don't enable/disable twice
   _enabled: false,
 
   // Layerview is focused
   _focused: false,
 
@@ -510,17 +519,18 @@ var Output = {
     inited: false,
 
     webspeechEnabled: false,
 
     deferredOutputs: [],
 
     init: function init() {
       let window = Utils.win;
-      this.webspeechEnabled = !!window.speechSynthesis;
+      this.webspeechEnabled = !!window.speechSynthesis &&
+        !!window.SpeechSynthesisUtterance;
 
       let settingsToGet = 2;
       let settingsCallback = (aName, aSetting) => {
         if (--settingsToGet > 0) {
           return;
         }
 
         this.inited = true;
--- a/accessible/src/jsat/OutputGenerator.jsm
+++ b/accessible/src/jsat/OutputGenerator.jsm
@@ -28,20 +28,16 @@ XPCOMUtils.defineLazyModuleGetter(this, 
   'resource://gre/modules/accessibility/Utils.jsm');
 XPCOMUtils.defineLazyModuleGetter(this, 'PluralForm',
   'resource://gre/modules/PluralForm.jsm');
 XPCOMUtils.defineLazyModuleGetter(this, 'Roles',
   'resource://gre/modules/accessibility/Constants.jsm');
 XPCOMUtils.defineLazyModuleGetter(this, 'States',
   'resource://gre/modules/accessibility/Constants.jsm');
 
-var gStringBundle = Cc['@mozilla.org/intl/stringbundle;1'].
-  getService(Ci.nsIStringBundleService).
-  createBundle('chrome://global/locale/AccessFu.properties');
-
 this.EXPORTED_SYMBOLS = ['UtteranceGenerator', 'BrailleGenerator'];
 
 this.OutputGenerator = {
 
   defaultOutputOrder: OUTPUT_DESC_LAST,
 
   /**
    * Generates output for a PivotContext.
@@ -189,17 +185,17 @@ this.OutputGenerator = {
    * @param {nsIAccessible} aAccessible current accessible object.
    */
   _addLandmark: function _addLandmark(aOutput, aAccessible) {
     let landmarkName = Utils.getLandmarkName(aAccessible);
     if (!landmarkName) {
       return;
     }
 
-    let landmark = gStringBundle.GetStringFromName(landmarkName);
+    let landmark = Utils.stringBundle.GetStringFromName(landmarkName);
     if (!landmark) {
       return;
     }
 
     aOutput[this.outputOrder === OUTPUT_DESC_FIRST ? 'unshift' : 'push'](
       landmark);
   },
 
@@ -216,17 +212,17 @@ this.OutputGenerator = {
 
     let typeName = Utils.getAttributes(aAccessible)['text-input-type'];
     // Ignore the the input type="text" case.
     if (!typeName || typeName === 'text') {
       return;
     }
     typeName = 'textInputType_' + typeName;
     try {
-      aDesc.push(gStringBundle.GetStringFromName(typeName));
+      aDesc.push(Utils.stringBundle.GetStringFromName(typeName));
     } catch (x) {
       Logger.warning('Failed to get a string from a bundle for', typeName);
     }
   },
 
   get outputOrder() {
     if (!this._utteranceOrder) {
       this._utteranceOrder = new PrefCache('accessibility.accessfu.utterance');
@@ -239,17 +235,17 @@ this.OutputGenerator = {
     return aName.replace(' ', '');
   },
 
   _getLocalizedRole: function _getLocalizedRole(aRoleStr) {},
 
   _getLocalizedState: function _getLocalizedState(aState) {},
 
   _getPluralFormString: function _getPluralFormString(aString, aCount) {
-    let str = gStringBundle.GetStringFromName(this._getOutputName(aString));
+    let str = Utils.stringBundle.GetStringFromName(this._getOutputName(aString));
     str = PluralForm.get(aCount, str);
     return str.replace('#1', aCount);
   },
 
   roleRuleMap: {
     'menubar': INCLUDE_DESC,
     'scrollbar': INCLUDE_DESC,
     'grip': INCLUDE_DESC,
@@ -373,17 +369,17 @@ this.OutputGenerator = {
     pagetab: function pagetab(aAccessible, aRoleStr, aState, aFlags) {
       let localizedRole = this._getLocalizedRole(aRoleStr);
       let itemno = {};
       let itemof = {};
       aAccessible.groupPosition({}, itemof, itemno);
       let output = [];
       let desc = this._getLocalizedState(aState);
       desc.push(
-        gStringBundle.formatStringFromName(
+        Utils.stringBundle.formatStringFromName(
           'objItemOf', [localizedRole, itemno.value, itemof.value], 3));
       output.push(desc.join(' '));
 
       this._addName(output, aAccessible, aFlags);
       this._addLandmark(output, aAccessible);
 
       return output;
     },
@@ -401,17 +397,17 @@ this.OutputGenerator = {
         // We don't want to speak any table information for layout tables.
         if (table.isProbablyForLayout()) {
           return output;
         }
         let tableColumnInfo = this._getPluralFormString('tableColumnInfo',
           table.columnCount);
         let tableRowInfo = this._getPluralFormString('tableRowInfo',
           table.rowCount);
-        output.push(gStringBundle.formatStringFromName(
+        output.push(Utils.stringBundle.formatStringFromName(
           this._getOutputName('tableInfo'), [this._getLocalizedRole(aRoleStr),
             tableColumnInfo, tableRowInfo], 3));
         this._addName(output, aAccessible, aFlags);
         this._addLandmark(output, aAccessible);
         return output;
       }
     }
   }
@@ -450,88 +446,89 @@ this.UtteranceGenerator = {
     collapse: 'collapseAction',
     expand: 'expandAction',
     activate: 'activateAction',
     cycle: 'cycleAction'
   },
 
   //TODO: May become more verbose in the future.
   genForAction: function genForAction(aObject, aActionName) {
-    return [gStringBundle.GetStringFromName(this.gActionMap[aActionName])];
+    return [Utils.stringBundle.GetStringFromName(this.gActionMap[aActionName])];
   },
 
   genForLiveRegion: function genForLiveRegion(aContext, aIsHide, aModifiedText) {
     let utterance = [];
     if (aIsHide) {
-      utterance.push(gStringBundle.GetStringFromName('hidden'));
+      utterance.push(Utils.stringBundle.GetStringFromName('hidden'));
     }
     return utterance.concat(
       aModifiedText || this.genForContext(aContext).output);
   },
 
   genForAnnouncement: function genForAnnouncement(aAnnouncement) {
     try {
-      return [gStringBundle.GetStringFromName(aAnnouncement)];
+      return [Utils.stringBundle.GetStringFromName(aAnnouncement)];
     } catch (x) {
       return [aAnnouncement];
     }
   },
 
   genForTabStateChange: function genForTabStateChange(aObject, aTabState) {
     switch (aTabState) {
       case 'newtab':
-        return [gStringBundle.GetStringFromName('tabNew')];
+        return [Utils.stringBundle.GetStringFromName('tabNew')];
       case 'loading':
-        return [gStringBundle.GetStringFromName('tabLoading')];
+        return [Utils.stringBundle.GetStringFromName('tabLoading')];
       case 'loaded':
         return [aObject.name || '',
-                gStringBundle.GetStringFromName('tabLoaded')];
+                Utils.stringBundle.GetStringFromName('tabLoaded')];
       case 'loadstopped':
-        return [gStringBundle.GetStringFromName('tabLoadStopped')];
+        return [Utils.stringBundle.GetStringFromName('tabLoadStopped')];
       case 'reload':
-        return [gStringBundle.GetStringFromName('tabReload')];
+        return [Utils.stringBundle.GetStringFromName('tabReload')];
       default:
         return [];
     }
   },
 
   genForEditingMode: function genForEditingMode(aIsEditing) {
-    return [gStringBundle.GetStringFromName(
-              aIsEditing ? 'editingMode' : 'navigationMode')];
+    return [Utils.stringBundle.GetStringFromName(
+      aIsEditing ? 'editingMode' : 'navigationMode')];
   },
 
   objectOutputFunctions: {
 
     __proto__: OutputGenerator.objectOutputFunctions,
 
     defaultFunc: function defaultFunc(aAccessible, aRoleStr, aState, aFlags) {
       return this.objectOutputFunctions._generateBaseOutput.apply(this, arguments);
     },
 
     heading: function heading(aAccessible, aRoleStr, aState, aFlags) {
       let level = {};
       aAccessible.groupPosition(level, {}, {});
       let utterance =
-        [gStringBundle.formatStringFromName('headingLevel', [level.value], 1)];
+        [Utils.stringBundle.formatStringFromName(
+          'headingLevel', [level.value], 1)];
 
       this._addName(utterance, aAccessible, aFlags);
       this._addLandmark(utterance, aAccessible);
 
       return utterance;
     },
 
     listitem: function listitem(aAccessible, aRoleStr, aState, aFlags) {
       let itemno = {};
       let itemof = {};
       aAccessible.groupPosition({}, itemof, itemno);
       let utterance = [];
       if (itemno.value == 1) // Start of list
-        utterance.push(gStringBundle.GetStringFromName('listStart'));
+        utterance.push(Utils.stringBundle.GetStringFromName('listStart'));
       else if (itemno.value == itemof.value) // last item
-        utterance.push(gStringBundle.GetStringFromName('listEnd'));
+        utterance.push(Utils.stringBundle.GetStringFromName('listEnd'));
 
       this._addName(utterance, aAccessible, aFlags);
       this._addLandmark(utterance, aAccessible);
 
       return utterance;
     },
 
     list: function list(aAccessible, aRoleStr, aState, aFlags) {
@@ -555,23 +552,23 @@ this.UtteranceGenerator = {
 
     cell: function cell(aAccessible, aRoleStr, aState, aFlags, aContext) {
       let utterance = [];
       let cell = aContext.getCellInfo(aAccessible);
       if (cell) {
         let desc = [];
         let addCellChanged = function addCellChanged(aDesc, aChanged, aString, aIndex) {
           if (aChanged) {
-            aDesc.push(gStringBundle.formatStringFromName(aString,
+            aDesc.push(Utils.stringBundle.formatStringFromName(aString,
               [aIndex + 1], 1));
           }
         };
         let addExtent = function addExtent(aDesc, aExtent, aString) {
           if (aExtent > 1) {
-            aDesc.push(gStringBundle.formatStringFromName(aString,
+            aDesc.push(Utils.stringBundle.formatStringFromName(aString,
               [aExtent], 1));
           }
         };
         let addHeaders = function addHeaders(aDesc, aHeaders) {
           if (aHeaders.length > 0) {
             aDesc.push.apply(aDesc, aHeaders);
           }
         };
@@ -604,59 +601,65 @@ this.UtteranceGenerator = {
   },
 
   _getContextStart: function _getContextStart(aContext) {
     return aContext.newAncestry;
   },
 
   _getLocalizedRole: function _getLocalizedRole(aRoleStr) {
     try {
-      return gStringBundle.GetStringFromName(this._getOutputName(aRoleStr));
+      return Utils.stringBundle.GetStringFromName(
+        this._getOutputName(aRoleStr));
     } catch (x) {
       return '';
     }
   },
 
   _getLocalizedState: function _getLocalizedState(aState) {
     let stateUtterances = [];
 
     if (aState.contains(States.UNAVAILABLE)) {
-      stateUtterances.push(gStringBundle.GetStringFromName('stateUnavailable'));
+      stateUtterances.push(
+        Utils.stringBundle.GetStringFromName('stateUnavailable'));
     }
 
     // Don't utter this in Jelly Bean, we let TalkBack do it for us there.
     // This is because we expose the checked information on the node itself.
     // XXX: this means the checked state is always appended to the end, regardless
     // of the utterance ordering preference.
     if (Utils.AndroidSdkVersion < 16 && aState.contains(States.CHECKABLE)) {
       let statetr = aState.contains(States.CHECKED) ?
         'stateChecked' : 'stateNotChecked';
-      stateUtterances.push(gStringBundle.GetStringFromName(statetr));
+      stateUtterances.push(Utils.stringBundle.GetStringFromName(statetr));
     }
 
     if (aState.contains(States.EXPANDABLE)) {
       let statetr = aState.contains(States.EXPANDED) ?
         'stateExpanded' : 'stateCollapsed';
-      stateUtterances.push(gStringBundle.GetStringFromName(statetr));
+      stateUtterances.push(Utils.stringBundle.GetStringFromName(statetr));
     }
 
     if (aState.contains(States.REQUIRED)) {
-      stateUtterances.push(gStringBundle.GetStringFromName('stateRequired'));
+      stateUtterances.push(
+        Utils.stringBundle.GetStringFromName('stateRequired'));
     }
 
     if (aState.contains(States.TRAVERSED)) {
-      stateUtterances.push(gStringBundle.GetStringFromName('stateTraversed'));
+      stateUtterances.push(
+        Utils.stringBundle.GetStringFromName('stateTraversed'));
     }
 
     if (aState.contains(States.HASPOPUP)) {
-      stateUtterances.push(gStringBundle.GetStringFromName('stateHasPopup'));
+      stateUtterances.push(
+        Utils.stringBundle.GetStringFromName('stateHasPopup'));
     }
 
     if (aState.contains(States.SELECTED)) {
-      stateUtterances.push(gStringBundle.GetStringFromName('stateSelected'));
+      stateUtterances.push(
+        Utils.stringBundle.GetStringFromName('stateSelected'));
     }
 
     return stateUtterances;
   },
 
   _getListUtterance: function _getListUtterance(aAccessible, aRoleStr, aFlags, aItemCount) {
     let desc = [];
     let roleStr = this._getLocalizedRole(aRoleStr);
@@ -739,17 +742,17 @@ this.BrailleGenerator = {
       if (cell) {
         let desc = [];
         let addHeaders = function addHeaders(aDesc, aHeaders) {
           if (aHeaders.length > 0) {
             aDesc.push.apply(aDesc, aHeaders);
           }
         };
 
-        desc.push(gStringBundle.formatStringFromName(
+        desc.push(Utils.stringBundle.formatStringFromName(
           this._getOutputName('cellInfo'), [cell.columnIndex + 1,
             cell.rowIndex + 1], 2));
 
         addHeaders(desc, cell.columnHeaders);
         addHeaders(desc, cell.rowHeaders);
         braille.push(desc.join(' '));
       }
 
@@ -810,20 +813,21 @@ this.BrailleGenerator = {
   },
 
   _getOutputName: function _getOutputName(aName) {
     return OutputGenerator._getOutputName(aName) + 'Abbr';
   },
 
   _getLocalizedRole: function _getLocalizedRole(aRoleStr) {
     try {
-      return gStringBundle.GetStringFromName(this._getOutputName(aRoleStr));
+      return Utils.stringBundle.GetStringFromName(
+        this._getOutputName(aRoleStr));
     } catch (x) {
       try {
-        return gStringBundle.GetStringFromName(
+        return Utils.stringBundle.GetStringFromName(
           OutputGenerator._getOutputName(aRoleStr));
       } catch (y) {
         return '';
       }
     }
   },
 
   _getLocalizedState: function _getLocalizedState(aState) {
--- a/accessible/src/jsat/Presentation.jsm
+++ b/accessible/src/jsat/Presentation.jsm
@@ -494,34 +494,45 @@ SpeechPresenter.prototype = {
         actions: [{
           method: 'speak',
           data: UtteranceGenerator.genForLiveRegion(aContext, aIsHide,
             aModifiedText).join(' '),
           options: {enqueue: aIsPolite}
         }]
       }
     };
+  },
+
+  announce: function SpeechPresenter_announce(aAnnouncement) {
+    return {
+      type: this.type,
+      details: {
+        actions: [{
+          method: 'speak', data: aAnnouncement, options: { enqueue: false }
+        }]
+      }
+    };
   }
 };
 
 /**
  * A haptic presenter
  */
 
 this.HapticPresenter = function HapticPresenter() {};
 
 HapticPresenter.prototype = {
   __proto__: Presenter.prototype,
 
   type: 'Haptic',
 
-  PIVOT_CHANGE_PATTHERN: [20],
+  PIVOT_CHANGE_PATTERN: [40],
 
   pivotChanged: function HapticPresenter_pivotChanged(aContext, aReason) {
-    return { type: this.type, details: { pattern: this.PIVOT_CHANGE_PATTHERN } };
+    return { type: this.type, details: { pattern: this.PIVOT_CHANGE_PATTERN } };
   }
 };
 
 /**
  * A braille presenter
  */
 
 this.BraillePresenter = function BraillePresenter() {};
--- a/accessible/src/jsat/Utils.jsm
+++ b/accessible/src/jsat/Utils.jsm
@@ -164,16 +164,23 @@ this.Utils = {
 
   get isContentProcess() {
     delete this.isContentProcess;
     this.isContentProcess =
       Services.appinfo.processType == Services.appinfo.PROCESS_TYPE_CONTENT;
     return this.isContentProcess;
   },
 
+  get stringBundle() {
+    delete this.stringBundle;
+    this.stringBundle = Services.strings.createBundle(
+      'chrome://global/locale/AccessFu.properties');
+    return this.stringBundle;
+  },
+
   getMessageManager: function getMessageManager(aBrowser) {
     try {
       return aBrowser.QueryInterface(Ci.nsIFrameLoaderOwner).
          frameLoader.messageManager;
     } catch (x) {
       Logger.logException(x);
       return null;
     }
@@ -770,28 +777,33 @@ this.PrefCache = function PrefCache(aNam
     }
   }
 
   branch.addObserver(aName, this, true);
 };
 
 PrefCache.prototype = {
   _getValue: function _getValue(aBranch) {
-    if (!this.type) {
-      this.type = aBranch.getPrefType(this.name);
-    }
-    switch (this.type) {
-      case Ci.nsIPrefBranch.PREF_STRING:
-        return aBranch.getCharPref(this.name);
-      case Ci.nsIPrefBranch.PREF_INT:
-        return aBranch.getIntPref(this.name);
-      case Ci.nsIPrefBranch.PREF_BOOL:
-        return aBranch.getBoolPref(this.name);
-      default:
-        return null;
+    try {
+      if (!this.type) {
+        this.type = aBranch.getPrefType(this.name);
+      }
+      switch (this.type) {
+        case Ci.nsIPrefBranch.PREF_STRING:
+          return aBranch.getCharPref(this.name);
+        case Ci.nsIPrefBranch.PREF_INT:
+          return aBranch.getIntPref(this.name);
+        case Ci.nsIPrefBranch.PREF_BOOL:
+          return aBranch.getBoolPref(this.name);
+        default:
+          return null;
+      }
+    } catch (x) {
+      // Pref does not exist.
+      return null;
     }
   },
 
   observe: function observe(aSubject, aTopic, aData) {
     this.value = this._getValue(aSubject.QueryInterface(Ci.nsIPrefBranch));
     if (this.callback) {
       try {
         this.callback(this.name, this.value);
--- a/accessible/tests/mochitest/hittest/a11y.ini
+++ b/accessible/tests/mochitest/hittest/a11y.ini
@@ -1,9 +1,11 @@
 [DEFAULT]
 support-files = zoom_tree.xul
 
 [test_browser.html]
+[text_canvas_hitregion.html]
+skip-if = os == "android" || appname == "b2g"
 [test_general.html]
 [test_menu.xul]
 [test_zoom.html]
 [test_zoom_text.html]
 [test_zoom_tree.xul]
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/hittest/test_canvas_hitregion.html
@@ -0,0 +1,88 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <title>nsIAccessible::childAtPoint() for canvas from browser tests</title>
+  <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+
+  <script type="application/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+
+  <script type="application/javascript"
+          src="../common.js"></script>
+  <script type="application/javascript"
+          src="../layout.js"></script>
+
+  <script type="application/javascript">
+    SpecialPowers.setBoolPref("canvas.hitregions.enabled", true);
+
+    function redrawCheckbox(context, element, x, y)
+    {
+      context.save();
+      context.font = '10px sans-serif';
+      context.textAlign = 'left';
+      context.textBaseline = 'middle';
+      var metrics = context.measureText(element.parentNode.textContent);
+      context.beginPath();
+      context.strokeStyle = 'black';
+      context.rect(x-5, y-5, 10, 10);
+      context.stroke();
+      if (element.checked) {
+        context.fillStyle = 'black';
+        context.fill();
+      }
+      context.fillText(element.parentNode.textContent, x+5, y);
+
+      context.beginPath();
+      context.rect(x-7, y-7, 12 + metrics.width+2, 14);
+
+      if (document.activeElement == element)
+        context.drawFocusIfNeeded(element);
+      context.addHitRegion({control: element});
+      context.restore();
+    }
+
+    function doTest()
+    {
+      getNode("hittest").scrollIntoView(true);
+
+      var context = document.getElementById("hitcanvas").getContext('2d');
+      redrawCheckbox(context, document.getElementById('hitcheck'), 20, 40);
+
+      var hitcanvas = getAccessible("hitcanvas");
+      var hitcheck = getAccessible("hitcheck");
+
+      var [hitX, hitY, hitWidth, hitHeight] = getBounds(hitcanvas);
+
+      var docAcc = getAccessible(document);
+      var tgtX = hitX+25;
+      var tgtY = hitY+45;
+      hitAcc = docAcc.getDeepestChildAtPoint(tgtX, tgtY);
+      // test if we hit the region associated with the shadow dom checkbox
+      is(hitAcc, hitcheck, "Hit match at " + tgtX + "," + tgtY +
+                          ". Found: " + prettyName(hitAcc));
+
+      tgtY = hitY+75;
+      hitAcc = docAcc.getDeepestChildAtPoint(tgtX, tgtY);
+      // test that we don't hit the region associated with the shadow dom checkbox
+      is(hitAcc, hitcanvas, "Hit match at " + tgtX + "," + tgtY +
+                          ". Found: " + prettyName(hitAcc));
+
+      SpecialPowers.setBoolPref("canvas.hitregions.enabled", false);
+      SimpleTest.finish();
+    }
+
+    SimpleTest.waitForExplicitFinish();
+    addA11yLoadEvent(doTest);
+  </script>
+</head>
+<body>
+
+  <a target="_blank"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=966591"
+     title="nsIAccessible::childAtPoint() for canvas hit regions from browser tests">Mozilla Bug 966591</a>
+
+  <canvas id="hitcanvas">
+    <input id="hitcheck" type="checkbox"><label for="showA"> Show A </label>
+  </canvas>
+</body>
+</html>
--- a/accessible/tests/mochitest/jsat/jsatcommon.js
+++ b/accessible/tests/mochitest/jsat/jsatcommon.js
@@ -88,26 +88,21 @@ var AccessFuTest = {
   waitForExplicitFinish: function AccessFuTest_waitForExplicitFinish() {
     this._waitForExplicitFinish = true;
   },
 
   finish: function AccessFuTest_finish() {
     // Disable the console service logging.
     Logger.test = false;
     Logger.logLevel = Logger.INFO;
-    AccessFu.doneCallback = function doneCallback() {
-      // This is being called once AccessFu has been shut down.
-      // Detach AccessFu from everything it attached itself to.
+    // Finish through idle callback to let AccessFu._disable complete.
+    SimpleTest.executeSoon(function () {
       AccessFu.detach();
-      // and finish the test run.
       SimpleTest.finish();
-    };
-    // Tear down accessibility and make AccessFu stop.
-    SpecialPowers.setIntPref("accessibility.accessfu.notify_output", 0);
-    SpecialPowers.setIntPref("accessibility.accessfu.activate", 0);
+    });
   },
 
   nextTest: function AccessFuTest_nextTest() {
     var testFunc;
     try {
       // Get the next test function from the iterator. If none left,
       // StopIteration exception is thrown.
       testFunc = gIterator.next()[1];
@@ -133,31 +128,31 @@ var AccessFuTest = {
     Components.utils.import("resource://gre/modules/accessibility/AccessFu.jsm");
 
     AccessFu.attach(getMainChromeWindow(window));
 
     AccessFu.readyCallback = function readyCallback() {
       // Enable logging to the console service.
       Logger.test = true;
       Logger.logLevel = Logger.DEBUG;
-      // This is being called once accessibility has been turned on.
+    };
 
+    SpecialPowers.pushPrefEnv({
+      'set': [['accessibility.accessfu.notify_output', 1],
+              ['dom.mozSettings.enabled', true]]
+    }, function () {
       if (AccessFuTest._waitForExplicitFinish) {
         // Run all test functions asynchronously.
         AccessFuTest.nextTest();
       } else {
         // Run all test functions synchronously.
         [testFunc() for (testFunc of gTestFuncs)];
         AccessFuTest.finish();
       }
-    };
-
-    // Invoke the whole thing.
-    SpecialPowers.setIntPref("accessibility.accessfu.activate", 1);
-    SpecialPowers.setIntPref("accessibility.accessfu.notify_output", 1);
+    });
   }
 };
 
 function AccessFuContentTest(aFuncResultPairs) {
   this.queue = aFuncResultPairs;
 }
 
 AccessFuContentTest.prototype = {
--- a/accessible/tests/mochitest/jsat/test_alive.html
+++ b/accessible/tests/mochitest/jsat/test_alive.html
@@ -8,53 +8,67 @@
   <script type="application/javascript"
           src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
   <script type="application/javascript"
           src="../common.js"></script>
   <script type="application/javascript"
           src="./jsatcommon.js"></script>
   <script type="application/javascript">
 
-    function confirmAccessFuStart() {
-      ok(AccessFu._enabled, "AccessFu was started and enabled.");
-      AccessFuTest.nextTest();
+    function prefStart() {
+      // Start AccessFu via pref.
+      SpecialPowers.setIntPref("accessibility.accessfu.activate", 1);
+      AccessFuTest.once_log("EventManager.start", AccessFuTest.nextTest);
     }
 
     // Listen for 'EventManager.stop' and enable AccessFu again.
-    function onStop() {
+    function settingsStart() {
       ok(true, "EventManager was stopped.");
       isnot(AccessFu._enabled, true, "AccessFu was disabled.");
-      AccessFuTest.once_log("EventManager.start", AccessFuTest.nextTest);
-      AccessFu._enable();
+      AccessFuTest.once([{
+        "method": "speak",
+        "data": "Screen reader started",
+        "options": {
+          "enqueue": false
+        }
+      }], AccessFuTest.nextTest);
+      // XXX: Bug 978076 - test start with SettingsManager.
+      //navigator.mozSettings.createLock().set(
+      //  {'accessibility.screenreader': false});
+      AccessFu._enable()
     }
 
     // Make sure EventManager is started again.
-    function onFinalStart() {
-      ok(true, "EventManager was started again.");
+    function settingsStop() {
       ok(AccessFu._enabled, "AccessFu was enabled again.");
-      AccessFuTest.finish();
+      AccessFuTest.once([{
+        "method": "speak",
+        "data": "Screen reader stopped",
+        "options": {
+          "enqueue": false
+        }
+      }], AccessFuTest.finish);
+      // XXX: Bug 978076 - test stop with SettingsManager.
+      //navigator.mozSettings.createLock().set(
+      //  {'accessibility.screenreader': false});
+      AccessFu._disable();
     }
 
     // Listen for initial 'EventManager.start' and disable AccessFu.
-    function onInitialStart() {
-      ok(true, "EventManager was started.");
+    function prefStop() {
+      ok(AccessFu._enabled, "AccessFu was started via preference.");
       AccessFuTest.once_log("EventManager.stop", AccessFuTest.nextTest);
-      AccessFu._disable();
-    }
-
-    function init() {
-      AccessFuTest.once_log("EventManager.start", AccessFuTest.nextTest);
+      SpecialPowers.setIntPref("accessibility.accessfu.activate", 0);
     }
 
     function doTest() {
-      AccessFuTest.addFunc(confirmAccessFuStart);
-      AccessFuTest.addFunc(init);
-      AccessFuTest.addFunc(onInitialStart);
-      AccessFuTest.addFunc(onStop);
-      AccessFuTest.addFunc(onFinalStart);
+      AccessFuTest.addFunc(prefStart);
+      AccessFuTest.addFunc(prefStop);
+      AccessFuTest.addFunc(settingsStart);
+      AccessFuTest.addFunc(settingsStop);
       AccessFuTest.waitForExplicitFinish();
       AccessFuTest.runTests();  // Will call SimpleTest.finish();
     }
 
     SimpleTest.waitForExplicitFinish();
     addA11yLoadEvent(doTest);
   </script>
 
--- a/accessible/tests/mochitest/jsat/test_live_regions.html
+++ b/accessible/tests/mochitest/jsat/test_live_regions.html
@@ -8,20 +8,26 @@
   <script type="application/javascript"
           src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
   <script type="application/javascript"
           src="../common.js"></script>
   <script type="application/javascript"
           src="./jsatcommon.js"></script>
   <script type="application/javascript">
 
-    function EventManagerStarted() {
+    function startAccessFu() {
+      SpecialPowers.setIntPref("accessibility.accessfu.activate", 1);
       AccessFuTest.once_log("EventManager.start", AccessFuTest.nextTest);
     }
 
+    function stopAccessFu() {
+      SpecialPowers.setIntPref("accessibility.accessfu.activate", 0);
+      AccessFuTest.once_log("EventManager.stop", AccessFuTest.finish);
+    }
+
     function hide(id) {
       var element = document.getElementById(id);
       element.style.display = "none";
     }
 
     function show(id) {
       var element = document.getElementById(id);
       element.style.display = "block";
@@ -240,24 +246,24 @@
         }
       }],
       action: function action() {
         updateHTML("to_replace_text", "I am a replaced text");
       }
     }];
 
     function doTest() {
-      AccessFuTest.addFunc(EventManagerStarted);
+      AccessFuTest.addFunc(startAccessFu);
       tests.forEach(function addTest(test) {
         AccessFuTest.addFunc(function () {
           AccessFuTest.once(test.expected, AccessFuTest.nextTest);
           test.action();
         });
       });
-      AccessFuTest.addFunc(AccessFuTest.finish);
+      AccessFuTest.addFunc(stopAccessFu);
       AccessFuTest.waitForExplicitFinish();
       AccessFuTest.runTests();
     }
 
     SimpleTest.waitForExplicitFinish();
     addA11yLoadEvent(doTest);
   </script>
 
--- a/browser/base/content/browser-plugins.js
+++ b/browser/base/content/browser-plugins.js
@@ -125,17 +125,17 @@ var gPluginHandler = {
                    [right, top],
                    [right, bottom],
                    [centerX, centerY]];
 
     if (right <= 0 || top <= 0) {
       return false;
     }
 
-    let contentWindow = plugin.ownerDocument.defaultView.top;
+    let contentWindow = plugin.ownerDocument.defaultView;
     let cwu = contentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
                            .getInterface(Ci.nsIDOMWindowUtils);
 
     for (let [x, y] of points) {
       let el = cwu.elementFromPoint(x, y, true, true);
       if (el !== plugin) {
         return false;
       }
--- a/browser/base/content/test/general/browser.ini
+++ b/browser/base/content/test/general/browser.ini
@@ -1,25 +1,19 @@
 [DEFAULT]
 support-files =
   POSTSearchEngine.xml
   accounts_testRemoteCommands.html
   alltabslistener.html
   app_bug575561.html
   app_subframe_bug575561.html
   authenticate.sjs
-  blockNoPlugins.xml
-  blockPluginHard.xml
-  blockPluginVulnerableNoUpdate.xml
-  blockPluginVulnerableUpdatable.xml
   browser_bug479408_sample.html
   browser_bug678392-1.html
   browser_bug678392-2.html
-  browser_clearplugindata.html
-  browser_clearplugindata_noage.html
   browser_registerProtocolHandler_notification.html
   browser_star_hsts.sjs
   browser_tab_dragdrop2_frame1.xul
   bug564387.html
   bug564387_video1.ogv
   bug564387_video1.ogv^headers^
   bug592338.html
   bug792517-2.html
@@ -60,42 +54,16 @@ support-files =
   file_fullscreen-window-open.html
   get_user_media.html
   head.js
   healthreport_testRemoteCommands.html
   moz.png
   offlineQuotaNotification.cacheManifest
   offlineQuotaNotification.html
   page_style_sample.html
-  plugin_add_dynamically.html
-  plugin_alternate_content.html
-  plugin_big.html
-  plugin_both.html
-  plugin_both2.html
-  plugin_bug744745.html
-  plugin_bug749455.html
-  plugin_bug752516.html
-  plugin_bug787619.html
-  plugin_bug797677.html
-  plugin_bug820497.html
-  plugin_clickToPlayAllow.html
-  plugin_clickToPlayDeny.html
-  plugin_data_url.html
-  plugin_hidden_to_visible.html
-  plugin_outsideScrollArea.html
-  plugin_overlayed.html
-  plugin_positioned.html
-  plugin_small.html
-  plugin_syncRemoved.html
-  plugin_test.html
-  plugin_test2.html
-  plugin_test3.html
-  plugin_two_types.html
-  plugin_unknown.html
-  pluginCrashCommentAndURL.html
   print_postdata.sjs
   redirect_bug623155.sjs
   test-mixedcontent-securityerrors.html
   test_bug435035.html
   test_bug462673.html
   test_bug628179.html
   test_bug839103.html
   test_bug959531.html
@@ -106,29 +74,18 @@ support-files =
   test_no_mcb_on_http_site_img.html
   test_no_mcb_on_http_site_img.css
   test_no_mcb_on_http_site_font.html
   test_no_mcb_on_http_site_font.css
   test_no_mcb_on_http_site_font2.html
   test_no_mcb_on_http_site_font2.css
   xul_tooltiptext.xhtml
 
-[browser_CTP_context_menu.js]
-skip-if = toolkit == "gtk2" || toolkit == "gtk3"   # browser_CTP_context_menu.js fails intermittently on Linux (bug 909342)
-[browser_CTP_crashreporting.js]
-run-if = crashreporter
-[browser_CTP_data_urls.js]
-[browser_CTP_drag_drop.js]
-[browser_CTP_hide_overlay.js]
-[browser_CTP_multi_allow.js]
-[browser_CTP_nonplugins.js]
-[browser_CTP_notificationBar.js]
-[browser_CTP_outsideScrollArea.js]
-[browser_CTP_resize.js]
 [browser_URLBarSetURI.js]
+skip-if = (os == "linux" || os == "mac") && debug # bug 970052, bug 970053
 [browser_aboutAccounts.js]
 skip-if = os == "linux" # Bug 958026
 [browser_aboutHealthReport.js]
 skip-if = os == "linux" # Bug 924307
 [browser_aboutHome.js]
 [browser_aboutSyncProgress.js]
 [browser_addKeywordSearch.js]
 [browser_alltabslistener.js]
@@ -224,40 +181,31 @@ run-if = toolkit == "cocoa"
 [browser_bug676619.js]
 skip-if = os == "mac" # Intermittent failures, bug 925225
 [browser_bug678392.js]
 [browser_bug710878.js]
 [browser_bug719271.js]
 [browser_bug724239.js]
 [browser_bug734076.js]
 [browser_bug735471.js]
-[browser_bug743421.js]
-[browser_bug744745.js]
 [browser_bug749738.js]
-[browser_bug752516.js]
 [browser_bug763468_perwindowpb.js]
 [browser_bug767836_perwindowpb.js]
 [browser_bug771331.js]
 [browser_bug783614.js]
-[browser_bug787619.js]
-[browser_bug797677.js]
-[browser_bug812562.js]
 [browser_bug816527.js]
 [browser_bug817947.js]
-[browser_bug818118.js]
-[browser_bug820497.js]
 [browser_bug822367.js]
 [browser_bug832435.js]
 [browser_bug839103.js]
 [browser_bug880101.js]
 [browser_bug882977.js]
 [browser_bug902156.js]
 [browser_bug906190.js]
 [browser_canonizeURL.js]
-[browser_clearplugindata.js]
 [browser_contentAreaClick.js]
 [browser_contextSearchTabPosition.js]
 skip-if = os == "mac" # bug 967013, bug 926729
 [browser_ctrlTab.js]
 [browser_customize_popupNotification.js]
 [browser_datareporting_notification.js]
 run-if = datareporting
 [browser_discovery.js]
@@ -283,26 +231,19 @@ skip-if = os == "linux" # Intermittent f
 skip-if = os != "win" # The Fitts Law menu button is only supported on Windows (bug 969376)
 [browser_middleMouse_inherit.js]
 [browser_minimize.js]
 [browser_mixedcontent_securityflags.js]
 [browser_notification_tab_switching.js]
 [browser_offlineQuotaNotification.js]
 [browser_overflowScroll.js]
 [browser_pageInfo.js]
-[browser_pageInfo_plugins.js]
 [browser_page_style_menu.js]
 [browser_pinnedTabs.js]
 [browser_plainTextLinks.js]
-[browser_pluginnotification.js]
-[browser_pluginplaypreview.js]
-[browser_pluginplaypreview2.js]
-[browser_pluginCrashCommentAndURL.js]
-run-if = crashreporter
-[browser_plugins_added_dynamically.js]
 [browser_popupNotification.js]
 skip-if = toolkit == "windows" # Disabled on Windows due to frequent failures (bugs 825739, 841341)
 [browser_popupUI.js]
 [browser_printpreview.js]
 [browser_private_browsing_window.js]
 [browser_private_no_prompt.js]
 [browser_relatedTabs.js]
 [browser_removeTabsToTheEnd.js]
deleted file mode 100644
--- a/browser/base/content/test/general/browser_bug752516.js
+++ /dev/null
@@ -1,45 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- *  License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-Components.utils.import("resource://gre/modules/Services.jsm");
-
-var gTestBrowser = null;
-
-function test() {
-  waitForExplicitFinish();
-  registerCleanupFunction(function() {
-    Services.prefs.clearUserPref("plugins.click_to_play");
-    gBrowser.removeCurrentTab();
-    window.focus();
-  });
-
-  Services.prefs.setBoolPref("plugins.click_to_play", true);
-  setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY);
-
-  gBrowser.selectedTab = gBrowser.addTab();
-  gTestBrowser = gBrowser.selectedBrowser;
-  let gHttpTestRoot = getRootDirectory(gTestPath).replace("chrome://mochitests/content/", "http://127.0.0.1:8888/");
-  gTestBrowser.contentWindow.location = gHttpTestRoot + "plugin_bug752516.html";
-
-  gTestBrowser.addEventListener("load", tabLoad, true);
-}
-
-function tabLoad() {
-  // Due to layout being async, "PluginBindAttached" may trigger later.
-  // This forces a layout flush, thus triggering it, and schedules the
-  // test so it is definitely executed afterwards.
-  gTestBrowser.contentDocument.getElementById('test').clientTop;
-  executeSoon(actualTest);
-}
-
-function actualTest() {
-  let doc = gTestBrowser.contentDocument;
-  let plugin = doc.getElementById("test");
-  ok(!plugin.activated, "Plugin should not be activated");
-  ok(PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser).dismissed, "Doorhanger should not be open");
-
-  EventUtils.synthesizeMouseAtCenter(plugin, {}, gTestBrowser.contentWindow);
-  let condition = function() !PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser).dismissed;
-  waitForCondition(condition, finish, "Waited too long for plugin doorhanger to activate");
-}
deleted file mode 100644
--- a/browser/base/content/test/general/plugin_bug752516.html
+++ /dev/null
@@ -1,24 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <meta charset="utf-8"/>
-  <style type="text/css">
-    div {
-      padding: 2%;
-      position: absolute;
-      top: 0; bottom: 0;
-      left: 0; right: 0;
-      text-align: center;
-      border: 4px solid red;
-    }
-  </style>
-</head>
-<body>
-  <div id="container">
-    <object id="test" type="application/x-test" width="159" height="91"></object>
-  </div>
-  <div id="overlay">
-  	<h1>overlay</h1>
-  </div>
-</body>
-</html>
rename from browser/base/content/test/general/blockNoPlugins.xml
rename to browser/base/content/test/plugins/blockNoPlugins.xml
rename from browser/base/content/test/general/blockPluginHard.xml
rename to browser/base/content/test/plugins/blockPluginHard.xml
rename from browser/base/content/test/general/blockPluginVulnerableNoUpdate.xml
rename to browser/base/content/test/plugins/blockPluginVulnerableNoUpdate.xml
rename from browser/base/content/test/general/blockPluginVulnerableUpdatable.xml
rename to browser/base/content/test/plugins/blockPluginVulnerableUpdatable.xml
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/plugins/browser.ini
@@ -0,0 +1,64 @@
+[DEFAULT]
+support-files =
+  blockNoPlugins.xml
+  blockPluginHard.xml
+  blockPluginVulnerableNoUpdate.xml
+  blockPluginVulnerableUpdatable.xml
+  browser_clearplugindata.html
+  browser_clearplugindata_noage.html
+  head.js
+  plugin_add_dynamically.html
+  plugin_alternate_content.html
+  plugin_big.html
+  plugin_both.html
+  plugin_both2.html
+  plugin_bug744745.html
+  plugin_bug749455.html
+  plugin_bug787619.html
+  plugin_bug797677.html
+  plugin_bug820497.html
+  plugin_clickToPlayAllow.html
+  plugin_clickToPlayDeny.html
+  plugin_data_url.html
+  plugin_hidden_to_visible.html
+  plugin_iframe.html
+  plugin_outsideScrollArea.html
+  plugin_overlayed.html
+  plugin_positioned.html
+  plugin_small.html
+  plugin_syncRemoved.html
+  plugin_test.html
+  plugin_test2.html
+  plugin_test3.html
+  plugin_two_types.html
+  plugin_unknown.html
+  plugin_crashCommentAndURL.html
+
+[browser_bug743421.js]
+[browser_bug744745.js]
+[browser_bug787619.js]
+[browser_bug797677.js]
+[browser_bug812562.js]
+[browser_bug818118.js]
+[browser_bug820497.js]
+[browser_clearplugindata.js]
+[browser_CTP_context_menu.js]
+skip-if = toolkit == "gtk2" || toolkit == "gtk3"   # browser_CTP_context_menu.js fails intermittently on Linux (bug 909342)
+[browser_CTP_crashreporting.js]
+run-if = crashreporter
+[browser_CTP_data_urls.js]
+[browser_CTP_drag_drop.js]
+[browser_CTP_hide_overlay.js]
+[browser_CTP_iframe.js]
+[browser_CTP_multi_allow.js]
+[browser_CTP_nonplugins.js]
+[browser_CTP_notificationBar.js]
+[browser_CTP_outsideScrollArea.js]
+[browser_CTP_resize.js]
+[browser_pageInfo_plugins.js]
+[browser_pluginnotification.js]
+[browser_pluginplaypreview.js]
+[browser_pluginplaypreview2.js]
+[browser_pluginCrashCommentAndURL.js]
+run-if = crashreporter
+[browser_plugins_added_dynamically.js]
rename from browser/base/content/test/general/browser_CTP_context_menu.js
rename to browser/base/content/test/plugins/browser_CTP_context_menu.js
rename from browser/base/content/test/general/browser_CTP_crashreporting.js
rename to browser/base/content/test/plugins/browser_CTP_crashreporting.js
rename from browser/base/content/test/general/browser_CTP_data_urls.js
rename to browser/base/content/test/plugins/browser_CTP_data_urls.js
rename from browser/base/content/test/general/browser_CTP_drag_drop.js
rename to browser/base/content/test/plugins/browser_CTP_drag_drop.js
rename from browser/base/content/test/general/browser_CTP_hide_overlay.js
rename to browser/base/content/test/plugins/browser_CTP_hide_overlay.js
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/plugins/browser_CTP_iframe.js
@@ -0,0 +1,102 @@
+let rootDir = getRootDirectory(gTestPath);
+const gTestRoot = rootDir;
+const gHttpTestRoot = rootDir.replace("chrome://mochitests/content/", "http://127.0.0.1:8888/");
+
+let gTestBrowser = null;
+let gNextTest = null;
+
+Components.utils.import("resource://gre/modules/Services.jsm");
+
+function test() {
+  waitForExplicitFinish();
+  registerCleanupFunction(function() {
+    clearAllPluginPermissions();
+    Services.prefs.clearUserPref("extensions.blocklist.suppressUI");
+  });
+  Services.prefs.setBoolPref("extensions.blocklist.suppressUI", true);
+
+  let newTab = gBrowser.addTab();
+  gBrowser.selectedTab = newTab;
+  gTestBrowser = gBrowser.selectedBrowser;
+  gTestBrowser.addEventListener("load", pageLoad, true);
+
+  Services.prefs.setBoolPref("plugins.click_to_play", true);
+  setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY);
+
+  prepareTest(delayTest(runAfterPluginBindingAttached(test1)), gHttpTestRoot + "plugin_iframe.html");
+}
+
+function finishTest() {
+  clearAllPluginPermissions();
+  gTestBrowser.removeEventListener("load", pageLoad, true);
+  gBrowser.removeCurrentTab();
+  window.focus();
+  finish();
+}
+
+function pageLoad() {
+  gNextTest();
+}
+
+function prepareTest(nextTest, url) {
+  gNextTest = nextTest;
+  gTestBrowser.contentWindow.location = url;
+}
+
+// Delay executing a test for one load event to wait for frame loads.
+function delayTest(nextTest) {
+  return () => {
+    gNextTest = nextTest;
+  }
+}
+
+// Due to layout being async, "PluginBindAttached" may trigger later.
+// This wraps a function to force a layout flush, thus triggering it,
+// and schedules the function execution so they're definitely executed
+// afterwards.
+function runAfterPluginBindingAttached(func) {
+  return () => {
+    let frame = gTestBrowser.contentDocument.getElementById("frame");
+    let doc = frame.contentDocument;
+    let elems = doc.getElementsByTagName('embed');
+    if (elems.length < 1) {
+      elems = doc.getElementsByTagName('object');
+    }
+    elems[0].clientTop;
+    executeSoon(func);
+  };
+}
+
+// Tests that the overlays are visible and actionable if the plugin is in an iframe.
+function test1() {
+  let frame = gTestBrowser.contentDocument.getElementById("frame");
+  let doc = frame.contentDocument;
+  let plugin = doc.getElementById("test");
+  ok(plugin, "Test 1, Found plugin in page");
+
+  let overlay = doc.getAnonymousElementByAttribute(plugin, "anonid", "main");
+  ok(overlay.classList.contains("visible"), "Test 1, Plugin overlay should exist, not be hidden");
+  let closeIcon = doc.getAnonymousElementByAttribute(plugin, "anonid", "closeIcon")
+
+  EventUtils.synthesizeMouseAtCenter(closeIcon, {}, frame.contentWindow);
+  let condition = () => !overlay.classList.contains("visible");
+  waitForCondition(condition, test2, "Test 1, Waited too long for the overlay to become invisible.");
+}
+
+function test2() {
+  prepareTest(delayTest(runAfterPluginBindingAttached(test3)), gHttpTestRoot + "plugin_iframe.html");
+}
+
+function test3() {
+  let frame = gTestBrowser.contentDocument.getElementById("frame");
+  let doc = frame.contentDocument;
+  let plugin = doc.getElementById("test");
+  ok(plugin, "Test 3, Found plugin in page");
+
+  let overlay = doc.getAnonymousElementByAttribute(plugin, "anonid", "main");
+  ok(overlay.classList.contains("visible"), "Test 3, Plugin overlay should exist, not be hidden");
+
+  EventUtils.synthesizeMouseAtCenter(plugin, {}, frame.contentWindow);
+  let condition = () => PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
+  waitForCondition(condition, finishTest, "Test 3, Waited too long for the doorhanger to pop up.");
+}
rename from browser/base/content/test/general/browser_CTP_multi_allow.js
rename to browser/base/content/test/plugins/browser_CTP_multi_allow.js
rename from browser/base/content/test/general/browser_CTP_nonplugins.js
rename to browser/base/content/test/plugins/browser_CTP_nonplugins.js
rename from browser/base/content/test/general/browser_CTP_notificationBar.js
rename to browser/base/content/test/plugins/browser_CTP_notificationBar.js
rename from browser/base/content/test/general/browser_CTP_outsideScrollArea.js
rename to browser/base/content/test/plugins/browser_CTP_outsideScrollArea.js
rename from browser/base/content/test/general/browser_CTP_resize.js
rename to browser/base/content/test/plugins/browser_CTP_resize.js
rename from browser/base/content/test/general/browser_bug743421.js
rename to browser/base/content/test/plugins/browser_bug743421.js
--- a/browser/base/content/test/general/browser_bug743421.js
+++ b/browser/base/content/test/plugins/browser_bug743421.js
@@ -1,9 +1,10 @@
-const gTestRoot = "http://mochi.test:8888/browser/browser/base/content/test/general/";
+var rootDir = getRootDirectory(gTestPath);
+const gTestRoot = rootDir.replace("chrome://mochitests/content/", "http://mochi.test:8888/");
 
 var gTestBrowser = null;
 var gNextTest = null;
 
 Components.utils.import("resource://gre/modules/Services.jsm");
 
 function test() {
   waitForExplicitFinish();
rename from browser/base/content/test/general/browser_bug744745.js
rename to browser/base/content/test/plugins/browser_bug744745.js
rename from browser/base/content/test/general/browser_bug787619.js
rename to browser/base/content/test/plugins/browser_bug787619.js
rename from browser/base/content/test/general/browser_bug797677.js
rename to browser/base/content/test/plugins/browser_bug797677.js
rename from browser/base/content/test/general/browser_bug812562.js
rename to browser/base/content/test/plugins/browser_bug812562.js
rename from browser/base/content/test/general/browser_bug818118.js
rename to browser/base/content/test/plugins/browser_bug818118.js
rename from browser/base/content/test/general/browser_bug820497.js
rename to browser/base/content/test/plugins/browser_bug820497.js
rename from browser/base/content/test/general/browser_clearplugindata.html
rename to browser/base/content/test/plugins/browser_clearplugindata.html
rename from browser/base/content/test/general/browser_clearplugindata.js
rename to browser/base/content/test/plugins/browser_clearplugindata.js
--- a/browser/base/content/test/general/browser_clearplugindata.js
+++ b/browser/base/content/test/plugins/browser_clearplugindata.js
@@ -1,16 +1,19 @@
 /**
  * Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
+var rootDir = getRootDirectory(gTestPath);
+const gHttpTestRoot = rootDir.replace("chrome://mochitests/content/", "http://mochi.test:8888/");
+
 // Test clearing plugin data using sanitize.js.
-const testURL1 = "http://mochi.test:8888/browser/browser/base/content/test/general/browser_clearplugindata.html";
-const testURL2 = "http://mochi.test:8888/browser/browser/base/content/test/general/browser_clearplugindata_noage.html";
+const testURL1 = gHttpTestRoot + "browser_clearplugindata.html";
+const testURL2 = gHttpTestRoot + "browser_clearplugindata_noage.html";
 
 let tempScope = {};
 Cc["@mozilla.org/moz/jssubscript-loader;1"].getService(Ci.mozIJSSubScriptLoader)
                                            .loadSubScript("chrome://browser/content/sanitize.js", tempScope);
 let Sanitizer = tempScope.Sanitizer;
 
 const pluginHostIface = Ci.nsIPluginHost;
 var pluginHost = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
rename from browser/base/content/test/general/browser_clearplugindata_noage.html
rename to browser/base/content/test/plugins/browser_clearplugindata_noage.html
rename from browser/base/content/test/general/browser_pageInfo_plugins.js
rename to browser/base/content/test/plugins/browser_pageInfo_plugins.js
rename from browser/base/content/test/general/browser_pluginCrashCommentAndURL.js
rename to browser/base/content/test/plugins/browser_pluginCrashCommentAndURL.js
--- a/browser/base/content/test/general/browser_pluginCrashCommentAndURL.js
+++ b/browser/base/content/test/plugins/browser_pluginCrashCommentAndURL.js
@@ -1,15 +1,15 @@
 /* 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/. */
 
 Cu.import("resource://gre/modules/Services.jsm");
 
-const CRASH_URL = "http://example.com/browser/browser/base/content/test/general/pluginCrashCommentAndURL.html";
+const CRASH_URL = "http://example.com/browser/browser/base/content/test/plugins/plugin_crashCommentAndURL.html";
 
 const SERVER_URL = "http://example.com/browser/toolkit/crashreporter/test/browser/crashreport.sjs";
 
 function test() {
   // Crashing the plugin takes up a lot of time, so extend the test timeout.
   requestLongerTimeout(runs.length);
   waitForExplicitFinish();
   setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED);
rename from browser/base/content/test/general/browser_pluginnotification.js
rename to browser/base/content/test/plugins/browser_pluginnotification.js
rename from browser/base/content/test/general/browser_pluginplaypreview.js
rename to browser/base/content/test/plugins/browser_pluginplaypreview.js
rename from browser/base/content/test/general/browser_pluginplaypreview2.js
rename to browser/base/content/test/plugins/browser_pluginplaypreview2.js
rename from browser/base/content/test/general/browser_plugins_added_dynamically.js
rename to browser/base/content/test/plugins/browser_plugins_added_dynamically.js
--- a/browser/base/content/test/general/browser_plugins_added_dynamically.js
+++ b/browser/base/content/test/plugins/browser_plugins_added_dynamically.js
@@ -1,9 +1,10 @@
-const gTestRoot = "http://mochi.test:8888/browser/browser/base/content/test/general/";
+var rootDir = getRootDirectory(gTestPath);
+const gTestRoot = rootDir.replace("chrome://mochitests/content/", "http://mochi.test:8888/");
 
 let gTestBrowser = null;
 let gNextTest = null;
 let gPluginHost = Components.classes["@mozilla.org/plugin/host;1"].getService(Components.interfaces.nsIPluginHost);
 
 Components.utils.import("resource://gre/modules/Services.jsm");
 
 // Let's do the XPCNativeWrapper dance!
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/plugins/head.js
@@ -0,0 +1,110 @@
+Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+
+XPCOMUtils.defineLazyModuleGetter(this, "Promise",
+  "resource://gre/modules/commonjs/sdk/core/promise.js");
+XPCOMUtils.defineLazyModuleGetter(this, "Task",
+  "resource://gre/modules/Task.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
+  "resource://gre/modules/PlacesUtils.jsm");
+
+function whenDelayedStartupFinished(aWindow, aCallback) {
+  Services.obs.addObserver(function observer(aSubject, aTopic) {
+    if (aWindow == aSubject) {
+      Services.obs.removeObserver(observer, aTopic);
+      executeSoon(aCallback);
+    }
+  }, "browser-delayed-startup-finished", false);
+}
+
+function findChromeWindowByURI(aURI) {
+  let windows = Services.wm.getEnumerator(null);
+  while (windows.hasMoreElements()) {
+    let win = windows.getNext();
+    if (win.location.href == aURI)
+      return win;
+  }
+  return null;
+}
+
+function waitForCondition(condition, nextTest, errorMsg) {
+  var tries = 0;
+  var interval = setInterval(function() {
+    if (tries >= 30) {
+      ok(false, errorMsg);
+      moveOn();
+    }
+    var conditionPassed;
+    try {
+      conditionPassed = condition();
+    } catch (e) {
+      ok(false, e + "\n" + e.stack);
+      conditionPassed = false;
+    }
+    if (conditionPassed) {
+      moveOn();
+    }
+    tries++;
+  }, 100);
+  var moveOn = function() { clearInterval(interval); nextTest(); };
+}
+
+function getTestPlugin(aName) {
+  var pluginName = aName || "Test Plug-in";
+  var ph = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
+  var tags = ph.getPluginTags();
+
+  // Find the test plugin
+  for (var i = 0; i < tags.length; i++) {
+    if (tags[i].name == pluginName)
+      return tags[i];
+  }
+  ok(false, "Unable to find plugin");
+  return null;
+}
+
+// call this to set the test plugin(s) initially expected enabled state.
+// it will automatically be reset to it's previous value after the test
+// ends
+function setTestPluginEnabledState(newEnabledState, pluginName) {
+  var plugin = getTestPlugin(pluginName);
+  var oldEnabledState = plugin.enabledState;
+  plugin.enabledState = newEnabledState;
+  SimpleTest.registerCleanupFunction(function() {
+    getTestPlugin(pluginName).enabledState = oldEnabledState;
+  });
+}
+
+// after a test is done using the plugin doorhanger, we should just clear
+// any permissions that may have crept in
+function clearAllPluginPermissions() {
+  let perms = Services.perms.enumerator;
+  while (perms.hasMoreElements()) {
+    let perm = perms.getNext();
+    if (perm.type.startsWith('plugin')) {
+      Services.perms.remove(perm.host, perm.type);
+    }
+  }
+}
+
+function updateBlocklist(aCallback) {
+  var blocklistNotifier = Cc["@mozilla.org/extensions/blocklist;1"]
+                          .getService(Ci.nsITimerCallback);
+  var observer = function() {
+    Services.obs.removeObserver(observer, "blocklist-updated");
+    SimpleTest.executeSoon(aCallback);
+  };
+  Services.obs.addObserver(observer, "blocklist-updated", false);
+  blocklistNotifier.notify(null);
+}
+
+var _originalTestBlocklistURL = null;
+function setAndUpdateBlocklist(aURL, aCallback) {
+  if (!_originalTestBlocklistURL)
+    _originalTestBlocklistURL = Services.prefs.getCharPref("extensions.blocklist.url");
+  Services.prefs.setCharPref("extensions.blocklist.url", aURL);
+  updateBlocklist(aCallback);
+}
+
+function resetBlocklist() {
+  Services.prefs.setCharPref("extensions.blocklist.url", _originalTestBlocklistURL);
+}
rename from browser/base/content/test/general/plugin_add_dynamically.html
rename to browser/base/content/test/plugins/plugin_add_dynamically.html
rename from browser/base/content/test/general/plugin_alternate_content.html
rename to browser/base/content/test/plugins/plugin_alternate_content.html
rename from browser/base/content/test/general/plugin_big.html
rename to browser/base/content/test/plugins/plugin_big.html
rename from browser/base/content/test/general/plugin_both.html
rename to browser/base/content/test/plugins/plugin_both.html
rename from browser/base/content/test/general/plugin_both2.html
rename to browser/base/content/test/plugins/plugin_both2.html
rename from browser/base/content/test/general/plugin_bug744745.html
rename to browser/base/content/test/plugins/plugin_bug744745.html
rename from browser/base/content/test/general/plugin_bug749455.html
rename to browser/base/content/test/plugins/plugin_bug749455.html
rename from browser/base/content/test/general/plugin_bug787619.html
rename to browser/base/content/test/plugins/plugin_bug787619.html
rename from browser/base/content/test/general/plugin_bug797677.html
rename to browser/base/content/test/plugins/plugin_bug797677.html
rename from browser/base/content/test/general/plugin_bug820497.html
rename to browser/base/content/test/plugins/plugin_bug820497.html
rename from browser/base/content/test/general/plugin_clickToPlayAllow.html
rename to browser/base/content/test/plugins/plugin_clickToPlayAllow.html
rename from browser/base/content/test/general/plugin_clickToPlayDeny.html
rename to browser/base/content/test/plugins/plugin_clickToPlayDeny.html
rename from browser/base/content/test/general/pluginCrashCommentAndURL.html
rename to browser/base/content/test/plugins/plugin_crashCommentAndURL.html
rename from browser/base/content/test/general/plugin_data_url.html
rename to browser/base/content/test/plugins/plugin_data_url.html
rename from browser/base/content/test/general/plugin_hidden_to_visible.html
rename to browser/base/content/test/plugins/plugin_hidden_to_visible.html
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/plugins/plugin_iframe.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+</head>
+<body>
+<iframe id="frame" with="400" height="400" src="plugin_test.html">
+</body>
+</html>
rename from browser/base/content/test/general/plugin_outsideScrollArea.html
rename to browser/base/content/test/plugins/plugin_outsideScrollArea.html
rename from browser/base/content/test/general/plugin_overlayed.html
rename to browser/base/content/test/plugins/plugin_overlayed.html
rename from browser/base/content/test/general/plugin_positioned.html
rename to browser/base/content/test/plugins/plugin_positioned.html
rename from browser/base/content/test/general/plugin_small.html
rename to browser/base/content/test/plugins/plugin_small.html
rename from browser/base/content/test/general/plugin_syncRemoved.html
rename to browser/base/content/test/plugins/plugin_syncRemoved.html
rename from browser/base/content/test/general/plugin_test.html
rename to browser/base/content/test/plugins/plugin_test.html
rename from browser/base/content/test/general/plugin_test2.html
rename to browser/base/content/test/plugins/plugin_test2.html
rename from browser/base/content/test/general/plugin_test3.html
rename to browser/base/content/test/plugins/plugin_test3.html
rename from browser/base/content/test/general/plugin_two_types.html
rename to browser/base/content/test/plugins/plugin_two_types.html
rename from browser/base/content/test/general/plugin_unknown.html
rename to browser/base/content/test/plugins/plugin_unknown.html
--- a/browser/base/content/test/social/head.js
+++ b/browser/base/content/test/social/head.js
@@ -320,17 +320,17 @@ function setAndUpdateBlocklist(aURL, aCa
   Services.prefs.setCharPref("extensions.blocklist.url", aURL);
   updateBlocklist(aCallback);
 }
 
 function resetBlocklist(aCallback) {
   // XXX - this has "forked" from the head.js helpers in our parent directory :(
   // But let's reuse their blockNoPlugins.xml.  Later, we should arrange to
   // use their head.js helpers directly
-  let noBlockedURL = "http://example.com/browser/browser/base/content/test/general/blockNoPlugins.xml";
+  let noBlockedURL = "http://example.com/browser/browser/base/content/test/plugins/blockNoPlugins.xml";
   setAndUpdateBlocklist(noBlockedURL, function() {
     Services.prefs.setCharPref("extensions.blocklist.url", _originalTestBlocklistURL);
     if (aCallback)
       aCallback();
   });
 }
 
 function setManifestPref(name, manifest) {
--- a/browser/base/moz.build
+++ b/browser/base/moz.build
@@ -10,16 +10,17 @@ MOCHITEST_MANIFESTS += [
 
 MOCHITEST_CHROME_MANIFESTS += [
     'content/test/chrome/chrome.ini',
 ]
 
 BROWSER_CHROME_MANIFESTS += [
     'content/test/general/browser.ini',
     'content/test/newtab/browser.ini',
+    'content/test/plugins/browser.ini',
     'content/test/social/browser.ini',
 ]
 
 DEFINES['MOZ_APP_VERSION'] = CONFIG['MOZ_APP_VERSION']
 DEFINES['APP_LICENSE_BLOCK'] = '%s/content/overrides/app-license.html' % SRCDIR
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('windows', 'gtk2', 'gtk3', 'cocoa'):
     DEFINES['HAVE_SHELL_SERVICE'] = 1
--- a/browser/branding/aurora/pref/firefox-branding.js
+++ b/browser/branding/aurora/pref/firefox-branding.js
@@ -23,11 +23,12 @@ pref("app.update.url.details", "https://
 
 // The number of days a binary is permitted to be old
 // without checking for an update.  This assumes that
 // app.update.checkInstallTime is true.
 pref("app.update.checkInstallTime.days", 2);
 
 // Search codes belong only in builds with official branding
 pref("browser.search.param.yahoo-fr", "");
+pref("browser.search.param.yahoo-fr-metro", "");
 pref("browser.search.param.yahoo-fr-cjkt", ""); // now unused
 pref("browser.search.param.yahoo-fr-ja", "");
 pref("browser.search.param.yahoo-f-CN", "");
--- a/browser/branding/nightly/pref/firefox-branding.js
+++ b/browser/branding/nightly/pref/firefox-branding.js
@@ -20,11 +20,12 @@ pref("app.update.url.details", "https://
 
 // The number of days a binary is permitted to be old
 // without checking for an update.  This assumes that
 // app.update.checkInstallTime is true.
 pref("app.update.checkInstallTime.days", 2);
 
 // Search codes belong only in builds with official branding
 pref("browser.search.param.yahoo-fr", "");
+pref("browser.search.param.yahoo-fr-metro", "");
 pref("browser.search.param.yahoo-fr-cjkt", ""); // now unused
 pref("browser.search.param.yahoo-fr-ja", "");
 pref("browser.search.param.yahoo-f-CN", "");
--- a/browser/branding/official/pref/firefox-branding.js
+++ b/browser/branding/official/pref/firefox-branding.js
@@ -19,11 +19,13 @@ pref("app.update.url.manual", "https://w
 pref("app.update.url.details", "https://www.mozilla.org/%LOCALE%/firefox/notes");
 
 // The number of days a binary is permitted to be old
 // without checking for an update.  This assumes that
 // app.update.checkInstallTime is true.
 pref("app.update.checkInstallTime.days", 63);
 
 pref("browser.search.param.ms-pc", "MOZI");
+pref("browser.search.param.ms-pc-metro", "MOZW");
 pref("browser.search.param.yahoo-fr", "moz35");
+pref("browser.search.param.yahoo-fr-metro", "mozilla_metro_search");
 pref("browser.search.param.yahoo-fr-cjkt", "moz35"); // now unused
 pref("browser.search.param.yahoo-fr-ja", "mozff");
--- a/browser/branding/unofficial/pref/firefox-branding.js
+++ b/browser/branding/unofficial/pref/firefox-branding.js
@@ -20,11 +20,12 @@ pref("app.update.url.details", "https://
 
 // The number of days a binary is permitted to be old
 // without checking for an update.  This assumes that
 // app.update.checkInstallTime is true.
 pref("app.update.checkInstallTime.days", 2);
 
 // Search codes belong only in builds with official branding
 pref("browser.search.param.yahoo-fr", "");
+pref("browser.search.param.yahoo-fr-metro", "");
 pref("browser.search.param.yahoo-fr-cjkt", ""); // now unused
 pref("browser.search.param.yahoo-fr-ja", "");
 pref("browser.search.param.yahoo-f-CN", "");
--- a/browser/devtools/debugger/test/browser_dbg_chrome-debugging.js
+++ b/browser/devtools/debugger/test/browser_dbg_chrome-debugging.js
@@ -7,16 +7,22 @@
 
 const TAB_URL = EXAMPLE_URL + "doc_inline-debugger-statement.html";
 
 let gClient, gThreadClient;
 let gAttached = promise.defer();
 let gNewGlobal = promise.defer()
 let gNewChromeSource = promise.defer()
 
+let { DevToolsLoader } = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
+let loader = new DevToolsLoader();
+loader.invisibleToDebugger = true;
+loader.main("devtools/server/main");
+let DebuggerServer = loader.DebuggerServer;
+
 function test() {
   if (!DebuggerServer.initialized) {
     DebuggerServer.init(() => true);
     DebuggerServer.addBrowserActors();
   }
 
   let transport = DebuggerServer.connectPipe();
   gClient = new DebuggerClient(transport);
@@ -84,9 +90,12 @@ function resumeAndCloseConnection() {
 
 registerCleanupFunction(function() {
   removeTab(gBrowser.selectedTab);
   gClient = null;
   gThreadClient = null;
   gAttached = null;
   gNewGlobal = null;
   gNewChromeSource = null;
+
+  loader = null;
+  DebuggerServer = null;
 });
--- a/browser/locales/en-US/searchplugins/bingmetrofx.xml
+++ b/browser/locales/en-US/searchplugins/bingmetrofx.xml
@@ -5,18 +5,18 @@
 <SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
     <ShortName>Bing</ShortName>
     <Description>Bing. Search by Microsoft.</Description>
     <InputEncoding>UTF-8</InputEncoding>
     <Image width="16" height="16">data:image/x-icon;base64,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</Image>
     <Image width="74" height="74">data:image/png;base64,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</Image>
     <Url type="application/x-suggestions+json" template="http://api.bing.com/osjson.aspx">
         <Param name="query" value="{searchTerms}"/>
-        <Param name="form" value="MOZW"/>
+        <Param name="form" value="OSDJAS"/>
         <Param name="language" value="{moz:locale}"/>
     </Url>
     <Url type="text/html" method="GET" template="http://www.bing.com/search">
         <Param name="q" value="{searchTerms}"/>
-        <MozParam name="pc" condition="pref" pref="ms-pc"/>
-        <Param name="form" value="MOZW"/>
+        <MozParam name="pc" condition="pref" pref="ms-pc-metro"/>
+        <Param name="form" value="MOZWSB"/>
     </Url>
     <SearchForm>http://www.bing.com/search</SearchForm>
 </SearchPlugin>
--- a/browser/locales/en-US/searchplugins/googlemetrofx.xml
+++ b/browser/locales/en-US/searchplugins/googlemetrofx.xml
@@ -2,17 +2,17 @@
    - 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/. -->
 
 <SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
 <ShortName>Google</ShortName>
 <Description>Google Search</Description>
 <InputEncoding>UTF-8</InputEncoding>
 <Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAB9AQAAJgAAACAgAAAAAAAA8gIAAKMBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAFESURBVDjLpZNJSwNBEIXnt4lE4kHxovgT9BDwJHqPy0HEEOJBiAuCRg+KUdC4QS4KrpC4gCBGE3NQ48JsnZ6eZ3UOM6gjaePhQU93v6+qq2q0pqgeJj2S8EdJT1hr0OxBtKCD5iEd8QxDYpvhvOBAuMDKURX9C9aPu4GA1GEVkzvMg10UBfYveWAWgYAP00V01fa+R9M2bA51wJvhIn3qR+ybt3D3JNQBE5sMjCIOLFpoHzOwdsLRO22qA6R6kiZiWwxUvy/PUQZIhYZ1vFM9cvcOOsYNdcBgysISdSJBnZjJMlR0Fw8vAp0xoz5gao/h+NZBy4i/10XGwrPA+hmvDyhVRG2Avu/LwcrkFADZa16L1h330w1RNgc3DiJzCpPYRm1bpveXX11clQR28xwblHpk1vq1iP/5mcoS0CoXDZiL0vsJ+dzfl+3T/VYAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAK5SURBVFjDxVfrSxRRFJ9/Jta/oyWjF5XQm6D6EkHRgygIIgjUTcueVgqVWSRRkppEUQYWWB8ye1iGWilWlo/Ude489s7M6Zw7D9dlt53dmd29cFiWvXvO77x+51xpaaUsoSxBaUWZQ4ECy5xji2xKZDyCMlMEw6lCNiOSgwZKJK1SkcKeSealfP64t0mBjl4Ow39MkDUL0p2RSROOtqhZdeUEYM1pBl39XCg/fEeFtWcY7G9W4csvUxjlBkCsQ4Nt9QyWVfvT6RsAKXw3aoDGATZeYIt+W1kjw7cJG0RctWDTRebbKd8A6h5pwsDb70ba3w/eUr3wt/cmwgfw6Yft4TNMQaY7o1P2ncm4FT4ANQH/jQBJ2xv7kqIXEADDql8eS3+n8bku7oxNm+EDIM/dU92upb3T/NJGeaNbDx/AsbsLRUY5Xn92caWXY5d8RV6gWllxSg4fAEnTC90DQW13BLlgXR2D3dcUeDVkwOthA1bXspxILWcm3HdThcfvufB26LcJpkOEAz9NKI/lzqpSEC7feol5EWnpSeSlIxCALUkApmULdjUqxQVAQnl3D/X/yQda4QBEq2TYc12By091MQ17Bg3R88nHKlQbVmHvj89awNBLYrwT9zXY2aBAxTkGFdiSxP/Jp6FLDw+AS7GfsdJTJ2EqSO5khD43nGfBARy/ZxOQgZHe7GPM1jzUvChUtmnBAXQPcKGMJp3fdFGq6NByEhiAO4b/YptFfQJwNyQ/bZkVQGcf90Ja25ndIyrKBOa/f8wIpwi3X1G8UcxNu7ozUS7tiH0jBswwS3RIaF1w6LYKU/ML2+8sGnjygQswtKrVIy/Qd9qQP6LnO64q4fPAKpxyZIymHo1jWk6p1ag2BsdNwQMHcC+M5kHFJX+YlPxpVlbCx2mZ5DzPI04k4kUwHHdskU3pH76iftG8yWlkAAAAAElFTkSuQmCC</Image>
-<Image width="74" height="74">data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEoAAABKCAIAAACTslUmAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw%2FeHBhY2tldCBiZWdpbj0i77u%2FIiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8%2BIDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoTWFjaW50b3NoKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDpBN0E5NEYwRUYzMDQxMUUyQjUzMEMyNEUyNjY3NEQyNyIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDpBN0E5NEYwRkYzMDQxMUUyQjUzMEMyNEUyNjY3NEQyNyI%2BIDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOkE3QTk0RjBDRjMwNDExRTJCNTMwQzI0RTI2Njc0RDI3IiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOkE3QTk0RjBERjMwNDExRTJCNTMwQzI0RTI2Njc0RDI3Ii8%2BIDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY%2BIDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8%2BTc4b7gAAA3xJREFUeNrs2WtIU1EcAPBz7r17XKdrEVNpc4qGsqz5IFOhUMikB2JIEvQUoi%2BRHzT6sIiiIrOIiIK%2B9PhSSZAVEfUlUb9VYhphqDOdZpqv%2BWxzj3t2OjclyUcQeefuOOfDOGyw7Xf%2F5%2FzP%2F38v3FQ6AUJ3MCCkB%2BVRHuVRHuVRHuVRHuVRHuVRHuVRHuVRnix5eLn%2FGA4qHlxuHgwSHpZyceEV58Fg3ntcYH4m0cTszFClJTAxaxgt%2F8cVsfWja888zTZBimsnOS9MBcuL1WYjc%2BWp5%2B4rZIpmy4tUqXGsTwBnHk232AXHOEZ%2BeR4MLAMqj%2FH5aYrS265PHYLTjVu7hRO3nG19SMEBa7EaISCdTXLe9s2K7ESuqVMYnZxLEh4fqHziIRNdGDyQp5Txsb4nS%2Fz3w5PzE%2BDnLqFjAJFJnkXOPLOBJa967SIZ4m2bmEu0vPyLMkssy7Hz3xwYE0M6OOGXMa%2FZLoYogodbUxTzPuKVYkhfNPhkzHtY652ZlBWqIzRzS5RjwLYU7kMXqq7zSpu612Zapfv2%2FhG%2FC%2BGsRI4EMNPM2YfwDzc2RDKn9vFOD7DemfZIGzwAA%2FDwOSmWK8xWJJsYPwZmI8tCsmjR8ZtOAYVEUdbeI1ztETehXgdfX4ggk%2Fc2IQC2QLezv4%2B%2FomxlTBQTaryRcVzbIoYxUgsfnNRsWZBO5bc4IQTxBsYSz5n0bJQOxuln86dGDa8f5W%2B8hFVvvHLl5aYrSgvUqzXg%2BTtvQ7vQO4QmXZis0ZIdykM5KgItK1B7faC6XiqhhJmztEh1OFfVZEfWe67RBWUnkVcc5EnfQDqj3eemxqawnPZeZjJHbCQ9nr6%2FiI2M%2Bibf2appMiFCyzpOZqllV4aYNuzDyDGxZFhqGn1fHXimLZQZL0rH%2FOromL%2FfThidEkvqjm9IZjxbv3%2BmFcrLWDL7a8PheiPb%2BEXoHfTLjFdV63GJHTk4v5%2Ffm6tc2BCRg%2BHiEX5yGl967JZlzbkhgbtcwkevEpenYwrXtQid3xEpqdVKmGRg81O5tn5UUeXuG%2FbLkkcGkeSmczkbFclGVhcOOQjGXXhgzP%2BxW6hpRq1dgqT3gAPUMfxflQpXdu%2FhIL46wX4THq44bzaGcJlNQfYADC%2FrhgueB2AgtPce5VEe5VEe5VEe5VEe5VEe5VEe5VEe5VHeP4yfAgwAufYl8QJfZAAAAAAASUVORK5CYII%3D</Image>
+<Image width="74" height="74">data:image/png;base64,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</Image>
 <Url type="application/x-suggestions+json" method="GET" template="https://www.google.com/complete/search?client=metrofirefox&amp;q={searchTerms}"/>
 <Url type="text/html" method="GET" template="https://www.google.com/search">
   <Param name="q" value="{searchTerms}"/>
   <Param name="ie" value="utf-8"/>
   <Param name="oe" value="utf-8"/>
   <Param name="client" value="metrofirefox"/>
 </Url>
 <SearchForm>https://www.google.com/</SearchForm>
--- a/browser/locales/en-US/searchplugins/wikipediametrofx.xml
+++ b/browser/locales/en-US/searchplugins/wikipediametrofx.xml
@@ -2,17 +2,17 @@
    - 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/. -->
 
 <SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
 <ShortName>Wikipedia (en)</ShortName>
 <Description>Wikipedia, the free encyclopedia</Description>
 <InputEncoding>UTF-8</InputEncoding>
 <Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image>
-<Image width="74" height="74">data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEoAAABKCAIAAACTslUmAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw%2FeHBhY2tldCBiZWdpbj0i77u%2FIiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8%2BIDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoTWFjaW50b3NoKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDpFOUFERjZERUY0MkExMUUyQjUzMEMyNEUyNjY3NEQyNyIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDpFOUFERjZERkY0MkExMUUyQjUzMEMyNEUyNjY3NEQyNyI%2BIDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOkU5QURGNkRDRjQyQTExRTJCNTMwQzI0RTI2Njc0RDI3IiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOkU5QURGNkRERjQyQTExRTJCNTMwQzI0RTI2Njc0RDI3Ii8%2BIDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY%2BIDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8%2B0WY7JQAAAuJJREFUeNrs2j1IamEYB3BTTLAQ%2BqKhgkgJbSilhqAGlyYzUiRqKSmCcKwlnFqkIXERggSjkGgMpxoikNAlcwpSCJIoKroJFZWCt3P%2FdOAgd%2Fa9F%2BP%2FDHJ8zgf8fN7zPs9gnSRJqp8batWPDvLII4888sgjjzzyyCOPPPLII4888sgjjzzyyCOPvP%2FK29zcHBkZsdlsQ0NDDofj8PBQTprN5sHBwdHR0YODg3K5vLGxgWt6e3tdLtev71hYWOjv7%2B%2Fr6xseHsb1VfZJVYrX19ejoyOdTodn7u%2FvF4tFJF9eXpaXl5Fxu90fHx%2FIvL29gWGxWG5ubn5%2FR6FQALirqyubzeKsVNVQVfdxXq8XmJWVla%2BvLznz%2BPjY3d3d1NR0dnaGr%2Bl0uqOj4%2BTkRLnl%2Bvq6s7Nze3tbEhBV5iUSifr6egCurq6UZCgUgnlpaQnHs7OzY2NjlbcEg0H4Ufwa4CEmJiaACQQCSub%2B%2Fh6rsbGxcXd312QyJZNJ5RRW78DAwPr6uiQmqs%2FDG4gCGo3Gp6cnJRkOh2HW6%2FV%2Bv19Zt4h4PN7T04P1WTO89%2Fd3u90OTCQSUZKgooBIHh8fV17sdDp9Pp8kLFQiHhqLxSCxWq2VO6HH45F3HSWTyWSwqWCzqTEeuhlaGTBwyhkY5N2%2Fra3t4uJCTs7Pz09OTkoiQ8jU0tLSMjMzg4O9vb3Pz08cRKPRqamp1dVVrNKdnR1kbm9vT09P5%2BbmxI4tgn62h4cH1Eqj0aRSqVwuB3A%2Bn0cPbG5ubm1tfX5%2B3trawnxTKpWEVk%2BztrYm4ldDG8A4gjaI6uEToxk6fkNDAzZJFA0qtAeUDsKarB7i8vKyvb1dq9UaDIbz83M5CRW%2BqtVqDKLwS4JDJfTpi4uLyrwiB5oemgGSGFYk8SGWh6KNj4%2Fj3atMYuCcnp6%2Bu7v7B7w6%2FmWOPPLII4888sgjjzzyyCOPPPLII4888sgjjzzyyCPv7%2FgjwAC5b9U654qBRwAAAABJRU5ErkJggg%3D%3D</Image>
+<Image width="74" height="74">data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEoAAABKCAIAAACTslUmAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA3NpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDIxIDc5LjE1NDkxMSwgMjAxMy8xMC8yOS0xMTo0NzoxNiAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDo5ZWJkNTlmMy02ZDIzLTRjZWUtOWQyOS01OWY4ODY2OTRmNzMiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NTA2MTE5RkU5QjQwMTFFM0IwODREMENBREVCMTMxOUIiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NTA2MTE5RkQ5QjQwMTFFM0IwODREMENBREVCMTMxOUIiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIChNYWNpbnRvc2gpIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6MGIwYjJiY2EtNDlhOS00ZTNmLThiMzAtYTViMGFjZTQ3OTVjIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjllYmQ1OWYzLTZkMjMtNGNlZS05ZDI5LTU5Zjg4NjY5NGY3MyIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PpbYde4AAATqSURBVHja7JpZKG1fHMeveYhMIXPodAxRElFmXlAyTw+eSBGivBiSPFCmPDhekJDiAZEiUaIQh8wiccpM5lm43+6u9d+dc/a5HMf/urf1e1p7re9e+/ux9t6/39qH0tvb249/N5R//NNB8SgexaN4FI/iUTyKR/EoHsWjeBSP4lE8ikfxKN47Q/X9Uk9Pz+fnZx6PZ2VlZWBgoKmp+fj4eHNzc3d3d3V1tb6+fnZ2trCw0NfXV1hYaGdn5+zsbGRkBBnOury8PDk52djY2NvbGxoagj4uLs7W1tbBwQFT6erqYqr9/f3Nzc2dnZ3+/v6Hh4fY2Fh7e3s+n49JtLW1b29vce7i4qKSktL09PR7Tb+9O3A9gHHNo6KiEhAQAJcjIyMeHh5SNUD18fERiUQrKytoSAqA4efnt7u7yyUwMzNLTEx8v+cP4DGxvLwcGBgodtXMzEwxGVYyJCSErcnIyBDTYFXZmo6ODjEB/lj+/v7MqIaGxuDg4EfdfhiPCdxUxJaamtrT05OkBub09PSIrKWlRVLT3t7OjHZ1dUm9EBEMDAzI4VNOPKFQ+N/bSVl5bW1NqkwgEBAZ7lhJQXp6OoZSUlK4LlRRUQFBaGiofD7lxEOw76usrCwumaWlJZGNjo6yhy4uLlR+xfX1NdfpTk5OOHF+fv7/xhsbGyO+8WDgFSpV1tTUxLWAzNJVVlZyXWJychICd3d3uU3Kjyf2BFZVVUnVvLy8GBsbE9nExATTjzSAQ0NDQxnz456U+6lTAB57ZSwsLLhk1dXVRIbXPdMZExODw7a2Nq6zGH4TE5PPOPwUHt6NSMrEemdnp1TZ/f09+xUK3+hBA2ldxuT5+fnQ1NfX/zE8REFBAfHt5ubGJSstLSWyhISE+Ph4NIaHh7n0SImoAVRVVVG+/Em8w8NDdu5GuSRVhioMdtlKX19fGdM2NzdDk5eX90l7n8VjijViOioqikuWm5vLruBQo8qY08bGBrKDg4M/jzczM8NeFtTEUmXHx8eob0ihg+qZa8KpqSlowsPDP+9NAXgIdg2dk5PDJSsuLiaysLAw2QUDNh/fBa+7u5u9LeBK8bW1tex1XlpaktRgu4AhV1dXhRhTDB7C1NSU+AaGpABbPuzr2HgRERGSsuzsbAxhy/e98MrLy4lvbAslBWlpaRhCNkOlQpSrq6tsDXYeKND19fUV5UpheOfn5+rq6sR3T08Pe/To6Aidjo6OaCclJXG9aRsbG9FZU1Pz7fAQqampXNVzdHQ0yYpzc3PsW3RjY4PIzM3N0YNi6DviIZWxfc/OzjL9W1tbOAwICCBKtNlFDNM5Pj4udVP/XfAQ5NsBAumeDbO9vU1k2DdIpkrm48rnU/kX4g0ODop9pzo9PUUjOTlZTOnl5UVkhYWFuCHRCA4OVqwfBeMh7O3tie+ysrLIyEg0kBXEZKiniQyPHMDQEAqF3x2voaFB7DtaSUmJVKWLiwtb5u3trXAzisfDXk5HR4eYRpZ7fX39ba2D6O3t/QvwENjIENOtra0ylDwej5FZW1t/hZMvwROJRIxpPp8vWwl4RllXV/fX4CGCgoJgemRk5PcOfsXd3d1X2FD9op9mioqKUIIxkLJDIBBgy6+lpfUVNpTe6L+KUzyKR/EoHsWjeBSP4lE8ikfxKB7Fo3gUj+JRvHfFTwEGAAgMbrUkfQalAAAAAElFTkSuQmCC</Image>
 <Url type="application/x-suggestions+json" method="GET" template="http://en.wikipedia.org/w/api.php">
   <Param name="action" value="opensearch"/>
   <Param name="search" value="{searchTerms}"/>
 </Url>
 <Url type="text/html" method="GET" template="http://en.wikipedia.org/wiki/Special:Search">
   <Param name="search" value="{searchTerms}"/>
   <Param name="sourceid" value="Mozilla-search"/>
 </Url>
--- a/browser/locales/en-US/searchplugins/yahoometrofx.xml
+++ b/browser/locales/en-US/searchplugins/yahoometrofx.xml
@@ -8,12 +8,12 @@
 <InputEncoding>UTF-8</InputEncoding>
 <Image width="16" height="16">data:image/x-icon;base64,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</Image>
 <Image width="74" height="74">data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEoAAABKCAIAAACTslUmAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA2xpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDE0IDc5LjE1MTQ4MSwgMjAxMy8wMy8xMy0xMjowOToxNSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDpGMkQ1NjY1OTQzMjA2ODExOEFCM0NBQTM2NzFDMUYwRiIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDoyNTI5NTE2NzcwQ0IxMUUzQUZGRUQxNzZFRDEwMkU1NiIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDoyNTI5NTE2NjcwQ0IxMUUzQUZGRUQxNzZFRDEwMkU1NiIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M2IChNYWNpbnRvc2gpIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6NDY2MGVjYzAtNDBiNy00NzFlLTg0NTgtOTQzNTNmOWM4YzYyIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjkzMUIyODkyMTQ5QjExRTM5QkRGOUUwM0ZBM0MwMDNBIi8+IDwvcmRmOkRl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</Image>
 <Url type="application/x-suggestions+json" method="GET"
      template="http://ff.search.yahoo.com/gossip?output=fxjson&amp;command={searchTerms}" />
 <Url type="text/html" method="GET" template="http://search.yahoo.com/search">
   <Param name="p" value="{searchTerms}"/>
   <Param name="ei" value="UTF-8"/>
-  <MozParam name="fr" condition="pref" pref="yahoo-fr" />
+  <MozParam name="fr" condition="pref" pref="yahoo-fr-metro" />
 </Url>
 <SearchForm>http://search.yahoo.com/</SearchForm>
 </SearchPlugin>
--- a/build/autoconf/icu.m4
+++ b/build/autoconf/icu.m4
@@ -117,18 +117,16 @@ AC_SUBST(DBG_SUFFIX)
 AC_SUBST(ENABLE_INTL_API)
 AC_SUBST(ICU_LIB_NAMES)
 AC_SUBST(MOZ_ICU_LIBS)
 
 if test -n "$ENABLE_INTL_API" -a -z "$MOZ_NATIVE_ICU"; then
     dnl We build ICU as a static library for non-shared js builds and as a shared library for shared js builds.
     if test -z "$MOZ_SHARED_ICU"; then
         AC_DEFINE(U_STATIC_IMPLEMENTATION)
-    else
-        AC_DEFINE(U_COMBINED_IMPLEMENTATION)
     fi
     dnl Source files that use ICU should have control over which parts of the ICU
     dnl namespace they want to use.
     AC_DEFINE(U_USING_ICU_NAMESPACE,0)
 fi
 
 
 ])
--- a/build/automationutils.py
+++ b/build/automationutils.py
@@ -451,18 +451,18 @@ def environment(xrePath, env=None, crash
 
   if crashreporter and not debugger:
     env['MOZ_CRASHREPORTER_NO_REPORT'] = '1'
     env['MOZ_CRASHREPORTER'] = '1'
   else:
     env['MOZ_CRASHREPORTER_DISABLE'] = '1'
 
   # Set WebRTC logging in case it is not set yet
-  env.setdefault('NSPR_LOG_MODULES', 'signaling:5,mtransport:3')
-  env.setdefault('R_LOG_LEVEL', '5')
+  env.setdefault('NSPR_LOG_MODULES', 'signaling:5,mtransport:5,datachannel:5')
+  env.setdefault('R_LOG_LEVEL', '6')
   env.setdefault('R_LOG_DESTINATION', 'stderr')
   env.setdefault('R_LOG_VERBOSE', '1')
 
   # ASan specific environment stuff
   asan = bool(mozinfo.info.get("asan"))
   if asan and (mozinfo.isLinux or mozinfo.isMac):
     try:
       # Symbolizer support
--- a/build/unix/elfhack/Makefile.in
+++ b/build/unix/elfhack/Makefile.in
@@ -44,10 +44,8 @@ dummy: dummy.$(OBJ_SUFFIX)
 libs:: dummy
 	# Will either crash or return exit code 1 if elfhack is broken
 	LD_PRELOAD=$(CURDIR)/test-array$(DLL_SUFFIX) $(CURDIR)/dummy
 	LD_PRELOAD=$(CURDIR)/test-ctors$(DLL_SUFFIX) $(CURDIR)/dummy
 
 GARBAGE += dummy
 endif
 endif
-
-test.$(OBJ_SUFFIX): CFLAGS := -O0
--- a/config/rules.mk
+++ b/config/rules.mk
@@ -967,17 +967,17 @@ endef
 
 $(HOST_CMMOBJS):
 	$(REPORT_BUILD)
 	$(ELOG) $(HOST_CXX) $(HOST_OUTOPTION)$@ -c $(HOST_CXXFLAGS) $(HOST_CMMFLAGS) $(INCLUDES) $(NSPR_CFLAGS) $(_VPATH_SRCS)
 
 $(COBJS):
 	$(REPORT_BUILD)
 	@$(MAKE_DEPS_AUTO_CC)
-	$(ELOG) $(CC) $(OUTOPTION)$@ -c $(COMPILE_CFLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS)
+	$(ELOG) $(CC) $(OUTOPTION)$@ -c $(COMPILE_CFLAGS) $($(notdir $<)_FLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS)
 
 # DEFINES and ACDEFINES are needed here to enable conditional compilation of Q_OBJECTs:
 # 'moc' only knows about #defines it gets on the command line (-D...), not in
 # included headers like mozilla-config.h
 $(filter moc_%.cpp,$(CPPSRCS)): moc_%.cpp: %.h
 	$(REPORT_BUILD)
 	$(ELOG) $(MOC) $(DEFINES) $(ACDEFINES) $< $(OUTOPTION)$@
 
@@ -989,65 +989,65 @@ endef
 	$(REPORT_BUILD)
 	$(ELOG) $(RCC) -name $* $< $(OUTOPTION)$@
 
 ifdef ASFILES
 # The AS_DASH_C_FLAG is needed cause not all assemblers (Solaris) accept
 # a '-c' flag.
 $(ASOBJS):
 	$(REPORT_BUILD)
-	$(AS) $(ASOUTOPTION)$@ $(ASFLAGS) $(AS_DASH_C_FLAG) $(_VPATH_SRCS)
+	$(AS) $(ASOUTOPTION)$@ $(ASFLAGS) $($(notdir $<)_FLAGS) $(AS_DASH_C_FLAG) $(_VPATH_SRCS)
 endif
 
 $(SOBJS):
 	$(REPORT_BUILD)
-	$(AS) -o $@ $(ASFLAGS) $(LOCAL_INCLUDES) $(TARGET_LOCAL_INCLUDES) -c $<
+	$(AS) -o $@ $(ASFLAGS) $($(notdir $<)_FLAGS) $(LOCAL_INCLUDES) $(TARGET_LOCAL_INCLUDES) -c $<
 
 $(CPPOBJS):
 	$(REPORT_BUILD)
 	@$(MAKE_DEPS_AUTO_CXX)
-	$(ELOG) $(CCC) $(OUTOPTION)$@ -c $(COMPILE_CXXFLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS)
+	$(ELOG) $(CCC) $(OUTOPTION)$@ -c $(COMPILE_CXXFLAGS) $($(notdir $<)_FLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS)
 
 $(CMMOBJS):
 	$(REPORT_BUILD)
 	@$(MAKE_DEPS_AUTO_CXX)
-	$(ELOG) $(CCC) -o $@ -c $(COMPILE_CXXFLAGS) $(COMPILE_CMMFLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS)
+	$(ELOG) $(CCC) -o $@ -c $(COMPILE_CXXFLAGS) $(COMPILE_CMMFLAGS) $($(notdir $<)_FLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS)
 
 $(CMOBJS):
 	$(REPORT_BUILD)
 	@$(MAKE_DEPS_AUTO_CC)
-	$(ELOG) $(CC) -o $@ -c $(COMPILE_CFLAGS) $(COMPILE_CMFLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS)
+	$(ELOG) $(CC) -o $@ -c $(COMPILE_CFLAGS) $(COMPILE_CMFLAGS) $($(notdir $<)_FLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS)
 
 $(filter %.s,$(CPPSRCS:%.cpp=%.s)): %.s: %.cpp $(call mkdir_deps,$(MDDEPDIR))
 	$(REPORT_BUILD)
-	$(CCC) -S $(COMPILE_CXXFLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS)
+	$(CCC) -S $(COMPILE_CXXFLAGS) $($(notdir $<)_FLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS)
 
 $(filter %.s,$(CPPSRCS:%.cc=%.s)): %.s: %.cc $(call mkdir_deps,$(MDDEPDIR))
 	$(REPORT_BUILD)
-	$(CCC) -S $(COMPILE_CXXFLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS)
+	$(CCC) -S $(COMPILE_CXXFLAGS) $($(notdir $<)_FLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS)
 
 $(filter %.s,$(CSRCS:%.c=%.s)): %.s: %.c $(call mkdir_deps,$(MDDEPDIR))
 	$(REPORT_BUILD)
-	$(CC) -S $(COMPILE_CFLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS)
+	$(CC) -S $(COMPILE_CFLAGS) $($(notdir $<)_FLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS)
 
 $(filter %.i,$(CPPSRCS:%.cpp=%.i)): %.i: %.cpp $(call mkdir_deps,$(MDDEPDIR))
 	$(REPORT_BUILD)
-	$(CCC) -C $(PREPROCESS_OPTION)$@ $(COMPILE_CXXFLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS)
+	$(CCC) -C $(PREPROCESS_OPTION)$@ $(COMPILE_CXXFLAGS) $($(notdir $<)_FLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS)
 
 $(filter %.i,$(CPPSRCS:%.cc=%.i)): %.i: %.cc $(call mkdir_deps,$(MDDEPDIR))
 	$(REPORT_BUILD)
-	$(CCC) -C $(PREPROCESS_OPTION)$@ $(COMPILE_CXXFLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS)
+	$(CCC) -C $(PREPROCESS_OPTION)$@ $(COMPILE_CXXFLAGS) $($(notdir $<)_FLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS)
 
 $(filter %.i,$(CSRCS:%.c=%.i)): %.i: %.c $(call mkdir_deps,$(MDDEPDIR))
 	$(REPORT_BUILD)
-	$(CC) -C $(PREPROCESS_OPTION)$@ $(COMPILE_CFLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS)
+	$(CC) -C $(PREPROCESS_OPTION)$@ $(COMPILE_CFLAGS) $($(notdir $<)_FLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS)
 
 $(filter %.i,$(CMMSRCS:%.mm=%.i)): %.i: %.mm $(call mkdir_deps,$(MDDEPDIR))
 	$(REPORT_BUILD)
-	$(CCC) -C $(PREPROCESS_OPTION)$@ $(COMPILE_CXXFLAGS) $(COMPILE_CMMFLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS)
+	$(CCC) -C $(PREPROCESS_OPTION)$@ $(COMPILE_CXXFLAGS) $(COMPILE_CMMFLAGS) $($(notdir $<)_FLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS)
 
 $(RESFILE): %.res: %.rc
 	$(REPORT_BUILD)
 	@echo Creating Resource file: $@
 ifdef GNU_CC
 	$(RC) $(RCFLAGS) $(filter-out -U%,$(DEFINES)) $(INCLUDES:-I%=--include-dir %) $(OUTOPTION)$@ $(_VPATH_SRCS)
 else
 	$(RC) $(RCFLAGS) -r $(DEFINES) $(INCLUDES) $(OUTOPTION)$@ $(_VPATH_SRCS)
--- a/configure.in
+++ b/configure.in
@@ -947,17 +947,17 @@ IMPORT_LIB_SUFFIX=
 TARGET_MD_ARCH=unix
 DIRENT_INO=d_ino
 MOZ_USER_DIR=".mozilla"
 
 MOZ_JPEG_CFLAGS=
 MOZ_JPEG_LIBS='$(call EXPAND_LIBNAME_PATH,mozjpeg,$(DEPTH)/media/libjpeg)'
 MOZ_BZ2_CFLAGS=
 MOZ_BZ2_LIBS='$(call EXPAND_LIBNAME_PATH,bz2,$(DEPTH)/modules/libbz2/src)'
-MOZ_PNG_CFLAGS=
+MOZ_PNG_CFLAGS="-I$_objdir/dist/include" # needed for freetype compilation
 MOZ_PNG_LIBS='$(call EXPAND_LIBNAME_PATH,mozpng,$(DEPTH)/media/libpng)'
 
 MOZ_JS_STATIC_LIBS='$(call EXPAND_LIBNAME_PATH,js_static,$(LIBXUL_DIST)/lib)'
 MOZ_JS_SHARED_LIBS='$(call EXPAND_LIBNAME_PATH,mozjs,$(LIBXUL_DIST)/lib)'
 MOZ_FIX_LINK_PATHS='-Wl,-rpath-link,$(LIBXUL_DIST)/bin -Wl,-rpath-link,$(prefix)/lib'
 XPCOM_FROZEN_LDOPTS='$(call EXPAND_LIBNAME_PATH,xul mozalloc,$(LIBXUL_DIST)/bin)'
 LIBXUL_LIBS='$(XPCOM_FROZEN_LDOPTS)'
 XPCOM_GLUE_LDOPTS='$(LIBXUL_DIST)/lib/$(LIB_PREFIX)xpcomglue_s.$(LIB_SUFFIX) $(XPCOM_FROZEN_LDOPTS)'
@@ -8670,29 +8670,17 @@ AC_SUBST(MOZ_ENABLE_SZIP)
 AC_SUBST(MOZ_SZIP_FLAGS)
 
 if test "$MOZ_DEBUG"; then
     MOZ_EM_DEBUG=1
 fi
 AC_SUBST(MOZ_EM_DEBUG)
 
 if test -n "$COMPILE_ENVIRONMENT"; then
-AC_MSG_CHECKING([for posix_fallocate])
-AC_TRY_LINK([#define _XOPEN_SOURCE 600
-  #include <fcntl.h>],
-                 [posix_fallocate(0, 0, 0);],
-                 [ac_cv___posix_fallocate=true],
-                 [ac_cv___posix_fallocate=false])
-
-if test "$ac_cv___posix_fallocate" = true ; then
-  AC_DEFINE(HAVE_POSIX_FALLOCATE)
-  AC_MSG_RESULT(yes)
-else
-  AC_MSG_RESULT(no)
-fi
+AC_CHECK_FUNCS(posix_fadvise posix_fallocate)
 
 dnl Check for missing components
 if test "$MOZ_X11"; then
     if test "$WITHOUT_X11"; then
         AC_MSG_ERROR([--without-x specified and MOZ_X11 still defined])
     fi
     dnl ====================================================
     dnl = Check if X headers exist
@@ -8922,18 +8910,20 @@ fi
 
 # Run freetype configure script
 
 if test "$MOZ_TREE_FREETYPE"; then
    export CFLAGS="$CFLAGS $MOZ_DEBUG_FLAGS -std=c99"
    export CPPFLAGS="$CPPFLAGS $MOZ_DEBUG_FLAGS"
    export CXXFLAGS="$CXXFLAGS $MOZ_DEBUG_FLAGS"
    export LDFLAGS="$LDFLAGS $MOZ_DEBUG_LDFLAGS"
+   export LIBPNG_CFLAGS="$MOZ_PNG_CFLAGS"
+   export LIBPNG_LDFLAGS="$MOZ_PNG_LIBS"
    export CONFIG_FILES="unix-cc.mk:unix-cc.in unix-def.mk:unix-def.in freetype-config freetype2.pc:freetype2.in"
-   ac_configure_args="$ac_configure_args --host=$target --disable-shared --with-pic=yes --without-png"
+   ac_configure_args="$ac_configure_args --host=$target --disable-shared --with-pic=yes"
 
    if ! test -e modules; then
      mkdir modules
    fi
 
    AC_OUTPUT_SUBDIRS(modules/freetype2)
 fi
 
deleted file mode 100644
--- a/content/base/src/Makefile.in
+++ /dev/null
@@ -1,18 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-include $(topsrcdir)/config/rules.mk
-
-# gcc requires -msse2 for this file since it uses SSE2 intrinsics.  (See bug
-# 585538 comment 12.)
-ifneq (,$(INTEL_ARCHITECTURE))
-ifdef GNU_CC
-nsTextFragmentSSE2.$(OBJ_SUFFIX): CXXFLAGS+=-msse2
-endif
-
-ifdef SOLARIS_SUNPRO_CXX
-nsTextFragmentSSE2.$(OBJ_SUFFIX): CXXFLAGS+=-xarch=sse2 -xO4
-endif
-endif
--- a/content/base/src/moz.build
+++ b/content/base/src/moz.build
@@ -45,19 +45,23 @@ if CONFIG['MOZ_WEBRTC']:
     ]
     LOCAL_INCLUDES += [
         '/netwerk/sctp/datachannel',
     ]
 
 # Are we targeting x86-32 or x86-64?  If so, we want to include SSE2 code for
 # nsTextFragment.cpp
 if CONFIG['INTEL_ARCHITECTURE']:
-    SOURCES += [
-        'nsTextFragmentSSE2.cpp',
-    ]
+    SOURCES += ['nsTextFragmentSSE2.cpp']
+    if CONFIG['GNU_CC']:
+        # gcc requires -msse2 for this file since it uses SSE2 intrinsics.  (See bug
+        # 585538 comment 12.)
+        SOURCES['nsTextFragmentSSE2.cpp'].flags += ['-msse2']
+    if CONFIG['SOLARIS_SUNPRO_CXX']:
+        SOURCES['nsTextFragmentSSE2.cpp'].flags += ['-xarch=sse2', '-xO4']
 
 EXPORTS.mozilla.dom += [
     'Attr.h',
     'Comment.h',
     'DocumentFragment.h',
     'DocumentType.h',
     'DOMImplementation.h',
     'DOMParser.h',
--- a/content/canvas/test/webgl/conformance/extensions/00_test_list.txt
+++ b/content/canvas/test/webgl/conformance/extensions/00_test_list.txt
@@ -1,9 +1,9 @@
 oes-standard-derivatives.html
 ext-texture-filter-anisotropic.html
 oes-texture-float.html
 oes-vertex-array-object.html
 webgl-debug-renderer-info.html
 webgl-debug-shaders.html
---min-version 1.0.2 webgl-compressed-texture-s3tc.html
+webgl-compressed-texture-s3tc.html
 --min-version 1.0.2 webgl-depth-texture.html
 ext-sRGB.html
--- a/content/canvas/test/webgl/non-conf-tests/mochitest.ini
+++ b/content/canvas/test/webgl/non-conf-tests/mochitest.ini
@@ -6,8 +6,9 @@ support-files =
 [test_depth_readpixels.html]
 [test_highp_fs.html]
 [test_no_arr_points.html]
 [test_privileged_exts.html]
 [test_webgl_available.html]
 [test_webgl_conformance.html]
 [test_webgl_request_context.html]
 [test_webgl_request_mismatch.html]
+[test_webgl2_not_exposed.html]
new file mode 100644
--- /dev/null
+++ b/content/canvas/test/webgl/non-conf-tests/test_webgl2_not_exposed.html
@@ -0,0 +1,22 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<title>WebGL test: WebGL2RenderingContext not exposed</title>
+<script src="/MochiKit/MochiKit.js"></script>
+<script src="/tests/SimpleTest/SimpleTest.js"></script>
+<link rel="stylesheet" href="/tests/SimpleTest/test.css">
+</head>
+<body>
+<script>
+
+var exposed = false;
+try {
+  null instanceof WebGL2RenderingContext;
+  exposed = true;
+} catch (e) {}
+
+ok(!exposed, 'WebGL2RenderingContext should not be exposed.');
+
+</script>
+</body>
+</html>
--- a/content/html/content/src/HTMLMediaElement.cpp
+++ b/content/html/content/src/HTMLMediaElement.cpp
@@ -612,17 +612,17 @@ void HTMLMediaElement::AbortExistingLoad
     mAudioStream = nullptr;
   }
 
   mLoadingSrc = nullptr;
 
   if (mNetworkState == nsIDOMHTMLMediaElement::NETWORK_LOADING ||
       mNetworkState == nsIDOMHTMLMediaElement::NETWORK_IDLE)
   {
-    DispatchEvent(NS_LITERAL_STRING("abort"));
+    DispatchAsyncEvent(NS_LITERAL_STRING("abort"));
   }
 
   mError = nullptr;
   mLoadedFirstFrame = false;
   mAutoplaying = true;
   mIsLoadingFromSourceChildren = false;
   mSuspendedAfterFirstFrame = false;
   mAllowSuspendAfterFirstFrame = true;
@@ -643,17 +643,17 @@ void HTMLMediaElement::AbortExistingLoad
 
     if (fireTimeUpdate) {
       // Since we destroyed the decoder above, the current playback position
       // will now be reported as 0. The playback position was non-zero when
       // we destroyed the decoder, so fire a timeupdate event so that the
       // change will be reflected in the controls.
       FireTimeUpdate(false);
     }
-    DispatchEvent(NS_LITERAL_STRING("emptied"));
+    DispatchAsyncEvent(NS_LITERAL_STRING("emptied"));
   }
 
   // We may have changed mPaused, mAutoplaying, mNetworkState and other
   // things which can affect AddRemoveSelfReference
   AddRemoveSelfReference();
 
   mIsRunningSelectResource = false;
 }
--- a/content/media/Makefile.in
+++ b/content/media/Makefile.in
@@ -1,10 +1,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/.
 
 include $(topsrcdir)/config/rules.mk
 
 CFLAGS   += $(GSTREAMER_CFLAGS)
 CXXFLAGS += $(GSTREAMER_CFLAGS)
-
-AudioNodeEngineNEON.$(OBJ_SUFFIX): CXXFLAGS += -mfpu=neon
--- a/content/media/moz.build
+++ b/content/media/moz.build
@@ -159,19 +159,18 @@ UNIFIED_SOURCES += [
 SOURCES += [
     'DecoderTraits.cpp',
     'Latency.cpp',
 ]
 
 FAIL_ON_WARNINGS = True
 
 if CONFIG['CPU_ARCH'] == 'arm' and CONFIG['BUILD_ARM_NEON']:
-    SOURCES += [
-        'AudioNodeEngineNEON.cpp',
-    ]
+    SOURCES += ['AudioNodeEngineNEON.cpp']
+    SOURCES['AudioNodeEngineNEON.cpp'].flags += ['-mfpu=neon']
 
 MSVC_ENABLE_PGO = True
 
 include('/ipc/chromium/chromium-config.mozbuild')
 
 FINAL_LIBRARY = 'gklayout'
 LOCAL_INCLUDES += [
     '/content/base/src',
--- a/content/media/test/mochitest.ini
+++ b/content/media/test/mochitest.ini
@@ -351,16 +351,17 @@ support-files =
 [test_playback_errors.html]
 [test_seekable1.html]
 [test_preload_actions.html]
 [test_preload_attribute.html]
 [test_progress.html]
 [test_reactivate.html]
 [test_readyState.html]
 [test_referer.html]
+[test_reset_events_async.html]
 [test_replay_metadata.html]
 [test_seek2.html]
 [test_seek_out_of_range.html]
 [test_seekable2.html]
 [test_seekable3.html]
 [test_source.html]
 [test_source_write.html]
 [test_source_null.html]
--- a/content/media/test/test_bug654550.html
+++ b/content/media/test/test_bug654550.html
@@ -57,16 +57,19 @@ https://bugzilla.mozilla.org/show_bug.cg
     removeNodeAndSource(v);
     manager.finished(v.token);
   }
 
   function startTest(test, token) {
     var v = document.createElement('video');
     v.token = token;
     v.src = test.name;
+    // playback may reach the end before pref is changed for the duration is short
+    // set 'loop' to true to keep playing so that we won't miss 'timeupdate' events
+    v.loop = true;
     manager.started(token);
     SpecialPowers.pushPrefEnv({"set": [["media.video_stats.enabled", true]]},
       function() {
         v.play();
         v.addEventListener("timeupdate", ontimeupdate_statsEnabled);
     });
   }
 
new file mode 100644
--- /dev/null
+++ b/content/media/test/test_reset_events_async.html
@@ -0,0 +1,58 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=975270
+-->
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug </title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+  <script type="application/javascript" src="manifest.js"></script>
+  <script type="application/javascript">
+
+  /** Test for Bug 975270 **/
+  // Test that 'emptied' and 'abort' events are fired asynchronously when re-starting
+  // media load.
+  SimpleTest.waitForExplicitFinish();
+
+  var a = document.createElement("audio");
+  a._abort = 0;
+  a._emptied = 0;
+  a.preload = "metadata"; // On B2G we default to preload:none.
+  
+  is(a.networkState, HTMLMediaElement.NETWORK_EMPTY, "Shouldn't be loading");
+  
+  a.addEventListener("abort", function(e) { a._abort++; });
+  a.addEventListener("emptied", function(e) { a._emptied++; });
+  a.addEventListener("loadedmetadata",
+    function(e) {
+      is(a._abort, 0, "Should not have received 'abort' before 'loadedmetadata");
+      is(a._emptied, 0, "Should not have received 'emptied' before 'loadedmetadata");
+
+      a.addEventListener("loadstart",
+        function(e) {
+          is(a._abort, 1, "Should have received 'abort' before 'loadstart");
+          is(a._emptied, 1, "Should  have received 'emptied' before 'loadstart");
+          SimpleTest.finish();
+        });
+
+      a.src = "";
+      is(a._abort, 0, "Should not have received 'abort' during setting a.src=''");
+      is(a._emptied, 0, "Should not have received 'emptied' during setting a.src=''");
+    });
+  
+  a.src = getPlayableAudio(gSmallTests).name;
+    
+  </script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=">Mozilla Bug </a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+</pre>
+</body>
+</html>
--- a/dom/base/CompositionStringSynthesizer.cpp
+++ b/dom/base/CompositionStringSynthesizer.cpp
@@ -18,28 +18,29 @@ namespace dom {
 
 NS_IMPL_ISUPPORTS1(CompositionStringSynthesizer,
                    nsICompositionStringSynthesizer)
 
 CompositionStringSynthesizer::CompositionStringSynthesizer(
                                 nsPIDOMWindow* aWindow)
 {
   mWindow = do_GetWeakReference(aWindow);
+  mClauses = new TextRangeArray();
   ClearInternal();
 }
 
 CompositionStringSynthesizer::~CompositionStringSynthesizer()
 {
 }
 
 void
 CompositionStringSynthesizer::ClearInternal()
 {
   mString.Truncate();
-  mClauses.Clear();
+  mClauses->Clear();
   mCaret.mRangeType = 0;
 }
 
 nsIWidget*
 CompositionStringSynthesizer::GetWidget()
 {
   nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
   if (!window) {
@@ -79,20 +80,20 @@ CompositionStringSynthesizer::AppendClau
 
   switch (aAttribute) {
     case ATTR_RAWINPUT:
     case ATTR_SELECTEDRAWTEXT:
     case ATTR_CONVERTEDTEXT:
     case ATTR_SELECTEDCONVERTEDTEXT: {
       TextRange textRange;
       textRange.mStartOffset =
-        mClauses.IsEmpty() ? 0 : mClauses[mClauses.Length() - 1].mEndOffset;
+        mClauses->IsEmpty() ? 0 : mClauses->LastElement().mEndOffset;
       textRange.mEndOffset = textRange.mStartOffset + aLength;
       textRange.mRangeType = aAttribute;
-      mClauses.AppendElement(textRange);
+      mClauses->AppendElement(textRange);
       return NS_OK;
     }
     default:
       return NS_ERROR_INVALID_ARG;
   }
 }
 
 NS_IMETHODIMP
@@ -113,37 +114,38 @@ CompositionStringSynthesizer::DispatchEv
   NS_ENSURE_ARG_POINTER(aDefaultPrevented);
   nsCOMPtr<nsIWidget> widget = GetWidget();
   NS_ENSURE_TRUE(widget && !widget->Destroyed(), NS_ERROR_NOT_AVAILABLE);
 
   if (!nsContentUtils::IsCallerChrome()) {
     return NS_ERROR_DOM_SECURITY_ERR;
   }
 
-  if (!mClauses.IsEmpty() &&
-      mClauses[mClauses.Length()-1].mEndOffset != mString.Length()) {
+  if (!mClauses->IsEmpty() &&
+      mClauses->LastElement().mEndOffset != mString.Length()) {
     NS_WARNING("Sum of length of the all clauses must be same as the string "
                "length");
     ClearInternal();
     return NS_ERROR_ILLEGAL_VALUE;
   }
   if (mCaret.mRangeType == NS_TEXTRANGE_CARETPOSITION) {
     if (mCaret.mEndOffset > mString.Length()) {
       NS_WARNING("Caret position is out of the composition string");
       ClearInternal();
       return NS_ERROR_ILLEGAL_VALUE;
     }
-    mClauses.AppendElement(mCaret);
+    mClauses->AppendElement(mCaret);
   }
 
   WidgetTextEvent textEvent(true, NS_TEXT_TEXT, widget);
   textEvent.time = PR_IntervalNow();
   textEvent.theText = mString;
-  textEvent.rangeCount = mClauses.Length();
-  textEvent.rangeArray = mClauses.Elements();
+  if (!mClauses->IsEmpty()) {
+    textEvent.mRanges = mClauses;
+  }
 
   // XXX How should we set false for this on b2g?
   textEvent.mFlags.mIsSynthesizedForTests = true;
 
   nsEventStatus status = nsEventStatus_eIgnore;
   nsresult rv = widget->DispatchEvent(&textEvent, status);
   *aDefaultPrevented = (status == nsEventStatus_eConsumeNoDefault);
 
--- a/dom/base/CompositionStringSynthesizer.h
+++ b/dom/base/CompositionStringSynthesizer.h
@@ -3,17 +3,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/. */
 
 #ifndef mozilla_dom_compositionstringsynthesizer_h__
 #define mozilla_dom_compositionstringsynthesizer_h__
 
 #include "nsICompositionStringSynthesizer.h"
 #include "nsString.h"
-#include "nsTArray.h"
 #include "nsWeakReference.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/TextRange.h"
 
 class nsIWidget;
 class nsPIDOMWindow;
 
 namespace mozilla {
@@ -27,17 +26,17 @@ public:
   ~CompositionStringSynthesizer();
 
   NS_DECL_ISUPPORTS
   NS_DECL_NSICOMPOSITIONSTRINGSYNTHESIZER
 
 private:
   nsWeakPtr mWindow; // refers an instance of nsPIDOMWindow
   nsString mString;
-  nsAutoTArray<TextRange, 10> mClauses;
+  nsRefPtr<TextRangeArray> mClauses;
   TextRange mCaret;
 
   nsIWidget* GetWidget();
   void ClearInternal();
 };
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/bindings/BindingUtils.cpp
+++ b/dom/bindings/BindingUtils.cpp
@@ -963,30 +963,29 @@ XrayResolveAttribute(JSContext* cx, JS::
       for ( ; attributeIds[i] != JSID_VOID; ++i) {
         if (id == attributeIds[i]) {
           const JSPropertySpec& attrSpec = attributeSpecs[i];
           // Because of centralization, we need to make sure we fault in the
           // JitInfos as well. At present, until the JSAPI changes, the easiest
           // way to do this is wrap them up as functions ourselves.
           desc.setAttributes(attrSpec.flags & ~JSPROP_NATIVE_ACCESSORS);
           // They all have getters, so we can just make it.
-          JS::Rooted<JSObject*> global(cx, JS_GetGlobalForObject(cx, wrapper));
           JS::Rooted<JSFunction*> fun(cx,
                                       JS_NewFunctionById(cx, (JSNative)attrSpec.getter.propertyOp.op,
-                                                         0, 0, global, id));
+                                                         0, 0, wrapper, id));
           if (!fun)
             return false;
           SET_JITINFO(fun, attrSpec.getter.propertyOp.info);
           JSObject *funobj = JS_GetFunctionObject(fun);
           desc.setGetterObject(funobj);
           desc.attributesRef() |= JSPROP_GETTER;
           if (attrSpec.setter.propertyOp.op) {
             // We have a setter! Make it.
             fun = JS_NewFunctionById(cx, (JSNative)attrSpec.setter.propertyOp.op, 1, 0,
-                                     global, id);
+                                     wrapper, id);
             if (!fun)
               return false;
             SET_JITINFO(fun, attrSpec.setter.propertyOp.info);
             funobj = JS_GetFunctionObject(fun);
             desc.setSetterObject(funobj);
             desc.attributesRef() |= JSPROP_SETTER;
           } else {
             desc.setSetter(nullptr);
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -1172,21 +1172,28 @@ class CGClassConstructor(CGAbstractStati
     def definition_body(self):
         return self.generate_code()
 
     def generate_code(self):
         preamble = """
   JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
   JS::Rooted<JSObject*> obj(cx, &args.callee());
 """
+        # [ChromeOnly] interfaces may only be constructed by chrome.
+        # Additionally, we want to throw if a non-chrome caller does a bareword invocation of a
+        # constructor without |new|. We don't enforce this for chrome to avoid the addon compat
+        # fallout of making that change. See bug 916644.
         if isChromeOnly(self._ctor):
-            preamble += """  if (!nsContentUtils::ThreadsafeIsCallerChrome()) {
+            mayInvokeCtor = "nsContentUtils::ThreadsafeIsCallerChrome()"
+        else:
+            mayInvokeCtor = "(args.isConstructing() || nsContentUtils::ThreadsafeIsCallerChrome())"
+        preamble += """  if (!%s) {
     return ThrowingConstructor(cx, argc, vp);
   }
-"""
+""" % mayInvokeCtor
         name = self._ctor.identifier.name
         nativeName = MakeNativeName(self.descriptor.binaryNames.get(name, name))
         callGenerator = CGMethodCall(nativeName, True, self.descriptor,
                                      self._ctor, isConstructor=True)
         return preamble + callGenerator.define();
 
 # Encapsulate the constructor in a helper method to share genConstructorBody with CGJSImplMethod.
 class CGConstructNavigatorObjectHelper(CGAbstractStaticMethod):
--- a/dom/browser-element/BrowserElementChildPreload.js
+++ b/dom/browser-element/BrowserElementChildPreload.js
@@ -68,33 +68,31 @@ function NS_ERROR_GET_CODE(err) {
 }
 
 let SEC_ERROR_BASE = Ci.nsINSSErrorsService.NSS_SEC_ERROR_BASE;
 let SEC_ERROR_UNKNOWN_ISSUER = (SEC_ERROR_BASE + 13);
 let SEC_ERROR_CA_CERT_INVALID =   (SEC_ERROR_BASE + 36);
 let SEC_ERROR_UNTRUSTED_ISSUER = (SEC_ERROR_BASE + 20);
 let SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE = (SEC_ERROR_BASE + 30);
 let SEC_ERROR_UNTRUSTED_CERT = (SEC_ERROR_BASE + 21);
-let SEC_ERROR_INADEQUATE_KEY_USAGE = (SEC_ERROR_BASE + 90);
 let SEC_ERROR_EXPIRED_CERTIFICATE = (SEC_ERROR_BASE + 11);
 let SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED = (SEC_ERROR_BASE + 176);
 
 let SSL_ERROR_BASE = Ci.nsINSSErrorsService.NSS_SSL_ERROR_BASE;
 let SSL_ERROR_BAD_CERT_DOMAIN = (SSL_ERROR_BASE + 12);
 
 function getErrorClass(errorCode) {
   let NSPRCode = -1 * NS_ERROR_GET_CODE(errorCode);
 
   switch (NSPRCode) {
     case SEC_ERROR_UNKNOWN_ISSUER:
     case SEC_ERROR_CA_CERT_INVALID:
     case SEC_ERROR_UNTRUSTED_ISSUER:
     case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE:
     case SEC_ERROR_UNTRUSTED_CERT:
-    case SEC_ERROR_INADEQUATE_KEY_USAGE:
     case SSL_ERROR_BAD_CERT_DOMAIN:
     case SEC_ERROR_EXPIRED_CERTIFICATE:
     case SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED:
       return Ci.nsINSSErrorsService.ERROR_CLASS_BAD_CERT;
     default:
       return Ci.nsINSSErrorsService.ERROR_CLASS_SSL_PROTOCOL;
   }
 
--- a/dom/datastore/DataStore.jsm
+++ b/dom/datastore/DataStore.jsm
@@ -74,16 +74,17 @@ this.DataStore.prototype = {
 
   _window: null,
   _name: null,
   _owner: null,
   _readOnly: null,
   _revisionId: null,
   _exposedObject: null,
   _cursor: null,
+  _shuttingdown: false,
 
   init: function(aWindow, aName, aOwner, aReadOnly) {
     debug("DataStore init");
 
     this._window = aWindow;
     this._name = aName;
     this._owner = aOwner;
     this._readOnly = aReadOnly;
@@ -91,16 +92,18 @@ this.DataStore.prototype = {
     this._db = new DataStoreDB();
     this._db.init(aOwner, aName);
 
     let self = this;
     Services.obs.addObserver(function(aSubject, aTopic, aData) {
       let wId = aSubject.QueryInterface(Ci.nsISupportsPRUint64).data;
       if (wId == self._innerWindowID) {
         cpmm.removeMessageListener("DataStore:Changed:Return:OK", self);
+        cpmm.sendAsyncMessage("DataStore:UnregisterForMessages");
+        self._shuttingdown = true;
         self._db.close();
       }
     }, "inner-window-destroyed", false);
 
     let util = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
                       .getInterface(Ci.nsIDOMWindowUtils);
     this._innerWindowID = util.currentInnerWindowID;
 
@@ -315,16 +318,21 @@ this.DataStore.prototype = {
         aMessage.data.store != this._name) {
       return;
     }
 
     let self = this;
 
     this.retrieveRevisionId(
       function() {
+        // If the window has been destroyed we don't emit the events.
+        if (self._shuttingdown) {
+          return;
+        }
+
         // If we have an active cursor we don't emit events.
         if (self._cursor) {
           return;
         }
 
         let event = new self._window.DataStoreChangeEvent('change',
                                                           aMessage.data.message);
         self.__DOM_IMPL__.dispatchEvent(event);
--- a/dom/datastore/DataStoreChangeNotifier.jsm
+++ b/dom/datastore/DataStoreChangeNotifier.jsm
@@ -20,16 +20,17 @@ Cu.import("resource://gre/modules/Servic
 
 XPCOMUtils.defineLazyServiceGetter(this, "ppmm",
                                    "@mozilla.org/parentprocessmessagemanager;1",
                                    "nsIMessageBroadcaster");
 
 this.DataStoreChangeNotifier = {
   children: [],
   messages: [ "DataStore:Changed", "DataStore:RegisterForMessages",
+              "DataStore:UnregisterForMessages",
               "child-process-shutdown" ],
 
   init: function() {
     debug("init");
 
     this.messages.forEach((function(msgName) {
       ppmm.addMessageListener(msgName, this);
     }).bind(this));
@@ -89,16 +90,17 @@ this.DataStoreChangeNotifier = {
         }
 
         this.children.push({ mm: aMessage.target,
                              store: aMessage.data.store,
                              owner: aMessage.data.owner });
         break;
 
       case "child-process-shutdown":
+      case "DataStore:UnregisterForMessages":
         debug("Unregister");
 
         for (let i = 0; i < this.children.length;) {
           if (this.children[i].mm == aMessage.target) {
             debug("Unregister index: " + i);
             this.children.splice(i, 1);
           } else {
             ++i;
--- a/dom/events/TextComposition.cpp
+++ b/dom/events/TextComposition.cpp
@@ -108,27 +108,18 @@ TextComposition::NotityUpdateComposition
       // Unknown offset
       NS_WARNING("Cannot get start offset of IME composition");
       mCompositionStartOffset = 0;
     }
     mCompositionTargetOffset = mCompositionStartOffset;
   } else if (aEvent->eventStructType != NS_TEXT_EVENT) {
     return;
   } else {
-    WidgetTextEvent* textEvent = aEvent->AsTextEvent();
-    mCompositionTargetOffset = mCompositionStartOffset;
-
-    for (uint32_t i = 0; i < textEvent->rangeCount; i++) {
-      TextRange& range = textEvent->rangeArray[i];
-      if (range.mRangeType == NS_TEXTRANGE_SELECTEDRAWTEXT ||
-          range.mRangeType == NS_TEXTRANGE_SELECTEDCONVERTEDTEXT) {
-        mCompositionTargetOffset += range.mStartOffset;
-        break;
-      }
-    }
+    mCompositionTargetOffset =
+      mCompositionStartOffset + aEvent->AsTextEvent()->TargetClauseOffset();
   }
 
   NotifyIME(NOTIFY_IME_OF_COMPOSITION_UPDATE);
 }
 
 void
 TextComposition::DispatchCompositionEventRunnable(uint32_t aEventMessage,
                                                   const nsAString& aData)
@@ -156,16 +147,17 @@ TextComposition::NotifyIME(IMEMessage aM
   NS_ENSURE_TRUE(mPresContext, NS_ERROR_NOT_AVAILABLE);
   return nsIMEStateManager::NotifyIME(aMessage, mPresContext);
 }
 
 void
 TextComposition::EditorWillHandleTextEvent(const WidgetTextEvent* aTextEvent)
 {
   mIsComposing = aTextEvent->IsComposing();
+  mRanges = aTextEvent->mRanges;
   mIsEditorHandlingEvent = true;
 
   MOZ_ASSERT(mLastData == aTextEvent->theText,
     "The text of a text event must be same as previous data attribute value "
     "of the latest compositionupdate event");
 }
 
 void
--- a/dom/events/TextComposition.h
+++ b/dom/events/TextComposition.h
@@ -11,16 +11,17 @@
 #include "nsINode.h"
 #include "nsIWeakReference.h"
 #include "nsIWidget.h"
 #include "nsTArray.h"
 #include "nsThreadUtils.h"
 #include "nsPresContext.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/EventForwards.h"
+#include "mozilla/TextRange.h"
 
 class nsDispatchingCallback;
 class nsIEditor;
 class nsIMEStateManager;
 
 namespace mozilla {
 
 /**
@@ -52,16 +53,22 @@ public:
   // This value is modified at dispatching compositionupdate.
   const nsString& LastData() const { return mLastData; }
   // The composition string which is already handled by the focused editor.
   // I.e., this value must be same as the composition string on the focused
   // editor.  This value is modified at a call of EditorDidHandleTextEvent().
   // Note that mString and mLastData are different between dispatcing
   // compositionupdate and text event handled by focused editor.
   const nsString& String() const { return mString; }
+  // Returns the clauses and/or caret range of the composition string.
+  // This is modified at a call of EditorWillHandleTextEvent().
+  // This may return null if there is no clauses and caret.
+  // XXX We should return |const TextRangeArray*| here, but it causes compile
+  //     error due to inaccessible Release() method.
+  TextRangeArray* GetRanges() const { return mRanges; }
   // Returns true if the composition is started with synthesized event which
   // came from nsDOMWindowUtils.
   bool IsSynthesizedForTests() const { return mIsSynthesizedForTests; }
 
   bool MatchesNativeContext(nsIWidget* aWidget) const;
 
   /**
    * This is called when nsIMEStateManager stops managing the instance.
@@ -138,16 +145,20 @@ public:
 private:
   // This class holds nsPresContext weak.  This instance shouldn't block
   // destroying it.  When the presContext is being destroyed, it's notified to
   // nsIMEStateManager::OnDestroyPresContext(), and then, it destroy
   // this instance.
   nsPresContext* mPresContext;
   nsCOMPtr<nsINode> mNode;
 
+  // This is the clause and caret range information which is managed by
+  // the focused editor.  This may be null if there is no clauses or caret.
+  nsRefPtr<TextRangeArray> mRanges;
+
   // mNativeContext stores a opaque pointer.  This works as the "ID" for this
   // composition.  Don't access the instance, it may not be available.
   void* mNativeContext;
 
   // mEditorWeak is a weak reference to the focused editor handling composition.
   nsWeakPtr mEditorWeak;
 
   // mLastData stores the data attribute of the latest composition event (except
--- a/dom/events/moz.build
+++ b/dom/events/moz.build
@@ -19,18 +19,16 @@ EXPORTS += [
     'nsDOMEventTargetHelper.h',
     'nsDOMKeyNameList.h',
     'nsEventDispatcher.h',
     'nsEventListenerManager.h',
     'nsEventNameList.h',
     'nsEventStateManager.h',
     'nsEventStates.h',
     'nsIJSEventListener.h',
-    'nsIPrivateTextEvent.h',
-    'nsIPrivateTextRange.h',
     'nsVKList.h',
 ]
 
 EXPORTS.mozilla += [
     'InternalMutationEvent.h',
 ]
 
 EXPORTS.mozilla.dom += [
@@ -84,24 +82,22 @@ UNIFIED_SOURCES += [
     'MouseScrollEvent.cpp',
     'MutationEvent.cpp',
     'NotifyAudioAvailableEvent.cpp',
     'NotifyPaintEvent.cpp',
     'nsAsyncDOMEvent.cpp',
     'nsContentEventHandler.cpp',
     'nsDOMEvent.cpp',
     'nsDOMEventTargetHelper.cpp',
-    'nsDOMTextEvent.cpp',
     'nsEventDispatcher.cpp',
     'nsEventListenerManager.cpp',
     'nsEventListenerService.cpp',
     'nsIMEStateManager.cpp',
     'nsJSEventListener.cpp',
     'nsPaintRequest.cpp',
-    'nsPrivateTextRange.cpp',
     'PointerEvent.cpp',
     'ScrollAreaEvent.cpp',
     'SimpleGestureEvent.cpp',
     'TextComposition.cpp',
     'Touch.cpp',
     'TouchEvent.cpp',
     'TransitionEvent.cpp',
     'UIEvent.cpp',
deleted file mode 100644
--- a/dom/events/nsDOMTextEvent.cpp
+++ /dev/null
@@ -1,86 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=2 sw=2 et tw=78: */
-/* 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/. */
-
-#include "nsDOMTextEvent.h"
-#include "nsPrivateTextRange.h"
-#include "prtime.h"
-#include "mozilla/TextEvents.h"
-
-using namespace mozilla;
-using namespace mozilla::dom;
-
-nsDOMTextEvent::nsDOMTextEvent(mozilla::dom::EventTarget* aOwner,
-                               nsPresContext* aPresContext,
-                               WidgetTextEvent* aEvent)
-  : UIEvent(aOwner, aPresContext,
-            aEvent ? aEvent : new WidgetTextEvent(false, 0, nullptr))
-{
-  NS_ASSERTION(mEvent->eventStructType == NS_TEXT_EVENT, "event type mismatch");
-
-  if (aEvent) {
-    mEventIsInternal = false;
-  }
-  else {
-    mEventIsInternal = true;
-    mEvent->time = PR_Now();
-  }
-
-  //
-  // extract the IME composition string
-  //
-  WidgetTextEvent* te = mEvent->AsTextEvent();
-  mText = te->theText;
-
-  //
-  // build the range list -- ranges need to be DOM-ified since the
-  // IME transaction will hold a ref, the widget representation
-  // isn't persistent
-  //
-  mTextRange = new nsPrivateTextRangeList(te->rangeCount);
-  if (mTextRange) {
-    uint16_t i;
-
-    for(i = 0; i < te->rangeCount; i++) {
-      nsRefPtr<nsPrivateTextRange> tempPrivateTextRange = new
-        nsPrivateTextRange(te->rangeArray[i]);
-
-      if (tempPrivateTextRange) {
-        mTextRange->AppendTextRange(tempPrivateTextRange);
-      }
-    }
-  }
-}
-
-NS_IMPL_ADDREF_INHERITED(nsDOMTextEvent, UIEvent)
-NS_IMPL_RELEASE_INHERITED(nsDOMTextEvent, UIEvent)
-
-NS_INTERFACE_MAP_BEGIN(nsDOMTextEvent)
-  NS_INTERFACE_MAP_ENTRY(nsIPrivateTextEvent)
-NS_INTERFACE_MAP_END_INHERITING(UIEvent)
-
-NS_METHOD nsDOMTextEvent::GetText(nsString& aText)
-{
-  aText = mText;
-  return NS_OK;
-}
-
-NS_METHOD_(already_AddRefed<nsIPrivateTextRangeList>) nsDOMTextEvent::GetInputRange()
-{
-  if (mEvent->message == NS_TEXT_TEXT) {
-    nsRefPtr<nsPrivateTextRangeList> textRange = mTextRange;
-    return textRange.forget();
-  }
-  return nullptr;
-}
-
-nsresult NS_NewDOMTextEvent(nsIDOMEvent** aInstancePtrResult,
-                            mozilla::dom::EventTarget* aOwner,
-                            nsPresContext* aPresContext,
-                            WidgetTextEvent* aEvent)
-{
-  nsDOMTextEvent* it = new nsDOMTextEvent(aOwner, aPresContext, aEvent);
-  return CallQueryInterface(it, aInstancePtrResult);
-}
deleted file mode 100644
--- a/dom/events/nsDOMTextEvent.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef nsDOMTextEvent_h__
-#define nsDOMTextEvent_h__
-
-#include "mozilla/dom/UIEvent.h"
-#include "mozilla/Attributes.h"
-#include "mozilla/EventForwards.h"
-#include "nsIPrivateTextEvent.h"
-#include "nsPrivateTextRange.h"
-
-class nsDOMTextEvent : public mozilla::dom::UIEvent,
-                       public nsIPrivateTextEvent
-{
-  typedef mozilla::dom::UIEvent UIEvent;
-
-public:
-  nsDOMTextEvent(mozilla::dom::EventTarget* aOwner,
-                 nsPresContext* aPresContext,
-                 mozilla::WidgetTextEvent* aEvent);
-
-  NS_DECL_ISUPPORTS_INHERITED
-
-  // Forward to base class
-  NS_FORWARD_TO_UIEVENT
-
-  // nsIPrivateTextEvent interface
-  NS_IMETHOD GetText(nsString& aText) MOZ_OVERRIDE;
-  NS_IMETHOD_(already_AddRefed<nsIPrivateTextRangeList>) GetInputRange() MOZ_OVERRIDE;
-  
-protected:
-  nsString mText;
-  nsRefPtr<nsPrivateTextRangeList> mTextRange;
-};
-
-#endif // nsDOMTextEvent_h__
--- a/dom/events/nsEventDispatcher.cpp
+++ b/dom/events/nsEventDispatcher.cpp
@@ -703,18 +703,18 @@ nsEventDispatcher::CreateEvent(mozilla::
                                        aEvent->AsMouseScrollEvent());
     case NS_WHEEL_EVENT:
       return NS_NewDOMWheelEvent(aDOMEvent, aOwner, aPresContext,
                                  aEvent->AsWheelEvent());
     case NS_DRAG_EVENT:
       return NS_NewDOMDragEvent(aDOMEvent, aOwner, aPresContext,
                                 aEvent->AsDragEvent());
     case NS_TEXT_EVENT:
-      return NS_NewDOMTextEvent(aDOMEvent, aOwner, aPresContext,
-                                aEvent->AsTextEvent());
+      return NS_NewDOMUIEvent(aDOMEvent, aOwner, aPresContext,
+                              aEvent->AsTextEvent());
     case NS_CLIPBOARD_EVENT:
       return NS_NewDOMClipboardEvent(aDOMEvent, aOwner, aPresContext,
                                      aEvent->AsClipboardEvent());
     case NS_SVGZOOM_EVENT:
       return NS_NewDOMSVGZoomEvent(aDOMEvent, aOwner, aPresContext,
                                    aEvent->AsGUIEvent());
     case NS_SMIL_TIME_EVENT:
       return NS_NewDOMTimeEvent(aDOMEvent, aOwner, aPresContext, aEvent);
@@ -759,17 +759,17 @@ nsEventDispatcher::CreateEvent(mozilla::
     return NS_NewDOMKeyboardEvent(aDOMEvent, aOwner, aPresContext, nullptr);
   if (aEventType.LowerCaseEqualsLiteral("compositionevent"))
     return NS_NewDOMCompositionEvent(aDOMEvent, aOwner, aPresContext, nullptr);
   if (aEventType.LowerCaseEqualsLiteral("mutationevent") ||
         aEventType.LowerCaseEqualsLiteral("mutationevents"))
     return NS_NewDOMMutationEvent(aDOMEvent, aOwner, aPresContext, nullptr);
   if (aEventType.LowerCaseEqualsLiteral("textevent") ||
       aEventType.LowerCaseEqualsLiteral("textevents"))
-    return NS_NewDOMTextEvent(aDOMEvent, aOwner, aPresContext, nullptr);
+    return NS_NewDOMUIEvent(aDOMEvent, aOwner, aPresContext, nullptr);
   if (aEventType.LowerCaseEqualsLiteral("popupblockedevents"))
     return NS_NewDOMPopupBlockedEvent(aDOMEvent, aOwner, aPresContext, nullptr);
   if (aEventType.LowerCaseEqualsLiteral("deviceorientationevent"))
     return NS_NewDOMDeviceOrientationEvent(aDOMEvent, aOwner, aPresContext, nullptr);
   if (aEventType.LowerCaseEqualsLiteral("devicemotionevent"))
     return NS_NewDOMDeviceMotionEvent(aDOMEvent, aOwner, aPresContext, nullptr);
   if (aEventType.LowerCaseEqualsLiteral("uievent") ||
       aEventType.LowerCaseEqualsLiteral("uievents"))
--- a/dom/events/nsEventNameList.h
+++ b/dom/events/nsEventNameList.h
@@ -654,17 +654,17 @@ NON_IDL_EVENT(speakerforcedchange,
               NS_SPEAKERMANAGER_SPEAKERFORCEDCHANGE,
               EventNameType_None,
               NS_EVENT)
 
 // Events that only have on* attributes on XUL elements
 NON_IDL_EVENT(text,
               NS_TEXT_TEXT,
               EventNameType_XUL,
-              NS_EVENT)
+              NS_TEXT_EVENT)
 NON_IDL_EVENT(compositionstart,
               NS_COMPOSITION_START,
               EventNameType_XUL,
               NS_COMPOSITION_EVENT)
 NON_IDL_EVENT(compositionupdate,
               NS_COMPOSITION_UPDATE,
               EventNameType_XUL,
               NS_COMPOSITION_EVENT)
deleted file mode 100644
--- a/dom/events/nsIPrivateTextEvent.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef nsIPrivateTextEvent_h__
-#define nsIPrivateTextEvent_h__
-
-#include "nsISupports.h"
-#include "nsIPrivateTextRange.h"
-
-#define NS_IPRIVATETEXTEVENT_IID \
-{ 0xb6840e02, 0x9e56, 0x49d8, \
-  { 0x84, 0xd, 0x5f, 0xc1, 0xcb, 0x6c, 0xff, 0xb3 } }
-
-class nsIPrivateTextEvent : public nsISupports {
-
-public:
-	NS_DECLARE_STATIC_IID_ACCESSOR(NS_IPRIVATETEXTEVENT_IID)
-
-	NS_IMETHOD GetText(nsString& aText) = 0;
-	NS_IMETHOD_(already_AddRefed<nsIPrivateTextRangeList>) GetInputRange() = 0;
-};
-
-NS_DEFINE_STATIC_IID_ACCESSOR(nsIPrivateTextEvent, NS_IPRIVATETEXTEVENT_IID)
-
-#endif // nsIPrivateTextEvent_h__
-
deleted file mode 100644
--- a/dom/events/nsIPrivateTextRange.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef nsIPrivateTextRange_h__
-#define nsIPrivateTextRange_h__
-
-#include "nsISupports.h"
-#include "nsString.h"
-#include "nsCOMPtr.h"
-#include "mozilla/EventForwards.h"
-
-#define NS_IPRIVATETEXTRANGE_IID \
-{ 0xf795a44d, 0x413a, 0x4c63, \
-  { 0xa6, 0xb0, 0x7a, 0xa3, 0x0c, 0xf5, 0xe9, 0xe0 } }
-
-class nsIPrivateTextRange : public nsISupports {
-public:
-  NS_DECLARE_STATIC_IID_ACCESSOR(NS_IPRIVATETEXTRANGE_IID)
-
-  // Note that the range array may not specify a caret position; in that
-  // case there will be no range of type TEXTRANGE_CARETPOSITION in the array.
-  enum {
-    TEXTRANGE_CARETPOSITION = 1,
-    TEXTRANGE_RAWINPUT = 2,
-    TEXTRANGE_SELECTEDRAWTEXT = 3,
-    TEXTRANGE_CONVERTEDTEXT = 4,
-    TEXTRANGE_SELECTEDCONVERTEDTEXT = 5
-  };
-
-  NS_IMETHOD    GetRangeStart(uint16_t* aRangeStart)=0;
-  NS_IMETHOD    GetRangeEnd(uint16_t* aRangeEnd)=0;
-  NS_IMETHOD    GetRangeType(uint16_t* aRangeType)=0;
-  NS_IMETHOD    GetRangeStyle(mozilla::TextRangeStyle* aTextRangeStyle)=0;
-};
-
-NS_DEFINE_STATIC_IID_ACCESSOR(nsIPrivateTextRange, NS_IPRIVATETEXTRANGE_IID)
-
-#define NS_IPRIVATETEXTRANGELIST_IID \
-{0xb5a04b19, 0xed33, 0x4cd0, \
-{0x82, 0xa8, 0xb7, 0x00, 0x83, 0xef, 0xc4, 0x91}}
-
-class nsIPrivateTextRangeList : public nsISupports {
-public:
-  NS_DECLARE_STATIC_IID_ACCESSOR(NS_IPRIVATETEXTRANGELIST_IID)
-
-  NS_IMETHOD_(uint16_t) GetLength()=0;
-  NS_IMETHOD_(already_AddRefed<nsIPrivateTextRange>) Item(uint16_t aIndex)=0;
-};
-
-NS_DEFINE_STATIC_IID_ACCESSOR(nsIPrivateTextRangeList,
-                              NS_IPRIVATETEXTRANGELIST_IID)
-
-#endif // nsIPrivateTextRange_h__
deleted file mode 100644
--- a/dom/events/nsPrivateTextRange.cpp
+++ /dev/null
@@ -1,67 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "nsPrivateTextRange.h"
-#include "mozilla/TextEvents.h"
-
-using namespace mozilla;
-
-nsPrivateTextRange::nsPrivateTextRange(const TextRange &aTextRange)
-  : mRangeStart(uint16_t(aTextRange.mStartOffset)),
-    mRangeEnd(uint16_t(aTextRange.mEndOffset)),
-    mRangeType(uint16_t(aTextRange.mRangeType)),
-    mRangeStyle(aTextRange.mRangeStyle)
-{
-}
-
-nsPrivateTextRange::~nsPrivateTextRange(void)
-{
-}
-
-NS_IMPL_ISUPPORTS1(nsPrivateTextRange, nsIPrivateTextRange)
-
-NS_METHOD nsPrivateTextRange::GetRangeStart(uint16_t* aRangeStart)
-{
-	*aRangeStart = mRangeStart;
-	return NS_OK;
-}
-
-NS_METHOD nsPrivateTextRange::GetRangeEnd(uint16_t* aRangeEnd)
-{
-	*aRangeEnd = mRangeEnd;
-	return NS_OK;
-}
-
-NS_METHOD nsPrivateTextRange::GetRangeType(uint16_t* aRangeType)
-{
-	*aRangeType = mRangeType;
-	return NS_OK;
-}
-
-NS_METHOD nsPrivateTextRange::GetRangeStyle(TextRangeStyle* aTextRangeStyle)
-{
-	NS_ENSURE_ARG_POINTER(aTextRangeStyle);
-	*aTextRangeStyle = mRangeStyle;
-	return NS_OK;
-}
-
-NS_IMPL_ISUPPORTS1(nsPrivateTextRangeList, nsIPrivateTextRangeList)
-
-void nsPrivateTextRangeList::AppendTextRange(nsRefPtr<nsPrivateTextRange>& aRange)
-{
-	mList.AppendElement(aRange);
-}
-
-NS_METHOD_(uint16_t) nsPrivateTextRangeList::GetLength()
-{
-  return static_cast<uint16_t>(mList.Length());
-}
-
-NS_METHOD_(already_AddRefed<nsIPrivateTextRange>) nsPrivateTextRangeList::Item(uint16_t aIndex)
-{
-  nsRefPtr<nsPrivateTextRange> ret = mList.ElementAt(aIndex);
-  return ret.forget();
-}
-
deleted file mode 100644
--- a/dom/events/nsPrivateTextRange.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef nsPrivateTextRange_h__
-#define nsPrivateTextRange_h__
-
-#include "nsIPrivateTextRange.h"
-#include "nsTArray.h"
-#include "nsAutoPtr.h"
-#include "mozilla/Attributes.h"
-#include "mozilla/TextRange.h"
-
-class nsPrivateTextRange MOZ_FINAL : public nsIPrivateTextRange
-{
-	NS_DECL_ISUPPORTS
-public:
-
-	nsPrivateTextRange(const mozilla::TextRange &aTextRange);
-	virtual ~nsPrivateTextRange(void);
-
-	NS_IMETHOD GetRangeStart(uint16_t* aRangeStart) MOZ_OVERRIDE;
-	NS_IMETHOD GetRangeEnd(uint16_t* aRangeEnd) MOZ_OVERRIDE;
-	NS_IMETHOD GetRangeType(uint16_t* aRangeType) MOZ_OVERRIDE;
-	NS_IMETHOD GetRangeStyle(mozilla::TextRangeStyle* aRangeStyle) MOZ_OVERRIDE;
-
-protected:
-
-	uint16_t	mRangeStart;
-	uint16_t	mRangeEnd;
-	uint16_t	mRangeType;
-	mozilla::TextRangeStyle mRangeStyle;
-};
-
-class nsPrivateTextRangeList MOZ_FINAL : public nsIPrivateTextRangeList
-{
-	NS_DECL_ISUPPORTS
-public:
-	nsPrivateTextRangeList(uint16_t aLength) : mList(aLength) {}
-
-	void          AppendTextRange(nsRefPtr<nsPrivateTextRange>& aRange);
-
-	NS_IMETHOD_(uint16_t)    GetLength() MOZ_OVERRIDE;
-
-	NS_IMETHOD_(already_AddRefed<nsIPrivateTextRange>)    Item(uint16_t aIndex) MOZ_OVERRIDE;
-protected:
-	nsTArray<nsRefPtr<nsPrivateTextRange> > mList;
-};
-
-
-#endif
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -2034,17 +2034,16 @@ TabChild::RecvCompositionEvent(const Wid
   return true;
 }
 
 bool
 TabChild::RecvTextEvent(const WidgetTextEvent& event)
 {
   WidgetTextEvent localEvent(event);
   DispatchWidgetEvent(localEvent);
-  IPC::ParamTraits<WidgetTextEvent>::Free(event);
   return true;
 }
 
 bool
 TabChild::RecvSelectionEvent(const WidgetSelectionEvent& event)
 {
   WidgetSelectionEvent localEvent(event);
   DispatchWidgetEvent(localEvent);
--- a/dom/locales/en-US/chrome/accessibility/AccessFu.properties
+++ b/dom/locales/en-US/chrome/accessibility/AccessFu.properties
@@ -1,12 +1,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/.
 
+# Screen reader started/stopped
+screenReaderStarted = Screen reader started
+screenReaderStopped = Screen reader stopped
+
+# Roles
 menubar        =       menu bar
 scrollbar      =       scroll bar
 grip           =       grip
 alert          =       alert
 menupopup      =       menu popup
 document       =       document
 pane           =       pane
 dialog         =       dialog
--- a/dom/media/tests/mochitest/pc.js
+++ b/dom/media/tests/mochitest/pc.js
@@ -1444,42 +1444,53 @@ PeerConnectionWrapper.prototype = {
         info(self + ": As expected, failed to add an ICE candidate");
         onFailure(err);
     }) ;
   },
 
   /**
    * Returns if the ICE the connection state is "connected".
    *
-   * @returns {boolean} True is the connection state is "connected", otherwise false.
+   * @returns {boolean} True if the connection state is "connected", otherwise false.
    */
   isIceConnected : function PCW_isIceConnected() {
     info("iceConnectionState: " + this.iceConnectionState);
     return this.iceConnectionState === "connected";
   },
 
   /**
    * Returns if the ICE the connection state is "checking".
    *
-   * @returns {boolean} True is the connection state is "checking", otherwise false.
+   * @returns {boolean} True if the connection state is "checking", otherwise false.
    */
   isIceChecking : function PCW_isIceChecking() {
     return this.iceConnectionState === "checking";
   },
 
   /**
    * Returns if the ICE the connection state is "new".
    *
-   * @returns {boolean} True is the connection state is "new", otherwise false.
+   * @returns {boolean} True if the connection state is "new", otherwise false.
    */
   isIceNew : function PCW_isIceNew() {
     return this.iceConnectionState === "new";
   },
 
   /**
+   * Checks if the ICE connection state still waits for a connection to get
+   * established.
+   *
+   * @returns {boolean} True if the connection state is "checking" or "new", 
+   *  otherwise false.
+   */
+  isIceConnectionPending : function PCW_isIceConnectionPending() {
+    return (this.isIceChecking() || this.isIceNew());
+  },
+
+  /**
    * Registers a callback for the ICE connection state change and
    * reports success (=connected) or failure via the callbacks.
    * States "new" and "checking" are ignored.
    *
    * @param {function} onSuccess
    *        Callback if ICE connection status is "connected".
    * @param {function} onFailure
    *        Callback if ICE connection reaches a different state than
@@ -1489,17 +1500,17 @@ PeerConnectionWrapper.prototype = {
     var self = this;
     var mySuccess = onSuccess;
     var myFailure = onFailure;
 
     function iceConnectedChanged () {
       if (self.isIceConnected()) {
         delete self.ice_connection_callbacks["waitForIceConnected"];
         mySuccess();
-      } else if (! (self.isIceChecking() || self.isIceNew())) {
+      } else if (! self.isIceConnectionPending()) {
         delete self.ice_connection_callbacks["waitForIceConnected"];
         myFailure();
       }
     };
 
     self.ice_connection_callbacks["waitForIceConnected"] = (function() {iceConnectedChanged()});
   },
 
--- a/dom/media/tests/mochitest/templates.js
+++ b/dom/media/tests/mochitest/templates.js
@@ -138,52 +138,58 @@ var commandsPeerConnection = [
   ],
   [
     'PC_LOCAL_WAIT_FOR_ICE_CONNECTED',
     function (test) {
       var myTest = test;
       var myPc = myTest.pcLocal;
 
       function onIceConnectedSuccess () {
-        ok(true, "pc_local: ICE switched to connected state");
+        ok(true, "pc_local: ICE switched to 'connected' state");
         myTest.next();
       };
       function onIceConnectedFailed () {
-        ok(false, "pc_local: ICE failed to switch to connected");
+        ok(false, "pc_local: ICE failed to switch to 'connected' state: " + myPc.iceConnectionState());
         myTest.next();
       };
 
       if (myPc.isIceConnected()) {
         ok(true, "pc_local: ICE is in connected state");
         myTest.next();
+      } else if (myPc.isIceConnectionPending()) {
+        myPc.waitForIceConnected(onIceConnectedSuccess, onIceConnectedFailed);
       } else {
-        myPc.waitForIceConnected(onIceConnectedSuccess, onIceConnectedFailed);
+        ok(false, "pc_local: ICE is already in bad state: " + myPc.iceConnectionState());
+        myTest.next();
       }
     }
   ],
   [
     'PC_REMOTE_WAIT_FOR_ICE_CONNECTED',
     function (test) {
       var myTest = test;
       var myPc = myTest.pcRemote;
 
       function onIceConnectedSuccess () {
-        ok(true, "pc_remote: ICE switched to connected state");
+        ok(true, "pc_remote: ICE switched to 'connected' state");
         myTest.next();
       };
       function onIceConnectedFailed () {
-        ok(false, "pc_remote: ICE failed to switch to connected");
+        ok(false, "pc_remote: ICE failed to switch to 'connected' state: " + myPc.iceConnectionState());
         myTest.next();
       };
 
       if (myPc.isIceConnected()) {
         ok(true, "pc_remote: ICE is in connected state");
         myTest.next();
+      } else if (myPc.isIceConnectionPending()) {
+        myPc.waitForIceConnected(onIceConnectedSuccess, onIceConnectedFailed);
       } else {
-        myPc.waitForIceConnected(onIceConnectedSuccess, onIceConnectedFailed);
+        ok(false, "pc_remote: ICE is already in bad state: " + myPc.iceConnectionState());
+        myTest.next();
       }
     }
   ],
   [
     'PC_LOCAL_CHECK_MEDIA_STREAMS',
     function (test) {
       test.pcLocal.checkMediaStreams(test._remote_constraints);
       test.next();
--- a/dom/plugins/base/nsPluginTags.cpp
+++ b/dom/plugins/base/nsPluginTags.cpp
@@ -562,15 +562,15 @@ nsPluginTag::GetBlocklistState()
 }
 
 void
 nsPluginTag::InvalidateBlocklistState()
 {
   mCachedBlocklistStateValid = false;
 }
 
-nsresult
+NS_IMETHODIMP
 nsPluginTag::GetLastModifiedTime(PRTime* aLastModifiedTime)
 {
   MOZ_ASSERT(aLastModifiedTime);
   *aLastModifiedTime = mLastModifiedTime;
   return NS_OK;
 }
--- a/dom/promise/Promise.cpp
+++ b/dom/promise/Promise.cpp
@@ -4,16 +4,17 @@
  * 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/. */
 
 #include "mozilla/dom/Promise.h"
 
 #include "jsfriendapi.h"
 #include "mozilla/dom/OwningNonNull.h"
 #include "mozilla/dom/PromiseBinding.h"
+#include "mozilla/CycleCollectedJSRuntime.h"
 #include "mozilla/Preferences.h"
 #include "PromiseCallback.h"
 #include "PromiseNativeHandler.h"
 #include "nsContentUtils.h"
 #include "WorkerPrivate.h"
 #include "WorkerRunnable.h"
 #include "nsJSPrincipals.h"
 #include "nsJSUtils.h"
@@ -93,38 +94,34 @@ public:
     : mPromise(aPromise)
     , mValue(aValue)
     , mState(aState)
   {
     MOZ_ASSERT(aPromise);
     MOZ_ASSERT(mState != Promise::Pending);
     MOZ_COUNT_CTOR(PromiseResolverMixin);
 
-    JSContext* cx = nsContentUtils::GetDefaultJSContextForThread();
-
     /* It's safe to use unsafeGet() here: the unsafeness comes from the
      * possibility of updating the value of mJSObject without triggering the
      * barriers.  However if the value will always be marked, post barriers
      * unnecessary. */
-    JS_AddNamedValueRootRT(JS_GetRuntime(cx), mValue.unsafeGet(),
+    JS_AddNamedValueRootRT(CycleCollectedJSRuntime::Get()->Runtime(), mValue.unsafeGet(),
                            "PromiseResolverMixin.mValue");
   }
 
   virtual ~PromiseResolverMixin()
   {
     NS_ASSERT_OWNINGTHREAD(PromiseResolverMixin);
     MOZ_COUNT_DTOR(PromiseResolverMixin);
 
-    JSContext* cx = nsContentUtils::GetDefaultJSContextForThread();
-
     /* It's safe to use unsafeGet() here: the unsafeness comes from the
      * possibility of updating the value of mJSObject without triggering the
      * barriers.  However if the value will always be marked, post barriers
      * unnecessary. */
-    JS_RemoveValueRootRT(JS_GetRuntime(cx), mValue.unsafeGet());
+    JS_RemoveValueRootRT(CycleCollectedJSRuntime::Get()->Runtime(), mValue.unsafeGet());
   }
 
 protected:
   void
   RunInternal()
   {
     NS_ASSERT_OWNINGTHREAD(PromiseResolverMixin);
     mPromise->RunResolveTask(
@@ -626,17 +623,17 @@ public:
   {
     mozilla::DropJSObjects(this);
   }
 
   void SetValue(uint32_t index, const JS::Handle<JS::Value> aValue)
   {
     MOZ_ASSERT(mCountdown > 0);
 
-    JSContext* cx = nsContentUtils::GetDefaultJSContextForThread();
+    ThreadsafeAutoSafeJSContext cx;
     JSAutoCompartment ac(cx, mValues);
 
     {
       AutoDontReportUncaught silenceReporting(cx);
       if (!JS_DefineElement(cx, mValues, index, aValue, nullptr, nullptr, JSPROP_ENUMERATE)) {
         MOZ_ASSERT(JS_IsExceptionPending(cx));
         JS::Rooted<JS::Value> exn(cx);
         JS_GetPendingException(cx, &exn);
@@ -850,39 +847,35 @@ Promise::RunTask()
   MOZ_ASSERT(mState != Pending);
 
   nsTArray<nsRefPtr<PromiseCallback>> callbacks;
   callbacks.SwapElements(mState == Resolved ? mResolveCallbacks
                                             : mRejectCallbacks);
   mResolveCallbacks.Clear();
   mRejectCallbacks.Clear();
 
-  JSContext* cx = nsContentUtils::GetDefaultJSContextForThread();
-  JSAutoRequest ar(cx);
+  ThreadsafeAutoJSContext cx; // Just for rooting.
   JS::Rooted<JS::Value> value(cx, mResult);
 
   for (uint32_t i = 0; i < callbacks.Length(); ++i) {
     callbacks[i]->Call(value);
   }
 }
 
 void
 Promise::MaybeReportRejected()
 {
   if (mState != Rejected || mHadRejectCallback || mResult.isUndefined()) {
     return;
   }
 
-  // Technically we should push this JSContext, but in reality the JS engine
-  // just uses it for string allocation here, so we can get away without it.
   if (!mResult.isObject()) {
     return;
   }
-  JSContext* cx = nsContentUtils::GetDefaultJSContextForThread();
-  JSAutoRequest ar(cx);
+  ThreadsafeAutoJSContext cx;
   JS::Rooted<JSObject*> obj(cx, &mResult.toObject());
   JSAutoCompartment ac(cx, obj);
   JSErrorReport* report = JS_ErrorFromException(cx, obj);
   if (!report) {
     return;
   }
 
   // Remains null in case of worker.
--- a/dom/promise/PromiseCallback.cpp
+++ b/dom/promise/PromiseCallback.cpp
@@ -72,22 +72,17 @@ ResolvePromiseCallback::~ResolvePromiseC
 {
   MOZ_COUNT_DTOR(ResolvePromiseCallback);
 }
 
 void
 ResolvePromiseCallback::Call(JS::Handle<JS::Value> aValue)
 {
   // Run resolver's algorithm with value and the synchronous flag set.
-  JSContext *cx = nsContentUtils::GetDefaultJSContextForThread();
-
-  Maybe<AutoCxPusher> pusher;
-  if (NS_IsMainThread()) {
-    pusher.construct(cx);
-  }
+  ThreadsafeAutoSafeJSContext cx;
 
   Maybe<JSAutoCompartment> ac;
   EnterCompartment(ac, cx, aValue);
 
   mPromise->ResolveInternal(cx, aValue, Promise::SyncTask);
 }
 
 // RejectPromiseCallback
@@ -113,22 +108,17 @@ RejectPromiseCallback::~RejectPromiseCal
 {
   MOZ_COUNT_DTOR(RejectPromiseCallback);
 }
 
 void
 RejectPromiseCallback::Call(JS::Handle<JS::Value> aValue)
 {
   // Run resolver's algorithm with value and the synchronous flag set.
-  JSContext *cx = nsContentUtils::GetDefaultJSContextForThread();
-
-  Maybe<AutoCxPusher> pusher;
-  if (NS_IsMainThread()) {
-    pusher.construct(cx);
-  }
+  ThreadsafeAutoSafeJSContext cx;
 
   Maybe<JSAutoCompartment> ac;
   EnterCompartment(ac, cx, aValue);
 
   mPromise->RejectInternal(cx, aValue, Promise::SyncTask);
 }
 
 // WrapperPromiseCallback
@@ -155,26 +145,17 @@ WrapperPromiseCallback::WrapperPromiseCa
 WrapperPromiseCallback::~WrapperPromiseCallback()
 {
   MOZ_COUNT_DTOR(WrapperPromiseCallback);
 }
 
 void
 WrapperPromiseCallback::Call(JS::Handle<JS::Value> aValue)
 {
-  // AutoCxPusher and co. interact with xpconnect, which crashes on
-  // workers. On workers we'll get the right context from
-  // GetDefaultJSContextForThread(), and since there is only one context, we
-  // don't need to push or pop it from the stack.
-  JSContext* cx = nsContentUtils::GetDefaultJSContextForThread();
-
-  Maybe<AutoCxPusher> pusher;
-  if (NS_IsMainThread()) {
-    pusher.construct(cx);
-  }
+  ThreadsafeAutoSafeJSContext cx;
 
   Maybe<JSAutoCompartment> ac;
   EnterCompartment(ac, cx, aValue);
 
   ErrorResult rv;
 
   // If invoking callback threw an exception, run resolver's reject with the
   // thrown exception as argument and the synchronous flag set.
--- a/dom/tests/mochitest/bugs/test_bug370098.html
+++ b/dom/tests/mochitest/bugs/test_bug370098.html
@@ -19,20 +19,19 @@ https://bugzilla.mozilla.org/show_bug.cg
 /** Test for Bug 370098 **/
 function test_constructor(dom_proto, shouldthrow) {
     var threw = false;
     try {
         window[dom_proto]();
     } catch (e) {
         threw = true;
     }
-    if (shouldthrow)
-      ok(threw, "Calling |" + dom_proto + "()| should throw");
-    else
-      todo(threw, "Calling |" + dom_proto + "()| should throw");
+    // XSLTProcessor is still on the old bindings.
+    if (dom_proto != 'XSLTProcessor')
+      ok(threw, "Calling |" + dom_proto + "()| should always throw");
 
     threw = false;
     try {
         new window[dom_proto]();
     } catch (e) {
         threw = true;
     }
     is(threw, shouldthrow, "Calling |new " + dom_proto + "()| should" + (shouldthrow ? " " : " not ") + "throw");
--- a/dom/xbl/nsXBLBinding.h
+++ b/dom/xbl/nsXBLBinding.h
@@ -32,17 +32,17 @@ class XBLChildrenElement;
 } // namespace dom
 } // namespace mozilla
 
 class nsAnonymousContentList;
 
 // *********************************************************************/
 // The XBLBinding class
 
-class nsXBLBinding
+class nsXBLBinding MOZ_FINAL
 {
 public:
   nsXBLBinding(nsXBLPrototypeBinding* aProtoBinding);
   nsXBLBinding(mozilla::dom::ShadowRoot* aShadowRoot, nsXBLPrototypeBinding* aProtoBinding);
   ~nsXBLBinding();
 
   /**
    * XBLBindings are refcounted.  They are held onto in 3 ways:
--- a/dom/xbl/nsXBLDocumentInfo.h
+++ b/dom/xbl/nsXBLDocumentInfo.h
@@ -10,17 +10,17 @@
 #include "nsAutoPtr.h"
 #include "nsWeakReference.h"
 #include "nsIDocument.h"
 #include "nsCycleCollectionParticipant.h"
 
 class nsXBLPrototypeBinding;
 class nsXBLDocGlobalObject;
 
-class nsXBLDocumentInfo : public nsSupportsWeakReference
+class nsXBLDocumentInfo MOZ_FINAL : public nsSupportsWeakReference
 {
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
 
   nsXBLDocumentInfo(nsIDocument* aDocument);
   virtual ~nsXBLDocumentInfo();
 
   already_AddRefed<nsIDocument> GetDocument()
--- a/dom/xbl/nsXBLProtoImpl.h
+++ b/dom/xbl/nsXBLProtoImpl.h
@@ -10,17 +10,17 @@
 #include "nsXBLPrototypeHandler.h"
 #include "nsXBLProtoImplMember.h"
 #include "nsXBLProtoImplField.h"
 #include "nsXBLBinding.h"
 
 class nsXBLPrototypeBinding;
 class nsXBLProtoImplAnonymousMethod;
 
-class nsXBLProtoImpl
+class nsXBLProtoImpl MOZ_FINAL
 {
 public:
   nsXBLProtoImpl()
     : mClassObject(nullptr),
       mMembers(nullptr),
       mFields(nullptr),
       mConstructor(nullptr),
       mDestructor(nullptr)
--- a/dom/xbl/nsXBLPrototypeBinding.h
+++ b/dom/xbl/nsXBLPrototypeBinding.h
@@ -26,17 +26,17 @@ class nsXBLBinding;
 class nsXBLProtoImplField;
 
 // *********************************************************************/
 // The XBLPrototypeBinding class
 
 // Instances of this class are owned by the nsXBLDocumentInfo object returned
 // by XBLDocumentInfo().  Consumers who want to refcount things should refcount
 // that.
-class nsXBLPrototypeBinding
+class nsXBLPrototypeBinding MOZ_FINAL
 {
 public:
   nsIContent* GetBindingElement() const { return mBinding; }
   void SetBindingElement(nsIContent* aElement);
 
   nsIURI* BindingURI() const { return mBindingURI; }
   nsIURI* AlternateBindingURI() const { return mAlternateBindingURI; }
   nsIURI* DocURI() const { return mXBLDocInfoWeak->DocumentURI(); }
--- a/dom/xbl/nsXBLService.h
+++ b/dom/xbl/nsXBLService.h
@@ -27,18 +27,18 @@ class nsIPrincipal;
 class nsHashtable;
 
 namespace mozilla {
 namespace dom {
 class EventTarget;
 }
 }
 
-class nsXBLService : public nsIObserver,
-                     public nsSupportsWeakReference
+class nsXBLService MOZ_FINAL : public nsIObserver,
+                               public nsSupportsWeakReference
 {
   NS_DECL_ISUPPORTS
 
   static nsXBLService* gInstance;
 
   static void Init();
 
   static void Shutdown() {
--- a/editor/libeditor/base/IMETextTxn.cpp
+++ b/editor/libeditor/base/IMETextTxn.cpp
@@ -10,17 +10,16 @@
 #include "nsAutoPtr.h"                  // for nsRefPtr
 #include "nsDebug.h"                    // for NS_ASSERTION, etc
 #include "nsError.h"                    // for NS_SUCCEEDED, NS_FAILED, etc
 #include "nsIDOMCharacterData.h"        // for nsIDOMCharacterData
 #include "nsIDOMRange.h"                // for nsRange::SetEnd, etc
 #include "nsIContent.h"                 // for nsIContent
 #include "nsIEditor.h"                  // for nsIEditor
 #include "nsIPresShell.h"               // for SelectionType
-#include "nsIPrivateTextRange.h"        // for nsIPrivateTextRange, etc
 #include "nsISelection.h"               // for nsISelection
 #include "nsISelectionController.h"     // for nsISelectionController, etc
 #include "nsISelectionPrivate.h"        // for nsISelectionPrivate
 #include "nsISupportsImpl.h"            // for nsRange::AddRef, etc
 #include "nsISupportsUtils.h"           // for NS_ADDREF_THIS, NS_RELEASE
 #include "nsITransaction.h"             // for nsITransaction
 #include "nsRange.h"                    // for nsRange
 #include "nsString.h"                   // for nsString
@@ -44,29 +43,27 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(
     NS_ADDREF_THIS();
     return NS_OK;
   } else
 NS_INTERFACE_MAP_END_INHERITING(EditTxn)
 
 NS_IMETHODIMP IMETextTxn::Init(nsIDOMCharacterData     *aElement,
                                uint32_t                 aOffset,
                                uint32_t                 aReplaceLength,
-                               nsIPrivateTextRangeList *aTextRangeList,
+                               TextRangeArray          *aTextRangeArray,
                                const nsAString         &aStringToInsert,
                                nsIEditor               *aEditor)
 {
-  NS_ASSERTION(aElement, "illegal value- null ptr- aElement");
-  NS_ASSERTION(aTextRangeList, "illegal value- null ptr - aTextRangeList");
-  NS_ENSURE_TRUE(aElement && aTextRangeList, NS_ERROR_NULL_POINTER);
-  mElement = do_QueryInterface(aElement);
+  NS_ENSURE_ARG_POINTER(aElement);
+  mElement = aElement;
   mOffset = aOffset;
   mReplaceLength = aReplaceLength;
   mStringToInsert = aStringToInsert;
   mEditor = aEditor;
-  mRangeList = do_QueryInterface(aTextRangeList);
+  mRanges = aTextRangeArray;
   mFixed = false;
   return NS_OK;
 }
 
 NS_IMETHODIMP IMETextTxn::DoTransaction(void)
 {
 
 #ifdef DEBUG_IMETXN
@@ -80,17 +77,17 @@ NS_IMETHODIMP IMETextTxn::DoTransaction(
   // advance caret: This requires the presentation shell to get the selection.
   nsresult result;
   if (mReplaceLength == 0) {
     result = mElement->InsertData(mOffset, mStringToInsert);
   } else {
     result = mElement->ReplaceData(mOffset, mReplaceLength, mStringToInsert);
   }
   if (NS_SUCCEEDED(result)) {
-    result = CollapseTextSelection();
+    result = SetSelectionForRanges();
   }
 
   return result;
 }
 
 NS_IMETHODIMP IMETextTxn::UndoTransaction(void)
 {
 #ifdef DEBUG_IMETXN
@@ -137,19 +134,18 @@ NS_IMETHODIMP IMETextTxn::Merge(nsITrans
   //
   IMETextTxn*  otherTxn = nullptr;
   nsresult result = aTransaction->QueryInterface(IMETextTxn::GetCID(),(void**)&otherTxn);
   if (otherTxn && NS_SUCCEEDED(result))
   {
     //
     //  we absorb the next IME transaction by adopting its insert string as our own
     //
-    nsIPrivateTextRangeList* newTextRangeList;
-    otherTxn->GetData(mStringToInsert,&newTextRangeList);
-    mRangeList = do_QueryInterface(newTextRangeList);
+    mStringToInsert = otherTxn->mStringToInsert;
+    mRanges = otherTxn->mRanges;
     *aDidMerge = true;
 #ifdef DEBUG_IMETXN
     printf("IMETextTxn assimilated IMETextTxn:%p\n", aTransaction);
 #endif
     NS_RELEASE(otherTxn);
     return NS_OK;
   }
 
@@ -166,201 +162,139 @@ NS_IMETHODIMP IMETextTxn::MarkFixed(void
 NS_IMETHODIMP IMETextTxn::GetTxnDescription(nsAString& aString)
 {
   aString.AssignLiteral("IMETextTxn: ");
   aString += mStringToInsert;
   return NS_OK;
 }
 
 /* ============ protected methods ================== */
-static SelectionType TextRangeToSelection(int aTextRangeType)
+static SelectionType
+ToSelectionType(uint32_t aTextRangeType)
 {
-   switch(aTextRangeType)
-   {
-      case nsIPrivateTextRange::TEXTRANGE_RAWINPUT:
-           return nsISelectionController::SELECTION_IME_RAWINPUT;
-      case nsIPrivateTextRange::TEXTRANGE_SELECTEDRAWTEXT:
-           return nsISelectionController::SELECTION_IME_SELECTEDRAWTEXT;
-      case nsIPrivateTextRange::TEXTRANGE_CONVERTEDTEXT:
-           return nsISelectionController::SELECTION_IME_CONVERTEDTEXT;
-      case nsIPrivateTextRange::TEXTRANGE_SELECTEDCONVERTEDTEXT:
-           return nsISelectionController::SELECTION_IME_SELECTEDCONVERTEDTEXT;
-      case nsIPrivateTextRange::TEXTRANGE_CARETPOSITION:
-      default:
-           return nsISelectionController::SELECTION_NORMAL;
-   };
-}
-
-NS_IMETHODIMP IMETextTxn::GetData(nsString& aResult,nsIPrivateTextRangeList** aTextRangeList)
-{
-  NS_ASSERTION(aTextRangeList, "illegal value- null ptr- aTextRangeList");
-  NS_ENSURE_TRUE(aTextRangeList, NS_ERROR_NULL_POINTER);
-  aResult = mStringToInsert;
-  *aTextRangeList = mRangeList;
-  return NS_OK;
+  switch(aTextRangeType) {
+    case NS_TEXTRANGE_RAWINPUT:
+      return nsISelectionController::SELECTION_IME_RAWINPUT;
+    case NS_TEXTRANGE_SELECTEDRAWTEXT:
+      return nsISelectionController::SELECTION_IME_SELECTEDRAWTEXT;
+    case NS_TEXTRANGE_CONVERTEDTEXT:
+      return nsISelectionController::SELECTION_IME_CONVERTEDTEXT;
+    case NS_TEXTRANGE_SELECTEDCONVERTEDTEXT:
+      return nsISelectionController::SELECTION_IME_SELECTEDCONVERTEDTEXT;
+    default:
+      MOZ_CRASH("Selection type is invalid");
+      return nsISelectionController::SELECTION_NORMAL;
+  }
 }
 
-static SelectionType sel[4]=
+nsresult
+IMETextTxn::SetSelectionForRanges()
 {
-  nsISelectionController::SELECTION_IME_RAWINPUT,
-  nsISelectionController::SELECTION_IME_SELECTEDRAWTEXT,
-  nsISelectionController::SELECTION_IME_CONVERTEDTEXT,
-  nsISelectionController::SELECTION_IME_SELECTEDCONVERTEDTEXT
-};
+  nsCOMPtr<nsISelectionController> selCon;
+  mEditor->GetSelectionController(getter_AddRefs(selCon));
+  NS_ENSURE_TRUE(selCon, NS_ERROR_NOT_INITIALIZED);
 
-NS_IMETHODIMP IMETextTxn::CollapseTextSelection(void)
-{
-    nsresult      result;
-    uint16_t      i;
+  nsCOMPtr<nsISelection> selection;
+  nsresult rv =
+    selCon->GetSelection(nsISelectionController::SELECTION_NORMAL,
+                         getter_AddRefs(selection));
+  NS_ENSURE_SUCCESS(rv, rv);
 
-#ifdef DEBUG_IMETXN
-    uint16_t listlen,start,stop,type;
-    result = mRangeList->GetLength(&listlen);
-    printf("nsIPrivateTextRangeList[%p]\n",mRangeList);
-    nsIPrivateTextRange* rangePtr;
-    for (i=0;i<listlen;i++) {
-      (void)mRangeList->Item(i,&rangePtr);
-      rangePtr->GetRangeStart(&start);
-      rangePtr->GetRangeEnd(&stop);
-      rangePtr->GetRangeType(&type);
-      printf("range[%d] start=%d end=%d type=",i,start,stop,type);
-      if (type==nsIPrivateTextRange::TEXTRANGE_RAWINPUT)
-                             printf("TEXTRANGE_RAWINPUT\n");
-      else if (type==nsIPrivateTextRange::TEXTRANGE_SELECTEDRAWTEXT)
-                                  printf("TEXTRANGE_SELECTEDRAWTEXT\n");
-      else if (type==nsIPrivateTextRange::TEXTRANGE_CONVERTEDTEXT)
-                                  printf("TEXTRANGE_CONVERTEDTEXT\n");
-      else if (type==nsIPrivateTextRange::TEXTRANGE_SELECTEDCONVERTEDTEXT)
-                                  printf("TEXTRANGE_SELECTEDCONVERTEDTEXT\n");
-      else if (type==nsIPrivateTextRange::TEXTRANGE_CARETPOSITION)
-                                  printf("TEXTRANGE_CARETPOSITION\n");
-      else printf("unknown constant\n");
+  nsCOMPtr<nsISelectionPrivate> selPriv(do_QueryInterface(selection));
+  rv = selPriv->StartBatchChanges();
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  // First, remove all selections of IME composition.
+  static const SelectionType kIMESelections[] = {
+    nsISelectionController::SELECTION_IME_RAWINPUT,
+    nsISelectionController::SELECTION_IME_SELECTEDRAWTEXT,
+    nsISelectionController::SELECTION_IME_CONVERTEDTEXT,
+    nsISelectionController::SELECTION_IME_SELECTEDCONVERTEDTEXT
+  };
+  for (uint32_t i = 0; i < ArrayLength(kIMESelections); ++i) {
+    nsCOMPtr<nsISelection> selectionOfIME;
+    if (NS_FAILED(selCon->GetSelection(kIMESelections[i],
+                                       getter_AddRefs(selectionOfIME)))) {
+      continue;
     }
-#endif
-        
-    //
-    // run through the text range list, if any
-    //
-    nsCOMPtr<nsISelectionController> selCon;
-    mEditor->GetSelectionController(getter_AddRefs(selCon));
-    NS_ENSURE_TRUE(selCon, NS_ERROR_NOT_INITIALIZED);
+    DebugOnly<nsresult> rv = selectionOfIME->RemoveAllRanges();
+    NS_ASSERTION(NS_SUCCEEDED(rv),
+                 "Failed to remove all ranges of IME selection");
+  }
+
+  // Set caret position and selection of IME composition with TextRangeArray.
+  bool setCaret = false;
+  uint32_t countOfRanges = mRanges ? mRanges->Length() : 0;
+  for (uint32_t i = 0; i < countOfRanges; ++i) {
+    const TextRange& textRange = mRanges->ElementAt(i);
 
-    uint16_t      textRangeListLength,selectionStart,selectionEnd,
-                  textRangeType;
-    
-    textRangeListLength = mRangeList->GetLength();
-    nsCOMPtr<nsISelection> selection;
-    result = selCon->GetSelection(nsISelectionController::SELECTION_NORMAL, getter_AddRefs(selection));
-    if(NS_SUCCEEDED(result))
-    {
-      nsCOMPtr<nsISelectionPrivate> selPriv(do_QueryInterface(selection));
-      result = selPriv->StartBatchChanges();
-      if (NS_SUCCEEDED(result))
-      {
-        nsCOMPtr<nsISelection> imeSel;
-        for(int8_t selIdx = 0; selIdx < 4;selIdx++)
-        {
-          result = selCon->GetSelection(sel[selIdx], getter_AddRefs(imeSel));
-          if (NS_SUCCEEDED(result))
-          {
-            result = imeSel->RemoveAllRanges();
-            NS_ASSERTION(NS_SUCCEEDED(result), "Cannot ClearSelection");
-            // we just ignore the result and clean up the next one here
-          }
-        }
-
-        nsCOMPtr<nsIPrivateTextRange> textRange;
-        bool setCaret=false;
-        for(i=0;i<textRangeListLength;i++)
-        {
-          textRange = mRangeList->Item(i);
-          NS_ASSERTION(textRange, "cannot get item");
-          if(!textRange)
-               break;
+    // Caret needs special handling since its length may be 0 and if it's not
+    // specified explicitly, we need to handle it ourselves later.
+    if (textRange.mRangeType == NS_TEXTRANGE_CARETPOSITION) {
+      NS_ASSERTION(!setCaret, "The ranges already has caret position");
+      NS_ASSERTION(!textRange.Length(), "nsEditor doesn't support wide caret");
+      // NOTE: If the caret position is larger than max length of the editor
+      //       content, this may fail.
+      rv = selection->Collapse(mElement, mOffset + textRange.mStartOffset);
+      setCaret = setCaret || NS_SUCCEEDED(rv);
+      NS_ASSERTION(setCaret, "Failed to collapse normal selection");
+      continue;
+    }
 
-          result = textRange->GetRangeType(&textRangeType);
-          NS_ASSERTION(NS_SUCCEEDED(result), "cannot get range type");
-          if(NS_FAILED(result))
-               break;
-
-          result = textRange->GetRangeStart(&selectionStart);
-          NS_ASSERTION(NS_SUCCEEDED(result), "cannot get range start");
-          if(NS_FAILED(result))
-               break;
-          result = textRange->GetRangeEnd(&selectionEnd);
-          NS_ASSERTION(NS_SUCCEEDED(result), "cannot get range end");
-          if(NS_FAILED(result))
-               break;
+    // If the clause length is 0, it's should be a bug.
+    if (!textRange.Length()) {
+      NS_WARNING("Any clauses must not be empty");
+      continue;
+    }
 
-          if(nsIPrivateTextRange::TEXTRANGE_CARETPOSITION == textRangeType)
-          {
-             NS_ASSERTION(selectionStart == selectionEnd,
-                          "nsEditor doesn't support wide caret");
-             // Set the caret....
-             result = selection->Collapse(mElement,
-                      mOffset+selectionStart);
-             NS_ASSERTION(NS_SUCCEEDED(result), "Cannot Collapse");
-             if(NS_SUCCEEDED(result))
-             setCaret = true;
-          } else {
-             // NS_ASSERTION(selectionStart != selectionEnd, "end == start");
-             if(selectionStart == selectionEnd)
-                continue;
+    nsRefPtr<nsRange> clauseRange;
+    rv = nsRange::CreateRange(mElement, mOffset + textRange.mStartOffset,
+                              mElement, mOffset + textRange.mEndOffset,
+                              getter_AddRefs(clauseRange));
+    if (NS_FAILED(rv)) {
+      NS_WARNING("Failed to create a DOM range for a clause of composition");
+      break;
+    }
 
-             result= selCon->GetSelection(TextRangeToSelection(textRangeType),
-                     getter_AddRefs(imeSel));
-             NS_ASSERTION(NS_SUCCEEDED(result), "Cannot get selction");
-             if(NS_FAILED(result))
-                break;
-
-             nsCOMPtr<nsIContent> content = do_QueryInterface(mElement);
-             if (!content) {
-               break;
-          }
+    // Set the range of the clause to selection.
+    nsCOMPtr<nsISelection> selectionOfIME;
+    rv = selCon->GetSelection(ToSelectionType(textRange.mRangeType),
+                              getter_AddRefs(selectionOfIME));
+    if (NS_FAILED(rv)) {
+      NS_WARNING("Failed to get IME selection");
+      break;
+    }
 
-             nsRefPtr<nsRange> newRange = new nsRange(content);
-             result = newRange->SetStart(content, mOffset+selectionStart);
-             NS_ASSERTION(NS_SUCCEEDED(result), "Cannot SetStart");
-             if(NS_FAILED(result))
-                break;
-
-             result = newRange->SetEnd(mElement,mOffset+selectionEnd);
-             NS_ASSERTION(NS_SUCCEEDED(result), "Cannot SetEnd");
-             if(NS_FAILED(result))
-                break;
-
-             result = imeSel->AddRange(newRange);
-             NS_ASSERTION(NS_SUCCEEDED(result), "Cannot AddRange");
-             if(NS_FAILED(result))
-                break;
+    rv = selectionOfIME->AddRange(clauseRange);
+    if (NS_FAILED(rv)) {
+      NS_WARNING("Failed to add selection range for a clause of composition");
+      break;
+    }
 
-             nsCOMPtr<nsISelectionPrivate> imeSelPriv(
-                                             do_QueryInterface(imeSel));
-             if (imeSelPriv) {
-               TextRangeStyle textRangeStyle;
-               result = textRange->GetRangeStyle(&textRangeStyle);
-               NS_ASSERTION(NS_SUCCEEDED(result),
-                            "nsIPrivateTextRange::GetRangeStyle failed");
-               if (NS_FAILED(result))
-                 break;
-               result = imeSelPriv->SetTextRangeStyle(newRange, textRangeStyle);
-               NS_ASSERTION(NS_SUCCEEDED(result),
-                 "nsISelectionPrivate::SetTextRangeStyle failed");
-               if (NS_FAILED(result))
-                 break;
-             } else {
-               NS_WARNING("IME selection doesn't have nsISelectionPrivate");
-             }
-          } // if GetRangeEnd
-        } // for textRangeListLength
-        if(! setCaret) {
-          // set cursor
-          result = selection->Collapse(mElement,mOffset+mStringToInsert.Length());
-          NS_ASSERTION(NS_SUCCEEDED(result), "Cannot Collapse");
-        }
-        result = selPriv->EndBatchChanges();
-        NS_ASSERTION(NS_SUCCEEDED(result), "Cannot EndBatchChanges");
-      } // if StartBatchChanges
-    } // if GetSelection
+    // Set the style of the clause.
+    nsCOMPtr<nsISelectionPrivate> selectionOfIMEPriv =
+                                    do_QueryInterface(selectionOfIME);
+    if (!selectionOfIMEPriv) {
+      NS_WARNING("Failed to get nsISelectionPrivate interface from selection");
+      continue; // Since this is additional feature, we can continue this job.
+    }
+    rv = selectionOfIMEPriv->SetTextRangeStyle(clauseRange,
+                                               textRange.mRangeStyle);
+    if (NS_FAILED(rv)) {
+      NS_WARNING("Failed to set selection style");
+      break; // but this is unexpected...
+    }
+  }
 
-    return result;
+  // If the ranges doesn't include explicit caret position, let's set the
+  // caret to the end of composition string.
+  if (!setCaret) {
+    rv = selection->Collapse(mElement, mOffset + mStringToInsert.Length());
+    NS_ASSERTION(NS_SUCCEEDED(rv),
+                 "Failed to set caret at the end of composition string");
+  }
+
+  rv = selPriv->EndBatchChanges();
+  NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to end batch changes");
+
+  return rv;
 }
 
--- a/editor/libeditor/base/IMETextTxn.h
+++ b/editor/libeditor/base/IMETextTxn.h
@@ -6,19 +6,19 @@
 #ifndef IMETextTxn_h__
 #define IMETextTxn_h__
 
 #include "EditTxn.h"
 #include "nsCOMPtr.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsID.h"
 #include "nsIDOMCharacterData.h"
-#include "nsIPrivateTextRange.h"
 #include "nsString.h"
 #include "nscore.h"
+#include "mozilla/TextRange.h"
 
 class nsITransaction;
 
 // {D4D25721-2813-11d3-9EA3-0060089FE59B}
 #define IME_TEXT_TXN_CID							\
 {0xd4d25721, 0x2813, 0x11d3,						\
 {0x9e, 0xa3, 0x0, 0x60, 0x8, 0x9f, 0xe5, 0x9b }}
 
@@ -33,23 +33,24 @@ class IMETextTxn : public EditTxn
 {
 public:
   static const nsIID& GetCID() { static const nsIID iid = IME_TEXT_TXN_CID; return iid; }
 
   /** initialize the transaction
     * @param aElement the text content node
     * @param aOffset  the location in aElement to do the insertion
     * @param aReplaceLength the length of text to replace (0 == no replacement)
+    * @param aTextRangeArray clauses and/or caret information. This may be null.
     * @param aString  the new text to insert
     * @param aSelCon used to get and set the selection
     */
   NS_IMETHOD Init(nsIDOMCharacterData *aElement,
                   uint32_t aOffset,
                   uint32_t aReplaceLength,
-                  nsIPrivateTextRangeList* aTextRangeList,
+                  mozilla::TextRangeArray* aTextRangeArray,
                   const nsAString& aString,
                   nsIEditor* aEditor);
 
   IMETextTxn();
 
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(IMETextTxn, EditTxn)
 
   NS_DECL_EDITTXN
@@ -58,36 +59,33 @@ public:
 
   NS_IMETHOD MarkFixed(void);
 
 // nsISupports declarations
 
   // override QueryInterface to handle IMETextTxn request
   NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr);
 
-  /** return the string data associated with this transaction */
-  NS_IMETHOD GetData(nsString& aResult, nsIPrivateTextRangeList** aTextRangeList);
-
 protected:
 
-  NS_IMETHOD CollapseTextSelection(void);
+  nsresult SetSelectionForRanges();
 
   /** the text element to operate upon */
   nsCOMPtr<nsIDOMCharacterData> mElement;
   
   /** the offsets into mElement where the insertion should be placed*/
   uint32_t mOffset;
 
   uint32_t mReplaceLength;
 
   /** the text to insert into mElement at mOffset */
   nsString mStringToInsert;
 
   /** the range list **/
-  nsCOMPtr<nsIPrivateTextRangeList>	mRangeList;
+  nsRefPtr<mozilla::TextRangeArray> mRanges;
 
   /** the editor, which is used to get the selection controller */
   nsIEditor *mEditor;
 
   bool	mFixed;
 };
 
 #endif
--- a/editor/libeditor/base/nsEditor.cpp
+++ b/editor/libeditor/base/nsEditor.cpp
@@ -76,17 +76,16 @@
 #include "nsIHTMLDocument.h"            // for nsIHTMLDocument
 #include "nsIInlineSpellChecker.h"      // for nsIInlineSpellChecker, etc
 #include "nsIMEStateManager.h"          // for nsIMEStateManager
 #include "nsNameSpaceManager.h"        // for kNameSpaceID_None, etc
 #include "nsINode.h"                    // for nsINode, etc
 #include "nsIObserverService.h"         // for nsIObserverService
 #include "nsIPlaintextEditor.h"         // for nsIPlaintextEditor, etc
 #include "nsIPresShell.h"               // for nsIPresShell
-#include "nsIPrivateTextRange.h"        // for nsIPrivateTextRange, etc
 #include "nsISelection.h"               // for nsISelection, etc
 #include "nsISelectionController.h"     // for nsISelectionController, etc
 #include "nsISelectionDisplay.h"        // for nsISelectionDisplay, etc
 #include "nsISelectionPrivate.h"        // for nsISelectionPrivate, etc
 #include "nsISupportsBase.h"            // for nsISupports
 #include "nsISupportsUtils.h"           // for NS_ADDREF, NS_IF_ADDREF
 #include "nsITransaction.h"             // for nsITransaction
 #include "nsITransactionManager.h"
@@ -160,17 +159,16 @@ nsEditor::~nsEditor()
 }
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsEditor)
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsEditor)
  NS_IMPL_CYCLE_COLLECTION_UNLINK(mRootElement)
  NS_IMPL_CYCLE_COLLECTION_UNLINK(mInlineSpellChecker)
  NS_IMPL_CYCLE_COLLECTION_UNLINK(mTxnMgr)
- NS_IMPL_CYCLE_COLLECTION_UNLINK(mIMETextRangeList)
  NS_IMPL_CYCLE_COLLECTION_UNLINK(mIMETextNode)
  NS_IMPL_CYCLE_COLLECTION_UNLINK(mActionListeners)
  NS_IMPL_CYCLE_COLLECTION_UNLINK(mEditorObservers)
  NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocStateListeners)
  NS_IMPL_CYCLE_COLLECTION_UNLINK(mEventTarget)
  NS_IMPL_CYCLE_COLLECTION_UNLINK(mEventListener)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
@@ -179,17 +177,16 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(
    tmp->mRootElement ? tmp->mRootElement->GetCurrentDoc() : nullptr;
  if (currentDoc &&
      nsCCUncollectableMarker::InGeneration(cb, currentDoc->GetMarkedCCGeneration())) {
    return NS_SUCCESS_INTERRUPTED_TRAVERSE;
  }
  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRootElement)
  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mInlineSpellChecker)
  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTxnMgr)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mIMETextRangeList)
  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mIMETextNode)
  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mActionListeners)
  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mEditorObservers)
  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocStateListeners)
  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mEventTarget)
  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mEventListener)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
@@ -2418,60 +2415,36 @@ nsresult nsEditor::InsertTextIntoTextNod
                                               int32_t aOffset,
                                               bool aSuppressIME)
 {
   nsRefPtr<EditTxn> txn;
   nsresult result = NS_OK;
   bool isIMETransaction = false;
   // aSuppressIME is used when editor must insert text, yet this text is not
   // part of current ime operation.  example: adjusting whitespace around an ime insertion.
-  if (mIMETextRangeList && mComposition && !aSuppressIME)
-  {
-    if (!mIMETextNode)
-    {
+  if (mComposition && !aSuppressIME) {
+    if (!mIMETextNode) {
       mIMETextNode = aTextNode;
       mIMETextOffset = aOffset;
     }
-    uint16_t len ;
-    len = mIMETextRangeList->GetLength();
-    if (len > 0)
-    {
-      nsCOMPtr<nsIPrivateTextRange> range;
-      for (uint16_t i = 0; i < len; i++) 
-      {
-        range = mIMETextRangeList->Item(i);
-        if (range)
-        {
-          uint16_t type;
-          result = range->GetRangeType(&type);
-          if (NS_SUCCEEDED(result)) 
-          {
-            if (type == nsIPrivateTextRange::TEXTRANGE_RAWINPUT) 
-            {
-              uint16_t start, end;
-              result = range->GetRangeStart(&start);
-              if (NS_SUCCEEDED(result)) 
-              {
-                result = range->GetRangeEnd(&end);
-                if (NS_SUCCEEDED(result)) 
-                {
-                  if (!mPhonetic)
-                    mPhonetic = new nsString();
-                  if (mPhonetic)
-                  {
-                    nsAutoString tmp(aStringToInsert);                  
-                    tmp.Mid(*mPhonetic, start, end-start);
-                  }
-                }
-              }
-            } // if
-          }
-        } // if
-      } // for
-    } // if
+    // Modify mPhonetic with raw text input clauses.
+    const TextRangeArray* ranges = mComposition->GetRanges();
+    for (uint32_t i = 0; i < (ranges ? ranges->Length() : 0); ++i) {
+      const TextRange& textRange = ranges->ElementAt(i);
+      if (!textRange.Length() ||
+          textRange.mRangeType != NS_TEXTRANGE_RAWINPUT) {
+        continue;
+      }
+      if (!mPhonetic) {
+        mPhonetic = new nsString();
+      }
+      nsAutoString stringToInsert(aStringToInsert);
+      stringToInsert.Mid(*mPhonetic,
+                         textRange.mStartOffset, textRange.Length());
+    }
 
     nsRefPtr<IMETextTxn> imeTxn;
     result = CreateTxnForIMEText(aStringToInsert, getter_AddRefs(imeTxn));
     txn = imeTxn;
     isIMETransaction = true;
   }
   else
   {
@@ -4397,19 +4370,20 @@ NS_IMETHODIMP
 nsEditor::CreateTxnForIMEText(const nsAString& aStringToInsert,
                               IMETextTxn ** aTxn)
 {
   NS_ASSERTION(aTxn, "illegal value- null ptr- aTxn");
      
   nsRefPtr<IMETextTxn> txn = new IMETextTxn();
 
   // During handling IME composition, mComposition must have been initialized.
+  // TODO: We can simplify IMETextTxn::Init() with TextComposition class.
   nsresult rv = txn->Init(mIMETextNode, mIMETextOffset,
                           mComposition->String().Length(),
-                          mIMETextRangeList, aStringToInsert, this);
+                          mComposition->GetRanges(), aStringToInsert, this);
   if (NS_SUCCEEDED(rv))
   {
     txn.forget(aTxn);
   }
 
   return rv;
 }
 
--- a/editor/libeditor/base/nsEditor.h
+++ b/editor/libeditor/base/nsEditor.h
@@ -53,17 +53,16 @@ class nsIDOMNode;
 class nsIDOMRange;
 class nsIDocument;
 class nsIDocumentStateListener;
 class nsIEditActionListener;
 class nsIEditorObserver;
 class nsIInlineSpellChecker;
 class nsINode;
 class nsIPresShell;
-class nsIPrivateTextRangeList;
 class nsISelection;
 class nsISupports;
 class nsITransaction;
 class nsIWidget;
 class nsRange;
 class nsString;
 class nsTransactionManager;
 
@@ -828,17 +827,16 @@ protected:
   };
   // Spellchecking
   nsCString mContentMIMEType;       // MIME type of the doc we are editing.
 
   nsCOMPtr<nsIInlineSpellChecker> mInlineSpellChecker;
 
   nsRefPtr<nsTransactionManager> mTxnMgr;
   nsCOMPtr<mozilla::dom::Element> mRootElement; // cached root node
-  nsCOMPtr<nsIPrivateTextRangeList> mIMETextRangeList; // IME special selection ranges
   nsCOMPtr<nsIDOMCharacterData>     mIMETextNode;      // current IME text node
   nsCOMPtr<mozilla::dom::EventTarget> mEventTarget; // The form field as an event receiver
   nsCOMPtr<nsIDOMEventListener> mEventListener;
   nsWeakPtr        mSelConWeak;          // weak reference to the nsISelectionController
   nsWeakPtr        mPlaceHolderTxn;      // weak reference to placeholder for begin/end batch purposes
   nsWeakPtr        mDocWeak;             // weak reference to the nsIDOMDocument
   nsIAtom          *mPlaceHolderName;    // name of placeholder transaction
   nsSelectionState *mSelState;           // saved selection state for placeholder txn batching
--- a/editor/libeditor/text/nsPlaintextEditor.cpp
+++ b/editor/libeditor/text/nsPlaintextEditor.cpp
@@ -35,18 +35,16 @@
 #include "nsIDOMKeyEvent.h"
 #include "nsIDOMNode.h"
 #include "nsIDOMNodeList.h"
 #include "nsIDocumentEncoder.h"
 #include "nsIEditorIMESupport.h"
 #include "nsNameSpaceManager.h"
 #include "nsINode.h"
 #include "nsIPresShell.h"
-#include "nsIPrivateTextEvent.h"
-#include "nsIPrivateTextRange.h"
 #include "nsISelection.h"
 #include "nsISelectionController.h"
 #include "nsISelectionPrivate.h"
 #include "nsISupportsPrimitives.h"
 #include "nsITransferable.h"
 #include "nsIWeakReferenceUtils.h"
 #include "nsInternetCiter.h"
 #include "nsLiteralString.h"
@@ -843,30 +841,20 @@ nsPlaintextEditor::UpdateIMEComposition(
   NS_ENSURE_TRUE(ps, NS_ERROR_NOT_INITIALIZED);
 
   nsCOMPtr<nsISelection> selection;
   nsresult rv = GetSelection(getter_AddRefs(selection));
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsRefPtr<nsCaret> caretP = ps->GetCaret();
 
-  nsCOMPtr<nsIPrivateTextEvent> privateTextEvent =
-    do_QueryInterface(aDOMTextEvent);
-  NS_ENSURE_TRUE(privateTextEvent, NS_ERROR_INVALID_ARG);
-
   {
     TextComposition::TextEventHandlingMarker
       textEventHandlingMarker(mComposition, widgetTextEvent);
 
-    // Update information of clauses in the new composition string.
-    // This will be refered by followed methods.
-    mIMETextRangeList = privateTextEvent->GetInputRange();
-    NS_ABORT_IF_FALSE(mIMETextRangeList,
-                      "mIMETextRangeList must not be nullptr");
-
     nsAutoPlaceHolderBatch batch(this, nsGkAtoms::IMETxnName);
 
     rv = InsertText(widgetTextEvent->theText);
 
     if (caretP) {
       caretP->SetCaretDOMSelection(selection);
     }
   }
--- a/editor/libeditor/text/nsPlaintextEditor.h
+++ b/editor/libeditor/text/nsPlaintextEditor.h
@@ -21,17 +21,16 @@ class nsIDOMDocument;
 class nsIDOMElement;
 class nsIDOMEvent;
 class nsIDOMEventTarget;
 class nsIDOMKeyEvent;
 class nsIDOMNode;
 class nsIDocumentEncoder;
 class nsIEditRules;
 class nsIOutputStream;
-class nsIPrivateTextRangeList;
 class nsISelection;
 class nsISelectionController;
 class nsITransferable;
 
 /**
  * The text editor implementation.
  * Use to edit text document represented as a DOM tree. 
  */
--- a/gfx/2d/Makefile.in
+++ b/gfx/2d/Makefile.in
@@ -9,25 +9,9 @@ endif
 
 include $(topsrcdir)/config/rules.mk
 
 # Due to bug 796023, we can't have -DUNICODE and -D_UNICODE; defining those
 # macros changes the type of LOGFONT to LOGFONTW instead of LOGFONTA. This
 # changes the symbol names of exported C++ functions that use LOGFONT.
 DEFINES := $(filter-out -DUNICODE -D_UNICODE,$(DEFINES))
 
-# The file uses SSE2 intrinsics, so it needs special compile flags on some
-# compilers.
-ifneq (,$(INTEL_ARCHITECTURE))
-ifdef GNU_CC
-ImageScalingSSE2.$(OBJ_SUFFIX): CXXFLAGS+=-msse2
-BlurSSE2.$(OBJ_SUFFIX): CXXFLAGS+=-msse2
-FilterProcessingSSE2.$(OBJ_SUFFIX): CXXFLAGS+=-msse2
-endif
-
-ifdef SOLARIS_SUNPRO_CXX
-ImageScalingSSE2.$(OBJ_SUFFIX): OS_CXXFLAGS += -xarch=sse2 -xO4
-BlurSSE2.$(OBJ_SUFFIX): OS_CXXFLAGS += -xarch=sse2 -xO4
-FilterProcessingSSE2.$(OBJ_SUFFIX): OS_CXXFLAGS += -xarch=sse2 -xO4
-endif
-endif
-
 CXXFLAGS += $(MOZ_CAIRO_CFLAGS)
--- a/gfx/2d/moz.build
+++ b/gfx/2d/moz.build
@@ -83,16 +83,26 @@ if CONFIG['INTEL_ARCHITECTURE']:
     # VC2005 doesn't support _mm_castsi128_ps, so SSE2 is turned off
     if CONFIG['_MSC_VER'] != '1400':
         SOURCES += [
             'BlurSSE2.cpp',
             'FilterProcessingSSE2.cpp',
             'ImageScalingSSE2.cpp',
         ]
         DEFINES['USE_SSE2'] = True
+        # The file uses SSE2 intrinsics, so it needs special compile flags on some
+        # compilers.
+        if CONFIG['GNU_CC']:
+            SOURCES['BlurSSE2.cpp'].flags += ['-msse2']
+            SOURCES['FilterProcessingSSE2.cpp'].flags += ['-msse2']
+            SOURCES['ImageScalingSSE2.cpp'].flags += ['-msse2']
+        if CONFIG['SOLARIS_SUNPRO_CXX']:
+            SOURCES['BlurSSE2.cpp'].flags += ['-xarch=sse2', '-xO4']
+            SOURCES['FilterProcessingSSE2.cpp'].flags += ['-xarch=sse2', '-xO4']
+            SOURCES['ImageScalingSSE2.cpp'].flags += ['-xarch=sse2', '-xO4']
 
 UNIFIED_SOURCES += [
     'Blur.cpp',
     'DataSourceSurface.cpp',
     'DrawEventRecorder.cpp',
     'DrawTargetCairo.cpp',
     'DrawTargetDual.cpp',
     'DrawTargetRecording.cpp',
--- a/gfx/angle/src/libGLESv2/Makefile.in
+++ b/gfx/angle/src/libGLESv2/Makefile.in
@@ -13,19 +13,16 @@ endif
 # End build_angle.gypi transcription.
 
 include $(topsrcdir)/config/rules.mk
 
 CXXFLAGS += -I'$(MOZ_DIRECTX_SDK_PATH)/include'
 
 ifdef GNU_CC
 
-TextureSSE2.$(OBJ_SUFFIX): CXXFLAGS+=-msse2
-ImageSSE2.$(OBJ_SUFFIX): CXXFLAGS+=-msse2
-
 OS_CXXFLAGS := $(filter-out -fno-exceptions,$(OS_CXXFLAGS)) -fexceptions
 OS_LIBS += -ld3d9 -ldxguid
 
 else
 
 EXTRA_DSO_LDOPTS = '$(MOZ_DIRECTX_SDK_PATH)/lib/$(MOZ_DIRECTX_SDK_CPU_SUFFIX)/d3d9.lib' \
                    '$(MOZ_DIRECTX_SDK_PATH)/lib/$(MOZ_DIRECTX_SDK_CPU_SUFFIX)/dxguid.lib' \
                    delayimp.lib
--- a/gfx/angle/src/libGLESv2/moz.build
+++ b/gfx/angle/src/libGLESv2/moz.build
@@ -167,16 +167,19 @@ SOURCES += ['renderer/' + src for src in
     'TextureStorage9.cpp',
     'VertexBuffer.cpp',
     'VertexBuffer11.cpp',
     'VertexBuffer9.cpp',
     'VertexDataManager.cpp',
     'VertexDeclarationCache.cpp',
 ]]
 
+if CONFIG['GNU_CC']:
+    SOURCES['renderer/ImageSSE2.cpp'].flags += ['-msse2']
+
 # On Windows, we don't automatically get "lib" prepended, but we need it.
 LIBRARY_NAME = 'libGLESv2'
 
 FORCE_SHARED_LIB = True
 
 LOCAL_INCLUDES += [
     '..',
     '../../include',
--- a/gfx/cairo/libpixman/src/Makefile.in
+++ b/gfx/cairo/libpixman/src/Makefile.in
@@ -1,68 +1,19 @@
 # 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/.
 
 ifeq ($(OS_TARGET),Android)
 MODULE_OPTIMIZE_FLAGS = -O2
 endif
 
-# Build MMX code either with VC or with gcc-on-x86
-ifdef _MSC_VER
-ifeq (86,$(findstring 86,$(OS_TEST)))
-USE_SSE2=1
-MMX_CFLAGS=
-SSE2_CFLAGS=
-endif
-endif
-
-ifdef GNU_CC
-ifeq (ppc,$(findstring ppc,$(OS_TEST)))
-VMX_CFLAGS=-maltivec
-endif
-ifeq (86,$(findstring 86,$(OS_TEST)))
-MMX_CFLAGS=-mmmx -Winline
-ifeq (64,$(findstring 64,$(OS_TEST)))
-USE_SSE2=1
-endif
-ifdef HAVE_GCC_ALIGN_ARG_POINTER
-USE_SSE2=1
-endif
-ifdef USE_SSE2
-SSE2_CFLAGS=-msse -msse2 -Winline
-endif
-MMX_CFLAGS+=--param inline-unit-growth=10000 --param large-function-growth=10000
-endif
-ifeq (arm,$(findstring arm,$(OS_TEST)))
-# Apple's arm assembler doesn't support the same syntax as
-# the standard GNU assembler, so use the C fallback paths for now.
-# This may be fixable if clang's ARM/iOS assembler improves into a
-# viable solution in the future.
-ifneq (Darwin,$(OS_ARCH))
-ifdef HAVE_ARM_NEON
-ARM_NEON_CFLAGS = -mfpu=neon
-endif
-endif
-endif
-
-endif
-
 include $(topsrcdir)/config/rules.mk
 
 # Disable spammy "missing initializer" GCC warning
 ifdef GNU_CC
 CFLAGS += -Wno-missing-field-initializers
 endif # GNU_CC
 
-# special rule for pixman-mmx to get the right cflags
-pixman-mmx.$(OBJ_SUFFIX): COMPILE_CFLAGS += $(MMX_CFLAGS)
-
-pixman-sse2.$(OBJ_SUFFIX): COMPILE_CFLAGS += $(SSE2_CFLAGS)
-
-pixman-arm-neon.$(OBJ_SUFFIX): COMPILE_CFLAGS += $(ARM_NEON_CFLAGS)
-
-pixman-vmx.$(OBJ_SUFFIX): COMPILE_CFLAGS += $(VMX_CFLAGS)
-
 # The ARM asm functions here don't appreciate being called by functions
 # compiled with -mapcs-frame.  See bug 832752.
 CXXFLAGS := $(filter-out -mapcs-frame,$(CXXFLAGS))
 CFLAGS := $(filter-out -mapcs-frame,$(CFLAGS))
--- a/gfx/cairo/libpixman/src/moz.build
+++ b/gfx/cairo/libpixman/src/moz.build
@@ -106,25 +106,40 @@ elif 'arm' in CONFIG['OS_TEST']:
         if CONFIG['HAVE_ARM_SIMD']:
             use_arm_simd_gcc = True
         if CONFIG['HAVE_ARM_NEON']:
             use_arm_neon_gcc = True
 
 if use_mmx:
     DEFINES['USE_MMX'] = True
     SOURCES += ['pixman-mmx.c']
+    if CONFIG['GNU_CC']:
+        SOURCES['pixman-mmx.c'].flags += [
+            '-mmmx',
+            '-Winline',
+            '--param inline-unit-growth=10000',
+            '--param large-function-growth=10000',
+        ]
 
 if use_sse2:
     DEFINES['USE_SSE'] = True
     DEFINES['USE_SSE2'] = True
     SOURCES += ['pixman-sse2.c']
+    if CONFIG['GNU_CC']:
+        SOURCES['pixman-sse2.c'].flags += [
+            '-msse',
+            '-msse2',
+            '-Winline',
+        ]
 
 if use_vmx:
     DEFINES['USE_VMX'] = True
     SOURCES += ['pixman-vmx.c']
+    SOURCES['pixman-vmx.c'].flags += ['-maltivec']
 
 if use_arm_simd_gcc:
     DEFINES['USE_ARM_SIMD'] = True
     SOURCES += ['pixman-arm-simd.c']
 
 if use_arm_neon_gcc:
     DEFINES['USE_ARM_NEON'] = True
     SOURCES += ['pixman-arm-neon.c']
+    SOURCES['pixman-arm-neon.c'].flags += ['-mfpu=neon']
--- a/gfx/gl/GLContext.cpp
+++ b/gfx/gl/GLContext.cpp
@@ -533,17 +533,18 @@ GLContext::InitWithPrefix(const char *pr
 
         const char *vendorMatchStrings[size_t(GLVendor::Other)] = {
                 "Intel",
                 "NVIDIA",
                 "ATI",
                 "Qualcomm",
                 "Imagination",
                 "nouveau",
-                "Vivante"
+                "Vivante",
+                "VMware, Inc."
         };
 
         mVendor = GLVendor::Other;
         for (size_t i = 0; i < size_t(GLVendor::Other); ++i) {
             if (DoesStringMatch(glVendorString, vendorMatchStrings[i])) {
                 mVendor = GLVendor(i);
                 break;
             }
@@ -558,17 +559,18 @@ GLContext::InitWithPrefix(const char *pr
         const char *rendererMatchStrings[size_t(GLRenderer::Other)] = {
                 "Adreno 200",
                 "Adreno 205",
                 "Adreno (TM) 205",
                 "Adreno (TM) 320",
                 "PowerVR SGX 530",
                 "PowerVR SGX 540",
                 "NVIDIA Tegra",
-                "Android Emulator"
+                "Android Emulator",
+                "Gallium 0.4 on llvmpipe"
         };
 
         mRenderer = GLRenderer::Other;
         for (size_t i = 0; i < size_t(GLRenderer::Other); ++i) {
             if (DoesStringMatch(glRendererString, rendererMatchStrings[i])) {
                 mRenderer = GLRenderer(i);
                 break;
             }
@@ -1092,17 +1094,17 @@ GLContext::InitWithPrefix(const char *pr
                     mMaxTextureSize = std::min(mMaxTextureSize, 8191);
                     mMaxRenderbufferSize = std::min(mMaxRenderbufferSize, 8191);
                 }
                 else {
                     // See bug 877949.
                     mMaxTextureSize = std::min(mMaxTextureSize, 4096);
                     mMaxRenderbufferSize = std::min(mMaxRenderbufferSize, 4096);
                 }
-                
+
                 // Part of the bug 879656, but it also doesn't hurt the 877949
                 mNeedsTextureSizeChecks = true;
             }
         }
 #endif
 #ifdef MOZ_X11
         if (mWorkAroundDriverBugs &&
             mVendor == GLVendor::Nouveau) {
@@ -1173,16 +1175,29 @@ GLContext::InitExtensions()
     if (WorkAroundDriverBugs() &&
         Renderer() == GLRenderer::AndroidEmulator) {
         // the Android emulator, which we use to run B2G reftests on,
         // doesn't expose the OES_rgb8_rgba8 extension, but it seems to
         // support it (tautologically, as it only runs on desktop GL).
         MarkExtensionSupported(OES_rgb8_rgba8);
     }
 
+    if (WorkAroundDriverBugs() &&
+        Vendor() == GLVendor::VMware &&
+        Renderer() == GLRenderer::GalliumLlvmpipe)
+    {
+        // The llvmpipe driver that is used on linux try servers appears to have
+        // buggy support for s3tc/dxt1 compressed textures.
+        // See Bug 975824.
+        MarkExtensionUnsupported(EXT_texture_compression_s3tc);
+        MarkExtensionUnsupported(EXT_texture_compression_dxt1);
+        MarkExtensionUnsupported(ANGLE_texture_compression_dxt3);
+        MarkExtensionUnsupported(ANGLE_texture_compression_dxt5);
+    }
+
 #ifdef DEBUG
     firstRun = false;
 #endif
 }
 
 void
 GLContext::PlatformStartup()
 {
--- a/gfx/gl/GLContext.h
+++ b/gfx/gl/GLContext.h
@@ -126,28 +126,30 @@ MOZ_END_ENUM_CLASS(ContextProfile)
 MOZ_BEGIN_ENUM_CLASS(GLVendor)
     Intel,
     NVIDIA,
     ATI,
     Qualcomm,
     Imagination,
     Nouveau,
     Vivante,
+    VMware,
     Other
 MOZ_END_ENUM_CLASS(GLVendor)
 
 MOZ_BEGIN_ENUM_CLASS(GLRenderer)
     Adreno200,
     Adreno205,
     AdrenoTM205,
     AdrenoTM320,
     SGX530,
     SGX540,
     Tegra,
     AndroidEmulator,
+    GalliumLlvmpipe,
     Other
 MOZ_END_ENUM_CLASS(GLRenderer)
 
 class GLContext
     : public GLLibraryLoader
     , public GenericAtomicRefCounted
 {
 // -----------------------------------------------------------------------------
--- a/gfx/tests/gtest/TestAsyncPanZoomController.cpp
+++ b/gfx/tests/gtest/TestAsyncPanZoomController.cpp
@@ -28,30 +28,30 @@ using ::testing::AtMost;
 using ::testing::MockFunction;
 using ::testing::InSequence;
 
 class Task;
 
 class AsyncPanZoomControllerTester : public ::testing::Test {
 protected:
   virtual void SetUp() {
-    gfxPrefs::One();
+    gfxPrefs::GetSingleton();
   }
   virtual void TearDown() {
-    gfxPrefs::Destroy();
+    gfxPrefs::DestroySingleton();
   }
 };
 
 class APZCTreeManagerTester : public ::testing::Test {
 protected:
   virtual void SetUp() {
-    gfxPrefs::One();
+    gfxPrefs::GetSingleton();
   }
   virtual void TearDown() {
-    gfxPrefs::Destroy();
+    gfxPrefs::DestroySingleton();
   }
 };
 
 class MockContentController : public GeckoContentController {
 public:
   MOCK_METHOD1(RequestContentRepaint, void(const FrameMetrics&));
   MOCK_METHOD2(AcknowledgeScrollUpdate, void(const FrameMetrics::ViewID&, const uint32_t& aScrollGeneration));
   MOCK_METHOD3(HandleDoubleTap, void(const CSSIntPoint&, int32_t, const ScrollableLayerGuid&));
new file mode 100644
--- /dev/null
+++ b/gfx/tests/gtest/TestGfxPrefs.cpp
@@ -0,0 +1,67 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "gtest/gtest.h"
+
+#include "gfxPrefs.h"
+#ifdef GFX_DECL_PREF
+#error "This is not supposed to be defined outside of gfxPrefs.h"
+#endif
+
+// If the default values for any of these preferences change,
+// just modify the test to match. We are only testing against
+// a particular value to make sure we receive the correct
+// result through this API.
+
+TEST(GfxPrefs, Singleton) {
+  ASSERT_FALSE(gfxPrefs::SingletonExists());
+  gfxPrefs::GetSingleton();
+  ASSERT_TRUE(gfxPrefs::SingletonExists());
+  gfxPrefs::DestroySingleton();
+  ASSERT_FALSE(gfxPrefs::SingletonExists());
+}
+
+TEST(GfxPrefs, LiveValues) {
+  ASSERT_FALSE(gfxPrefs::SingletonExists());
+  gfxPrefs::GetSingleton();
+  ASSERT_TRUE(gfxPrefs::SingletonExists());
+
+  // Live boolean, default false
+  ASSERT_FALSE(gfxPrefs::CanvasAzureAccelerated());
+
+  // Live int32_t, default 23456
+  ASSERT_TRUE(gfxPrefs::LayerScopePort() == 23456);
+
+  // Live uint32_t, default 2
+  ASSERT_TRUE(gfxPrefs::MSAALevel() == 2);
+
+  gfxPrefs::DestroySingleton();
+  ASSERT_FALSE(gfxPrefs::SingletonExists());
+}
+
+TEST(GfxPrefs, OnceValues) {
+  ASSERT_FALSE(gfxPrefs::SingletonExists());
+  gfxPrefs::GetSingleton();
+  ASSERT_TRUE(gfxPrefs::SingletonExists());
+
+  // Once boolean, default true
+  ASSERT_TRUE(gfxPrefs::WorkAroundDriverBugs());
+
+  // Once boolean, default false
+  ASSERT_FALSE(gfxPrefs::LayersDump());
+
+  // Once int32_t, default 95
+  ASSERT_TRUE(gfxPrefs::CanvasSkiaGLCacheSize() == 96);
+
+  // Once uint32_t, default 5
+  ASSERT_TRUE(gfxPrefs::APZMaxVelocityQueueSize() == 5);
+
+  // Once float, default -1 (should be OK with ==)
+  ASSERT_TRUE(gfxPrefs::APZMaxVelocity() == -1.0f);
+
+  gfxPrefs::DestroySingleton();
+  ASSERT_FALSE(gfxPrefs::SingletonExists());
+}
+
--- a/gfx/tests/gtest/moz.build
+++ b/gfx/tests/gtest/moz.build
@@ -8,16 +8,17 @@ LIBRARY_NAME = 'gfxtest'
 
 UNIFIED_SOURCES += [
     'gfxSurfaceRefCountTest.cpp',
     # Disabled on suspicion of causing bug 904227
     #'gfxWordCacheTest.cpp',
     'TestAsyncPanZoomController.cpp',
     'TestBufferRotation.cpp',
     'TestColorNames.cpp',
+    'TestGfxPrefs.cpp',
     'TestLayers.cpp',
     'TestRegion.cpp',
     'TestSkipChars.cpp',
     # Hangs on linux in ApplyGdkScreenFontOptions
     #'gfxFontSelectionTest.cpp',
     'TestTextures.cpp',
     # Test works but it doesn't assert anything
     #'gfxTextRunPerfTest.cpp',
--- a/gfx/thebes/Makefile.in
+++ b/gfx/thebes/Makefile.in
@@ -24,22 +24,10 @@ endif
 ifdef MOZ_WIDGET_GTK
 CXXFLAGS += $(MOZ_PANGO_CFLAGS)
 endif
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),qt)
 CXXFLAGS += $(CAIRO_FT_CFLAGS) $(MOZ_PANGO_CFLAGS)
 endif
 
-# The file uses SSE2 intrinsics, so it needs special compile flags on some
-# compilers.
-ifneq (,$(INTEL_ARCHITECTURE))
-ifdef GNU_CC
-gfxAlphaRecoverySSE2.$(OBJ_SUFFIX): CXXFLAGS+=-msse2
-endif
-
-ifdef SOLARIS_SUNPRO_CXX
-gfxAlphaRecoverySSE2.$(OBJ_SUFFIX): OS_CXXFLAGS += -xarch=sse2 -xO4
-endif
-endif
-
 DeprecatedPremultiplyTables.h: $(srcdir)/genTables.py
 	$(PYTHON) $(srcdir)/genTables.py
--- a/gfx/thebes/gfxPlatform.cpp
+++ b/gfx/thebes/gfxPlatform.cpp
@@ -102,17 +102,16 @@ static qcms_transform *gCMSRGBTransform 
 static qcms_transform *gCMSInverseRGBTransform = nullptr;
 static qcms_transform *gCMSRGBATransform = nullptr;
 
 static bool gCMSInitialized = false;
 static eCMSMode gCMSMode = eCMSMode_Off;
 static int gCMSIntent = -2;
 
 static void ShutdownCMS();
-static void MigratePrefs();
 
 #include "mozilla/gfx/2D.h"
 using namespace mozilla::gfx;
 
 /* Class to listen for pref changes so that chrome code can dynamically
    force sRGB as an output profile. See Bug #452125. */
 class SRGBOverrideObserver MOZ_FINAL : public nsIObserver,
                                        public nsSupportsWeakReference
@@ -319,22 +318,18 @@ void RecordingPrefChanged(const char *aP
 void
 gfxPlatform::Init()
 {
     if (gEverInitialized) {
         NS_RUNTIMEABORT("Already started???");
     }
     gEverInitialized = true;
 
-    /* Pref migration hook. */
-    MigratePrefs();
-
-    // Initialize the preferences by creating the singleton.  This should
-    // be done after the preference migration using MigratePrefs().
-    gfxPrefs::One();
+    // Initialize the preferences by creating the singleton.
+    gfxPrefs::GetSingleton();
 
     gGfxPlatformPrefsLock = new Mutex("gfxPlatform::gGfxPlatformPrefsLock");
 
     /* Initialize the GfxInfo service.
      * Note: we can't call functions on GfxInfo that depend
      * on gPlatform until after it has been initialized
      * below. GfxInfo initialization annotates our
      * crash reports so we want to do it before
@@ -501,17 +496,17 @@ gfxPlatform::Shutdown()
     // This will block this thread untill the ImageBridge protocol is completely
     // deleted.
     ImageBridgeChild::ShutDown();
 
     CompositorParent::ShutDown();
 
     delete gGfxPlatformPrefsLock;
 
-    gfxPrefs::Destroy();
+    gfxPrefs::DestroySingleton();
 
     delete gPlatform;
     gPlatform = nullptr;
 }
 
 gfxPlatform::~gfxPlatform()
 {
     mScreenReferenceSurface = nullptr;
@@ -1744,31 +1739,16 @@ static void ShutdownCMS()
     }
 
     // Reset the state variables
     gCMSIntent = -2;
     gCMSMode = eCMSMode_Off;
     gCMSInitialized = false;
 }
 
-static void MigratePrefs()
-{
-    /* Migrate from the boolean color_management.enabled pref - we now use
-       color_management.mode.  These calls should be made before gfxPrefs
-       is initialized, otherwise we may not pick up the correct values
-       with the gfxPrefs functions.
-    */
-    if (Preferences::HasUserValue(GFX_PREF_CMS_ENABLED_OBSOLETE)) {
-        if (Preferences::GetBool(GFX_PREF_CMS_ENABLED_OBSOLETE, false)) {
-            Preferences::SetInt(GFX_PREF_CMS_MODE, static_cast<int32_t>(eCMSMode_All));
-        }
-        Preferences::ClearUser(GFX_PREF_CMS_ENABLED_OBSOLETE);
-    }
-}
-
 // default SetupClusterBoundaries, based on Unicode properties;
 // platform subclasses may override if they wish
 void
 gfxPlatform::SetupClusterBoundaries(gfxTextRun *aTextRun, const char16_t *aString)
 {
     if (aTextRun->GetFlags() & gfxTextRunFactory::TEXT_IS_8BIT) {
         // 8-bit text doesn't have clusters.
         // XXX is this true in all languages???
--- a/gfx/thebes/gfxPrefs.cpp
+++ b/gfx/thebes/gfxPrefs.cpp
@@ -8,26 +8,26 @@
 #include "mozilla/Preferences.h"
 #include "MainThreadUtils.h"
 
 using namespace mozilla;
 
 gfxPrefs* gfxPrefs::sInstance = nullptr;
 
 void
-gfxPrefs::Destroy()
+gfxPrefs::DestroySingleton()
 {
   if (sInstance) {
     delete sInstance;
     sInstance = nullptr;
   }
 }
 
 bool
-gfxPrefs::Exists()
+gfxPrefs::SingletonExists()
 {
   return sInstance != nullptr;
 }
 
 gfxPrefs::gfxPrefs()
 {
   // Needs to be created on the main thread.
   MOZ_ASSERT(NS_IsMainThread(), "must be constructed on the main thread");
--- a/gfx/thebes/gfxPrefs.h
+++ b/gfx/thebes/gfxPrefs.h
@@ -5,17 +5,17 @@
 
 #ifndef GFX_PREFS_H
 #define GFX_PREFS_H
 
 #include <stdint.h>
 #include "mozilla/Assertions.h"
 #include "mozilla/TypedEnum.h"
 
-// First time gfxPrefs::One() needs to be called on the main thread,
+// First time gfxPrefs::GetSingleton() needs to be called on the main thread,
 // before any of the methods accessing the values are used, but after
 // the Preferences system has been initialized.
 
 // The static methods to access the preference value are safe to call
 // from any thread after that first call.
 
 // To register a preference, you need to add a line in this file using
 // the DECL_GFX_PREF macro.
@@ -48,17 +48,17 @@
 // Things are a bit more complicated and perhaps even dangerous when
 // going from Once to Live, or indeed setting a preference to be Live
 // in the first place, so be careful.  You need to be ready for the
 // values changing mid execution, and if you're using those preferences
 // in any setup and initialization, you may need to do extra work.
 
 #define DECL_GFX_PREF(Update, Pref, Name, Type, Default)                     \
 public:                                                                       \
-static Type Name() { MOZ_ASSERT(Exists()); return One().mPref##Name.mValue; } \
+static Type Name() { MOZ_ASSERT(SingletonExists()); return GetSingleton().mPref##Name.mValue; } \
 private:                                                                      \
 static const char* Get##Name##PrefName() { return Pref; }                     \
 static Type Get##Name##PrefDefault() { return Default; }                      \
 PrefTemplate<UpdatePolicy::Update, Type, Get##Name##PrefDefault, Get##Name##PrefName> mPref##Name
 
 class gfxPrefs;
 class gfxPrefs MOZ_FINAL
 {
@@ -123,17 +123,17 @@ private:
   DECL_GFX_PREF(Live, "gfx.gralloc.fence-with-readpixels",     GrallocFenceWithReadPixels, bool, false);
   DECL_GFX_PREF(Live, "gfx.layerscope.enabled",                LayerScopeEnabled, bool, false);
   DECL_GFX_PREF(Live, "gfx.layerscope.port",                   LayerScopePort, int32_t, 23456);
   DECL_GFX_PREF(Once, "gfx.work-around-driver-bugs",           WorkAroundDriverBugs, bool, true);
 
   DECL_GFX_PREF(Live, "gl.msaa-level",                         MSAALevel, uint32_t, 2);
 
   DECL_GFX_PREF(Once, "layers.acceleration.disabled",          LayersAccelerationDisabled, bool, false);
-  DECL_GFX_PREF(Live, "layers.acceleration.draw-fps",          LayersDrawFPS, bool, true);
+  DECL_GFX_PREF(Live, "layers.acceleration.draw-fps",          LayersDrawFPS, bool, false);
   DECL_GFX_PREF(Once, "layers.acceleration.force-enabled",     LayersAccelerationForceEnabled, bool, false);
 #ifdef XP_WIN
   // On windows, ignore the preference value, forcing async video to false.
   DECL_GFX_PREF(Skip, "layers.async-video.enabled",            AsyncVideoEnabled, bool, false);
 #else
   DECL_GFX_PREF(Once, "layers.async-video.enabled",            AsyncVideoEnabled, bool, false);
 #endif
   DECL_GFX_PREF(Once, "layers.bufferrotation.enabled",         BufferRotationEnabled, bool, true);
@@ -167,25 +167,25 @@ private:
   DECL_GFX_PREF(Once, "layout.frame_rate",                     LayoutFrameRate, int32_t, -1);
 
   DECL_GFX_PREF(Live, "nglayout.debug.widget_update_flashing", WidgetUpdateFlashing, bool, false);
 
   DECL_GFX_PREF(Once, "webgl.force-layers-readback",           WebGLForceLayersReadback, bool, false);
 
 public:
   // Manage the singleton:
-  static gfxPrefs& One()
+  static gfxPrefs& GetSingleton()
   {
     if (!sInstance) {
       sInstance = new gfxPrefs;
     }
     return *sInstance;
   }
-  static void Destroy();
-  static bool Exists();
+  static void DestroySingleton();
+  static bool SingletonExists();
 
 private:
   static gfxPrefs* sInstance;
 
 private:
   // Creating these to avoid having to include Preferences.h in the .h
   static void PrefAddVarCache(bool*, const char*, bool);
   static void PrefAddVarCache(int32_t*, const char*, int32_t);
--- a/gfx/thebes/moz.build
+++ b/gfx/thebes/moz.build
@@ -194,19 +194,23 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'wi
             'gfxDWriteFontList.cpp',
             'gfxDWriteFonts.cpp',
             'gfxDWriteShaper.cpp',
             'gfxDWriteTextAnalysis.cpp',
         ]
 
 # Are we targeting x86 or x64?  If so, build gfxAlphaRecoverySSE2.cpp.
 if CONFIG['INTEL_ARCHITECTURE']:
-    SOURCES += [
-        'gfxAlphaRecoverySSE2.cpp',
-    ]
+    SOURCES += ['gfxAlphaRecoverySSE2.cpp']
+    # The file uses SSE2 intrinsics, so it needs special compile flags on some
+    # compilers.
+    if CONFIG['GNU_CC']:
+        SOURCES['gfxAlphaRecoverySSE2.cpp'].flags += ['-msse2']
+    if CONFIG['SOLARIS_SUNPRO_CXX']:
+        SOURCES['gfxAlphaRecoverySSE2.cpp'].flags += ['-xarch=sse2', '-xO4']
 
 SOURCES += [
     # Includes mac system header conflicting with point/size,
     # and includes glxXlibSurface.h which drags in Xrender.h
     'gfxASurface.cpp',
     # on X11, gfxDrawable.cpp includes X headers for an old workaround which
     # we could consider removing soon (affects Ubuntus older than 10.04 LTS)
     # which currently prevent it from joining UNIFIED_SOURCES.
deleted file mode 100644
--- a/gfx/ycbcr/Makefile.in
+++ /dev/null
@@ -1,15 +0,0 @@
-include $(topsrcdir)/config/rules.mk
-
-# These files use MMX and SSE2 intrinsics, so they need special compile flags
-# on some compilers.
-ifneq (,$(INTEL_ARCHITECTURE))
-ifdef GNU_CC
-yuv_convert_mmx.$(OBJ_SUFFIX): CXXFLAGS += -mmmx
-yuv_convert_sse2.$(OBJ_SUFFIX): CXXFLAGS += -msse2
-endif
-
-ifdef SOLARIS_SUNPRO_CXX
-yuv_convert_mmx.$(OBJ_SUFFIX): CXXFLAGS += -xarch=mmx -xO4
-yuv_convert_sse2.$(OBJ_SUFFIX): CXXFLAGS += -xarch=sse2 -xO4
-endif
-endif
--- a/gfx/ycbcr/moz.build
+++ b/gfx/ycbcr/moz.build
@@ -16,30 +16,36 @@ UNIFIED_SOURCES += [
     'ycbcr_to_rgb565.cpp',
     'YCbCrUtils.cpp',
     'yuv_convert.cpp',
     'yuv_row_c.cpp',
     'yuv_row_table.cpp',
 ]
 
 if CONFIG['INTEL_ARCHITECTURE']:
-    SOURCES += [
-        'yuv_convert_sse2.cpp',
-    ]
+    # These files use MMX and SSE2 intrinsics, so they need special compile flags
+    # on some compilers.
+    SOURCES += ['yuv_convert_sse2.cpp']
+    if CONFIG['GNU_CC']:
+        SOURCES['yuv_convert_sse2.cpp'].flags += ['-msse2']
+    if CONFIG['SOLARIS_SUNPRO_CXX']:
+        SOURCES['yuv_convert_sse2.cpp'].flags += ['-xarch=sse2', '-xO4']
 
     # MSVC doesn't support MMX when targeting AMD64.
     if CONFIG['_MSC_VER']:
         if CONFIG['OS_TEST'] != 'x86_64':
             SOURCES += [
                 'yuv_convert_mmx.cpp',
             ]
     else:
-        SOURCES += [
-            'yuv_convert_mmx.cpp',
-        ]
+        SOURCES += ['yuv_convert_mmx.cpp']
+        if CONFIG['GNU_CC']:
+            SOURCES['yuv_convert_mmx.cpp'].flags += ['-mmmx']
+        if CONFIG['SOLARIS_SUNPRO_CXX']:
+            SOURCES['yuv_convert_mmx.cpp'].flags += ['-xarch=mmx', '-xO4']
 
 if CONFIG['_MSC_VER']:
     if CONFIG['OS_TEST'] == 'x86_64':
         if CONFIG['_MSC_VER'] == '1400':
             # VC8 doesn't support some SSE2 built-in functions
             SOURCES += [
                 'yuv_row_win.cpp',
             ]
--- a/intl/strres/src/nsStringBundle.cpp
+++ b/intl/strres/src/nsStringBundle.cpp
@@ -713,31 +713,19 @@ nsStringBundleService::CreateExtensibleB
 nsresult
 nsStringBundleService::FormatWithBundle(nsIStringBundle* bundle, nsresult aStatus,
                                         uint32_t argCount, char16_t** argArray,
                                         char16_t* *result)
 {
   nsresult rv;
   nsXPIDLCString key;
 
-  // then find a key into the string bundle for that particular error:
-  rv = mErrorService->GetErrorStringBundleKey(aStatus, getter_Copies(key));
-
-  // first try looking up the error message with the string key:
-  if (NS_SUCCEEDED(rv)) {
-    rv = bundle->FormatStringFromName(NS_ConvertASCIItoUTF16(key).get(),
-                                      (const char16_t**)argArray, 
-                                      argCount, result);
-  }
-
-  // if the string key fails, try looking up the error message with the int key:
-  if (NS_FAILED(rv)) {
-    uint16_t code = NS_ERROR_GET_CODE(aStatus);
-    rv = bundle->FormatStringFromID(code, (const char16_t**)argArray, argCount, result);
-  }
+  // try looking up the error message with the int key:
+  uint16_t code = NS_ERROR_GET_CODE(aStatus);
+  rv = bundle->FormatStringFromID(code, (const char16_t**)argArray, argCount, result);
 
   // If the int key fails, try looking up the default error message. E.g. print:
   //   An unknown error has occurred (0x804B0003).
   if (NS_FAILED(rv)) {
     nsAutoString statusStr;
     statusStr.AppendInt(static_cast<uint32_t>(aStatus), 16);
     const char16_t* otherArgArray[1];
     otherArgArray[0] = statusStr.get();
deleted file mode 100644
--- a/intl/uconv/src/Makefile.in
+++ /dev/null
@@ -1,18 +0,0 @@
-# vim:set noet ts=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/.
-
-include $(topsrcdir)/config/rules.mk
-
-ifneq (,$(INTEL_ARCHITECTURE))
-# nsUTF8ToUnicodeSSE2.cpp uses SSE2 intrinsics, so we need to pass -msse2 if
-# we're using gcc. (See bug 585538 comment 12.)
-ifdef GNU_CC
-nsUTF8ToUnicodeSSE2.$(OBJ_SUFFIX): CXXFLAGS+=-msse2
-endif
-
-ifdef SOLARIS_SUNPRO_CXX
-nsUTF8ToUnicodeSSE2.$(OBJ_SUFFIX): OS_CXXFLAGS += -xarch=sse2 -xO4
-endif
-endif
--- a/intl/uconv/src/moz.build
+++ b/intl/uconv/src/moz.build
@@ -196,19 +196,23 @@ UNIFIED_SOURCES += [
     '../util/nsUnicodeDecodeHelper.cpp',
     '../util/nsUnicodeEncodeHelper.cpp',
     '../util/ugen.c',
     '../util/umap.c',
     '../util/uscan.c',
 ]
 
 if CONFIG['INTEL_ARCHITECTURE']:
-    SOURCES += [
-        'nsUTF8ToUnicodeSSE2.cpp',
-    ]
+    SOURCES += ['nsUTF8ToUnicodeSSE2.cpp']
+    if CONFIG['GNU_CC']:
+        # nsUTF8ToUnicodeSSE2.cpp uses SSE2 intrinsics, so we need to pass -msse2 if
+        # we're using gcc. (See bug 585538 comment 12.)
+        SOURCES['nsUTF8ToUnicodeSSE2.cpp'].flags += ['-msse2']
+    if CONFIG['SOLARIS_SUNPRO_CXX']:
+        SOURCES['nsUTF8ToUnicodeSSE2.cpp'].flags += ['-xarch=sse2', '-xO4']
 
 MSVC_ENABLE_PGO = True
 
 LOCAL_INCLUDES += [
     '../ucvcn',
     '../ucvibm',
     '../ucvja',
     '../ucvko',
--- a/js/src/Makefile.in
+++ b/js/src/Makefile.in
@@ -355,20 +355,16 @@ ifdef HAVE_DTRACE
 	    -e '/const/!s/char \*/const char */g' \
 	    javascript-trace.h.in > javascript-trace.h
 
 # We can't automatically generate dependencies on auto-generated headers;
 # we have to list them explicitly.
 $(addsuffix .$(OBJ_SUFFIX),Probes jsinterp jsobj): $(CURDIR)/javascript-trace.h
 endif
 
-ifdef HAVE_LINUX_PERF_EVENT_H
-pm_linux.$(OBJ_SUFFIX): CXXFLAGS += $(LINUX_HEADERS_INCLUDES)
-endif
-
 # Prepare self-hosted JS code for embedding
 export:: selfhosting
 selfhosting:: selfhosted.out.h
 
 selfhosting_srcs := \
   $(srcdir)/builtin/Utilities.js \
   $(srcdir)/builtin/Array.js \
   $(srcdir)/builtin/Date.js \
--- a/js/src/builtin/Array.js
+++ b/js/src/builtin/Array.js
@@ -885,16 +885,23 @@ function ArrayScatterPar(targets, defaul
         x = collide(x, buffer[t]);
 
       UnsafePutElements(buffer, t, x, conflicts, t, true);
     }
 
     return buffer;
   }
 
+  function collide(elem1, elem2) {
+    if (conflictFunc === undefined)
+      ThrowError(JSMSG_PAR_ARRAY_SCATTER_CONFLICT);
+
+    return conflictFunc(elem1, elem2);
+  }
+
   function checkTarget(i, t) {
     if (TO_INT32(t) !== t)
       ThrowError(JSMSG_PAR_ARRAY_SCATTER_BAD_TARGET, i);
 
     if (t < 0 || t >= length)
       ThrowError(JSMSG_PAR_ARRAY_SCATTER_BOUNDS);
 
     // It's not enough to return t, as -0 | 0 === -0.
--- a/js/src/configure.in
+++ b/js/src/configure.in
@@ -4021,29 +4021,17 @@ AC_SUBST(BIN_SUFFIX)
 AC_SUBST(ASM_SUFFIX)
 AC_SUBST(IMPORT_LIB_SUFFIX)
 AC_SUBST(USE_N32)
 AC_SUBST(CC_VERSION)
 AC_SUBST(CXX_VERSION)
 AC_SUBST(MSMANIFEST_TOOL)
 AC_SUBST(MOZ_LINKER)
 
-AC_MSG_CHECKING([for posix_fallocate])
-AC_TRY_LINK([#define _XOPEN_SOURCE 600
-  #include <fcntl.h>],
-                 [posix_fallocate(0, 0, 0);],
-                 [ac_cv___posix_fallocate=true],
-                 [ac_cv___posix_fallocate=false])
-
-if test "$ac_cv___posix_fallocate" = true ; then
-  AC_DEFINE(HAVE_POSIX_FALLOCATE)
-  AC_MSG_RESULT(yes)
-else
-  AC_MSG_RESULT(no)
-fi
+AC_CHECK_FUNCS(posix_fadvise posix_fallocate)
 
 dnl Check for missing components
 if test "$COMPILE_ENVIRONMENT"; then
 if test "$MOZ_X11"; then
     dnl ====================================================
     dnl = Check if X headers exist
     dnl ====================================================
     _SAVE_CFLAGS=$CFLAGS
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/asm.js/testBug978714.js
@@ -0,0 +1,9 @@
+if (!getBuildConfiguration().parallelJS)
+    quit();
+
+var y = Array.buildPar(9, function() {});
+Array.prototype.every.call(y, (function() {
+    "use asm";
+    function f() {}
+    return f
+}))
--- a/js/src/jit-test/tests/ion/inlining/TypedObject-ObjectIsTypeDescr-multi.js
+++ b/js/src/jit-test/tests/ion/inlining/TypedObject-ObjectIsTypeDescr-multi.js
@@ -13,16 +13,19 @@
  * Load this into the js shell with IONFLAGS=logs, then exit and run
  * iongraph.  You're looking for a smallish function within the
  * "self-hosted" domain.  Look for a call to ObjectIsTypeDescr far
  * down in the graph for pass00, with a call to DescrToSource in a
  * subsequent block (all of this is at the mercy of the way the code
  * is currently written).
  */
 
+if (!this.TypedObject)
+  quit();
+
 var T = TypedObject;
 var ST1 = new T.StructType({x:T.int32});
 var ST2 = new T.StructType({x:T.float64});
 
 function check(v) {
     return v.toSource();
 }
 
--- a/js/src/jit-test/tests/ion/inlining/TypedObject-ObjectIsTypeDescr-unknown.js
+++ b/js/src/jit-test/tests/ion/inlining/TypedObject-ObjectIsTypeDescr-unknown.js
@@ -13,16 +13,19 @@
  * Load this into the js shell with IONFLAGS=logs, then exit and run
  * iongraph.  You're looking for a smallish function within the
  * "self-hosted" domain.  Look for a call to ObjectIsTypeDescr far
  * down in the graph for pass00, with a call to DescrToSource in a
  * subsequent block (all of this is at the mercy of the way the code
  * is currently written).
  */
 
+if (!this.TypedObject)
+  quit();
+
 var T = TypedObject;
 var ST = new T.StructType({x:T.int32});
 
 function check(v) {
     return v.toSource();
 }
 
 function test() {
--- a/js/src/jit-test/tests/ion/inlining/TypedObject-ObjectIsTypeDescr-wrong-multi.js
+++ b/js/src/jit-test/tests/ion/inlining/TypedObject-ObjectIsTypeDescr-wrong-multi.js
@@ -13,16 +13,19 @@
  * Load this into the js shell with IONFLAGS=logs, then exit and run
  * iongraph.  You're looking for a smallish function within the
  * "self-hosted" domain.  Look for a call to ObjectIsTypeDescr far
  * down in the graph for pass00, with a call to DescrToSource in a
  * subsequent block (all of this is at the mercy of the way the code
  * is currently written).
  */
 
+if (!this.TypedObject)
+  quit();
+
 var T = TypedObject;
 var ST = new T.StructType({x:T.int32});
 
 function check(v) {
     return v.toSource();
 }
 
 function test() {
--- a/js/src/jit-test/tests/ion/inlining/TypedObject-ObjectIsTypeDescr-wrong.js
+++ b/js/src/jit-test/tests/ion/inlining/TypedObject-ObjectIsTypeDescr-wrong.js
@@ -13,16 +13,19 @@
  * Load this into the js shell with IONFLAGS=logs, then exit and run
  * iongraph.  You're looking for a smallish function within the
  * "self-hosted" domain.  Look for a call to ObjectIsTypeDescr far
  * down in the graph for pass00, with a call to DescrToSource in a
  * subsequent block (all of this is at the mercy of the way the code
  * is currently written).
  */
 
+if (!this.TypedObject)
+  quit();
+
 var T = TypedObject;
 var ST = new T.StructType({x:T.int32});
 
 function check(v) {
     return v.toSource();
 }
 
 function test() {
--- a/js/src/jit-test/tests/ion/inlining/TypedObject-ObjectIsTypeDescr.js
+++ b/js/src/jit-test/tests/ion/inlining/TypedObject-ObjectIsTypeDescr.js
@@ -13,16 +13,19 @@
  * Load this into the js shell with IONFLAGS=logs, then exit and run
  * iongraph.  You're looking for a smallish function within the
  * "self-hosted" domain.  Look for a call to ObjectIsTypeDescr far
  * down in the graph for pass00, with a call to DescrToSource in a
  * subsequent block (all of this is at the mercy of the way the code
  * is currently written).
  */
 
+if (!this.TypedObject)
+  quit();
+
 var T = TypedObject;
 var ST = new T.StructType({x:T.int32});
 
 function check(v) {
     return v.toSource();
 }
 
 function test() {
--- a/js/src/jit-test/tests/ion/inlining/TypedObject-storage-opaque.js
+++ b/js/src/jit-test/tests/ion/inlining/TypedObject-storage-opaque.js
@@ -11,16 +11,19 @@
  * ObjectIsTransparentTypedObject resolves to false.
  *
  * Load this into the js shell with IONFLAGS=logs, then exit and run
  * iongraph.  func01 will likely be the one we want (look for calls to
  * ObjectIsOpaqueTypedObject and ObjectIsTransparentTypedObject in the
  * graph for pass00).
  */
 
+if (!this.TypedObject)
+  quit();
+
 var T = TypedObject;
 
 function check(v) {
     return T.storage(v);
 }
 
 function test() {
     var AT = new T.ArrayType(T.Any,10);
--- a/js/src/jit-test/tests/ion/inlining/TypedObject-storage-transparent.js
+++ b/js/src/jit-test/tests/ion/inlining/TypedObject-storage-transparent.js
@@ -11,16 +11,19 @@
  * ObjectIsTransparentTypedObject resolves to true.
  *
  * Load this into the js shell with IONFLAGS=logs, then exit and run
  * iongraph.  func01 will likely be the one we want (look for calls to
  * ObjectIsOpaqueTypedObject and ObjectIsTransparentTypedObject in the
  * graph for pass00).
  */
 
+if (!this.TypedObject)
+  quit();
+
 var T = TypedObject;
 
 function check(v) {
     return T.storage(v);
 }
 
 function test() {
     var AT = new T.ArrayType(T.int32,10);
--- a/js/src/jit-test/tests/ion/inlining/TypedObject-storage-unknown.js
+++ b/js/src/jit-test/tests/ion/inlining/TypedObject-storage-unknown.js
@@ -12,16 +12,19 @@
  * "HasClass" primitive.
  *
  * Load this into the js shell with IONFLAGS=logs, then exit and run
  * iongraph.  func01 will likely be the one we want (look for calls to
  * ObjectIsOpaqueTypedObject and ObjectIsTransparentTypedObject in the
  * graph for pass00).
  */
 
+if (!this.TypedObject)
+  quit();
+
 var T = TypedObject;
 
 function check(v) {
     return T.storage(v);
 }
 
 function test() {
     var AT = new T.ArrayType(T.int32,10);
--- a/js/src/jit-test/tests/ion/inlining/TypedObject-storage-wrong.js
+++ b/js/src/jit-test/tests/ion/inlining/TypedObject-storage-wrong.js
@@ -11,16 +11,19 @@
  * resolve to false.
  *
  * Load this into the js shell with IONFLAGS=logs, then exit and run
  * iongraph.  func01 will likely be the one we want (look for calls to
  * ObjectIsOpaqueTypedObject and ObjectIsTransparentTypedObject in the
  * graph for pass00).
  */
 
+if (!this.TypedObject)
+  quit();
+
 var T = TypedObject;
 
 function check(v) {
     return T.storage(v);
 }
 
 function test() {
     var v = new Object;         // Not actually a typed object
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/parallel/bug977900.js
@@ -0,0 +1,5 @@
+if (!getBuildConfiguration().parallelJS)
+    quit();
+
+function chooseMax(a, b) { return a>b?a:b;};
+var a = [1,2].scatterPar([0,0], -1, chooseMax);
--- a/js/src/jit/AsmJS.cpp
+++ b/js/src/jit/AsmJS.cpp
@@ -752,93 +752,16 @@ TypedArrayLoadType(ArrayBufferView::View
     MOZ_ASSUME_UNREACHABLE("Unexpected array type");
 }
 
 enum NeedsBoundsCheck {
     NO_BOUNDS_CHECK,
     NEEDS_BOUNDS_CHECK
 };
 
-/*****************************************************************************/
-
-// The Asm.js heap length is constrained by the x64 backend heap access scheme
-// to be a multiple of the page size which is 4096 bytes, and also constrained
-// by the limits of ARM backends 'cmp immediate' instruction which supports a
-// complex range for the immediate argument.
-//
-// ARMv7 mode supports the following immediate constants, and the Thumb T2
-// instruction encoding also supports the subset of immediate constants used.
-//  abcdefgh 00000000 00000000 00000000
-//  00abcdef gh000000 00000000 00000000
-//  0000abcd efgh0000 00000000 00000000
-//  000000ab cdefgh00 00000000 00000000
-//  00000000 abcdefgh 00000000 00000000
-//  00000000 00abcdef gh000000 00000000
-//  00000000 0000abcd efgh0000 00000000
-//  ...
-//
-// The 4096 page size constraint restricts the length to:
-//  xxxxxxxx xxxxxxxx xxxx0000 00000000
-//
-// Intersecting all the above constraints gives:
-//  Heap length 0x40000000 to 0xff000000 quanta 0x01000000
-//  Heap length 0x10000000 to 0x3fc00000 quanta 0x00400000
-//  Heap length 0x04000000 to 0x0ff00000 quanta 0x00100000
-//  Heap length 0x01000000 to 0x03fc0000 quanta 0x00040000
-//  Heap length 0x00400000 to 0x00ff0000 quanta 0x00010000
-//  Heap length 0x00100000 to 0x003fc000 quanta 0x00004000
-//  Heap length 0x00001000 to 0x000ff000 quanta 0x00001000
-//
-uint32_t
-js::RoundUpToNextValidAsmJSHeapLength(uint32_t length)
-{
-    if (length < 0x00001000u) // Minimum length is the pages size of 4096.
-        return 0x1000u;
-    if (length < 0x00100000u) // < 1M quanta 4K
-        return (length + 0x00000fff) & ~0x00000fff;
-    if (length < 0x00400000u) // < 4M quanta 16K
-        return (length + 0x00003fff) & ~0x00003fff;
-    if (length < 0x01000000u) // < 16M quanta 64K
-        return (length + 0x0000ffff) & ~0x0000ffff;
-    if (length < 0x04000000u) // < 64M quanta 256K
-        return (length + 0x0003ffff) & ~0x0003ffff;
-    if (length < 0x10000000u) // < 256M quanta 1M
-        return (length + 0x000fffff) & ~0x000fffff;
-    if (length < 0x40000000u) // < 1024M quanta 4M
-        return (length + 0x003fffff) & ~0x003fffff;
-    // < 4096M quanta 16M.  Note zero is returned if over 0xff000000 but such
-    // lengths are not currently valid.
-    JS_ASSERT(length <= 0xff000000);
-    return (length + 0x00ffffff) & ~0x00ffffff;
-}
-
-bool
-js::IsValidAsmJSHeapLength(uint32_t length)
-{
-    if (length <  AsmJSAllocationGranularity)
-        return false;
-    if (length <= 0x00100000u)
-        return (length & 0x00000fff) == 0;
-    if (length <= 0x00400000u)
-        return (length & 0x00003fff) == 0;
-    if (length <= 0x01000000u)
-        return (length & 0x0000ffff) == 0;
-    if (length <= 0x04000000u)
-        return (length & 0x0003ffff) == 0;
-    if (length <= 0x10000000u)
-        return (length & 0x000fffff) == 0;
-    if (length <= 0x40000000u)
-        return (length & 0x003fffff) == 0;
-    if (length <= 0xff000000u)
-        return (length & 0x00ffffff) == 0;
-    return false;
-}
-
-/*****************************************************************************/
-
 namespace {
 
 typedef js::Vector<PropertyName*,1> LabelVector;
 typedef js::Vector<MBasicBlock*,8> BlockVector;
 
 // ModuleCompiler encapsulates the compilation of an entire asm.js module. Over
 // the course of an ModuleCompiler object's lifetime, many FunctionCompiler
 // objects will be created and destroyed in sequence, one for each function in
--- a/js/src/jit/AsmJS.h
+++ b/js/src/jit/AsmJS.h
@@ -75,23 +75,16 @@ class AsmJSActivation
 };
 
 // The assumed page size; dynamically checked in CompileAsmJS.
 const size_t AsmJSPageSize = 4096;
 
 // The asm.js spec requires that the ArrayBuffer's byteLength be a multiple of 4096.
 static const size_t AsmJSAllocationGranularity = 4096;
 
-// These functions define the valid heap lengths.
-extern uint32_t
-RoundUpToNextValidAsmJSHeapLength(uint32_t length);
-
-extern bool
-IsValidAsmJSHeapLength(uint32_t length);
-
 #ifdef JS_CODEGEN_X64
 // On x64, the internal ArrayBuffer data array is inflated to 4GiB (only the
 // byteLength portion of which is accessible) so that out-of-bounds accesses
 // (made using a uint32 index) are guaranteed to raise a SIGSEGV.
 static const size_t AsmJSBufferProtectedSize = 4 * 1024ULL * 1024ULL * 1024ULL;
 
 // To avoid dynamically checking bounds on each load/store, asm.js code relies
 // on the SIGSEGV handler in AsmJSSignalHandlers.cpp. However, this only works
@@ -130,11 +123,84 @@ IsAsmJSCompilationAvailable(JSContext *c
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     args.rval().set(BooleanValue(false));
     return true;
 }
 
 #endif // JS_ION
 
+// The Asm.js heap length is constrained by the x64 backend heap access scheme
+// to be a multiple of the page size which is 4096 bytes, and also constrained
+// by the limits of ARM backends 'cmp immediate' instruction which supports a
+// complex range for the immediate argument.
+//
+// ARMv7 mode supports the following immediate constants, and the Thumb T2
+// instruction encoding also supports the subset of immediate constants used.
+//  abcdefgh 00000000 00000000 00000000
+//  00abcdef gh000000 00000000 00000000
+//  0000abcd efgh0000 00000000 00000000
+//  000000ab cdefgh00 00000000 00000000
+//  00000000 abcdefgh 00000000 00000000
+//  00000000 00abcdef gh000000 00000000
+//  00000000 0000abcd efgh0000 00000000
+//  ...
+//
+// The 4096 page size constraint restricts the length to:
+//  xxxxxxxx xxxxxxxx xxxx0000 00000000
+//
+// Intersecting all the above constraints gives:
+//  Heap length 0x40000000 to 0xff000000 quanta 0x01000000
+//  Heap length 0x10000000 to 0x3fc00000 quanta 0x00400000
+//  Heap length 0x04000000 to 0x0ff00000 quanta 0x00100000
+//  Heap length 0x01000000 to 0x03fc0000 quanta 0x00040000
+//  Heap length 0x00400000 to 0x00ff0000 quanta 0x00010000
+//  Heap length 0x00100000 to 0x003fc000 quanta 0x00004000
+//  Heap length 0x00001000 to 0x000ff000 quanta 0x00001000
+//
+inline uint32_t
+RoundUpToNextValidAsmJSHeapLength(uint32_t length)
+{
+    if (length < 0x00001000u) // Minimum length is the pages size of 4096.
+        return 0x1000u;
+    if (length < 0x00100000u) // < 1M quanta 4K
+        return (length + 0x00000fff) & ~0x00000fff;
+    if (length < 0x00400000u) // < 4M quanta 16K
+        return (length + 0x00003fff) & ~0x00003fff;
+    if (length < 0x01000000u) // < 16M quanta 64K
+        return (length + 0x0000ffff) & ~0x0000ffff;
+    if (length < 0x04000000u) // < 64M quanta 256K
+        return (length + 0x0003ffff) & ~0x0003ffff;
+    if (length < 0x10000000u) // < 256M quanta 1M
+        return (length + 0x000fffff) & ~0x000fffff;
+    if (length < 0x40000000u) // < 1024M quanta 4M
+        return (length + 0x003fffff) & ~0x003fffff;
+    // < 4096M quanta 16M.  Note zero is returned if over 0xff000000 but such
+    // lengths are not currently valid.
+    JS_ASSERT(length <= 0xff000000);
+    return (length + 0x00ffffff) & ~0x00ffffff;
+}
+
+inline bool
+IsValidAsmJSHeapLength(uint32_t length)
+{
+    if (length <  AsmJSAllocationGranularity)
+        return false;
+    if (length <= 0x00100000u)
+        return (length & 0x00000fff) == 0;
+    if (length <= 0x00400000u)
+        return (length & 0x00003fff) == 0;
+    if (length <= 0x01000000u)
+        return (length & 0x0000ffff) == 0;
+    if (length <= 0x04000000u)
+        return (length & 0x0003ffff) == 0;
+    if (length <= 0x10000000u)
+        return (length & 0x000fffff) == 0;
+    if (length <= 0x40000000u)
+        return (length & 0x003fffff) == 0;
+    if (length <= 0xff000000u)
+        return (length & 0x00ffffff) == 0;
+    return false;
+}
+
 } // namespace js
 
 #endif // jit_AsmJS_h
--- a/js/src/jit/AsmJSModule.cpp
+++ b/js/src/jit/AsmJSModule.cpp
@@ -342,17 +342,18 @@ AsmJSModule::AsmJSModule(ScriptSource *s
   : globalArgumentName_(nullptr),
     importArgumentName_(nullptr),
     bufferArgumentName_(nullptr),
     code_(nullptr),
     operationCallbackExit_(nullptr),
     dynamicallyLinked_(false),
     loadedFromCache_(false),
     charsBegin_(charsBegin),
-    scriptSource_(scriptSource)
+    scriptSource_(scriptSource),
+    codeIsProtected_(false)
 {
     mozilla::PodZero(&pod);
     scriptSource_->incref();
     pod.minHeapLength_ = AsmJSAllocationGranularity;
 }
 
 AsmJSModule::~AsmJSModule()
 {
--- a/js/src/jscntxtinlines.h
+++ b/js/src/jscntxtinlines.h
@@ -24,17 +24,26 @@ namespace js {
 #ifdef JS_CRASH_DIAGNOSTICS
 class CompartmentChecker
 {
     JSCompartment *compartment;
 
   public:
     explicit CompartmentChecker(ExclusiveContext *cx)
       : compartment(cx->compartment())
-    {}
+    {
+#ifdef DEBUG
+        // In debug builds, make sure the embedder passed the cx it claimed it
+        // was going to use.
+        JSContext *activeContext = nullptr;
+        if (cx->isJSContext())
+            activeContext = cx->asJSContext()->runtime()->activeContext;
+        JS_ASSERT_IF(activeContext, cx == activeContext);
+#endif
+    }
 
     /*
      * Set a breakpoint here (break js::CompartmentChecker::fail) to debug
      * compartment mismatches.
      */
     static void fail(JSCompartment *c1, JSCompartment *c2) {
         printf("*** Compartment mismatch %p vs. %p\n", (void *) c1, (void *) c2);
         MOZ_CRASH();
@@ -363,17 +372,19 @@ ExclusiveContext::typeLifoAlloc()
 }  /* namespace js */
 
 inline void
 JSContext::setPendingException(js::Value v)
 {
     JS_ASSERT(!IsPoisonedValue(v));
     this->throwing = true;
     this->unwrappedException_ = v;
-    js::assertSameCompartment(this, v);
+    // We don't use assertSameCompartment here to allow
+    // js::SetPendingExceptionCrossContext to work.
+    JS_ASSERT_IF(v.isObject(), v.toObject().compartment() == compartment());
 }
 
 inline void
 JSContext::setDefaultCompartmentObject(JSObject *obj)
 {
     JS_ASSERT(!options().noDefaultCompartmentObject());
     defaultCompartmentObject_ = obj;
 }
--- a/js/src/jsfriendapi.cpp
+++ b/js/src/jsfriendapi.cpp
@@ -389,16 +389,22 @@ js::GetObjectParentMaybeScope(JSObject *
 
 JS_FRIEND_API(JSObject *)
 js::GetGlobalForObjectCrossCompartment(JSObject *obj)
 {
     return &obj->global();
 }
 
 JS_FRIEND_API(void)
+js::SetPendingExceptionCrossContext(JSContext *cx, JS::HandleValue v)
+{
+    cx->setPendingException(v);
+}
+
+JS_FRIEND_API(void)
 js::AssertSameCompartment(JSContext *cx, JSObject *obj)
 {
     assertSameCompartment(cx, obj);
 }
 
 #ifdef DEBUG
 JS_FRIEND_API(void)
 js::AssertSameCompartment(JSObject *objA, JSObject *objB)
@@ -1145,16 +1151,24 @@ js::DefaultJSContext(JSRuntime *rt)
 }
 
 JS_FRIEND_API(void)
 js::SetDefaultJSContextCallback(JSRuntime *rt, DefaultJSContextCallback cb)
 {
     rt->defaultJSContextCallback = cb;
 }
 
+#ifdef DEBUG
+JS_FRIEND_API(void)
+js::Debug_SetActiveJSContext(JSRuntime *rt, JSContext *cx)
+{
+    rt->activeContext = cx;
+}
+#endif
+
 JS_FRIEND_API(void)
 js::SetCTypesActivityCallback(JSRuntime *rt, CTypesActivityCallback cb)
 {
     rt->ctypesActivityCallback = cb;
 }
 
 js::AutoCTypesActivityCallback::AutoCTypesActivityCallback(JSContext *cx,
                                                            js::CTypesActivityType beginType,
--- a/js/src/jsfriendapi.h
+++ b/js/src/jsfriendapi.h
@@ -656,16 +656,21 @@ GetObjectCompartment(JSObject *obj)
 }
 
 JS_FRIEND_API(JSObject *)
 GetObjectParentMaybeScope(JSObject *obj);
 
 JS_FRIEND_API(JSObject *)
 GetGlobalForObjectCrossCompartment(JSObject *obj);
 
+// Sidestep the activeContext checking implicitly performed in
+// JS_SetPendingException.
+JS_FRIEND_API(void)
+SetPendingExceptionCrossContext(JSContext *cx, JS::HandleValue v);
+
 JS_FRIEND_API(void)
 AssertSameCompartment(JSContext *cx, JSObject *obj);
 
 #ifdef JS_DEBUG
 JS_FRIEND_API(void)
 AssertSameCompartment(JSObject *objA, JSObject *objB);
 #else
 inline void AssertSameCompartment(JSObject *objA, JSObject *objB) {}
@@ -1946,16 +1951,31 @@ extern JS_FRIEND_API(JSContext *)
 DefaultJSContext(JSRuntime *rt);
 
 typedef JSContext*
 (* DefaultJSContextCallback)(JSRuntime *rt);
 
 JS_FRIEND_API(void)
 SetDefaultJSContextCallback(JSRuntime *rt, DefaultJSContextCallback cb);
 
+/*
+ * To help embedders enforce their invariants, we allow them to specify in
+ * advance which JSContext should be passed to JSAPI calls. If this is set
+ * to a non-null value, the assertSameCompartment machinery does double-
+ * duty (in debug builds) to verify that it matches the cx being used.
+ */
+#ifdef DEBUG
+JS_FRIEND_API(void)
+Debug_SetActiveJSContext(JSRuntime *rt, JSContext *cx);
+#else
+inline void
+Debug_SetActiveJSContext(JSRuntime *rt, JSContext *cx) {};
+#endif
+
+
 enum CTypesActivityType {
     CTYPES_CALL_BEGIN,
     CTYPES_CALL_END,
     CTYPES_CALLBACK_BEGIN,
     CTYPES_CALLBACK_END
 };
 
 typedef void
--- a/js/src/moz.build
+++ b/js/src/moz.build
@@ -385,16 +385,17 @@ if CONFIG['MOZ_VTUNE']:
     SOURCES += [
         'vtune/jitprofiling.c'
     ]
 
 if CONFIG['HAVE_LINUX_PERF_EVENT_H']:
     SOURCES += [
         'perf/pm_linux.cpp'
     ]
+    SOURCES['perf/pm_linux.cpp'].flags += [CONFIG['LINUX_HEADERS_INCLUDES']]
 else:
     SOURCES += [
         'perf/pm_stub.cpp'
     ]
 
 MSVC_ENABLE_PGO = True
 
 HOST_SOURCES += [
--- a/js/src/vm/Runtime.cpp
+++ b/js/src/vm/Runtime.cpp
@@ -156,16 +156,19 @@ JSRuntime::JSRuntime(JSRuntime *parentRu
     activityCallback(nullptr),
     activityCallbackArg(nullptr),
 #ifdef JS_THREADSAFE
     requestDepth(0),
 # ifdef DEBUG
     checkRequestDepth(0),
 # endif
 #endif
+#ifdef DEBUG
+    activeContext(nullptr),
+#endif
     gcInitialized(false),
     gcSystemAvailableChunkListHead(nullptr),
     gcUserAvailableChunkListHead(nullptr),
     gcBytes(0),
     gcMaxBytes(0),
     gcMaxMallocBytes(0),
     gcNumArenasFreeCommitted(0),
     gcMarker(this),
--- a/js/src/vm/Runtime.h
+++ b/js/src/vm/Runtime.h
@@ -961,16 +961,26 @@ struct JSRuntime : public JS::shadow::Ru
     /* The request depth for this thread. */
     unsigned            requestDepth;
 
 # ifdef DEBUG
     unsigned            checkRequestDepth;
 # endif
 #endif
 
+#ifdef DEBUG
+    /*
+     * To help embedders enforce their invariants, we allow them to specify in
+     * advance which JSContext should be passed to JSAPI calls. If this is set
+     * to a non-null value, the assertSameCompartment machinery does double-
+     * duty (in debug builds) to verify that it matches the cx being used.
+     */
+    JSContext          *activeContext;
+#endif
+
     /* Garbage collector state, used by jsgc.c. */
 
     /* Garbase collector state has been sucessfully initialized. */
     bool                gcInitialized;
 
     /*
      * Set of all GC chunks with at least one allocated thing. The
      * conservative GC uses it to quickly check if a possible GC thing points
--- a/js/src/vm/SharedArrayObject.cpp
+++ b/js/src/vm/SharedArrayObject.cpp
@@ -80,32 +80,28 @@ SharedArrayRawBuffer::New(uint32_t lengt
     void *p = MapMemory(AsmJSMappedSize, false);
     if (!p)
         return nullptr;
 
     if (!MarkValidRegion(p, AsmJSPageSize + length)) {
         UnmapMemory(p, AsmJSMappedSize);
         return nullptr;
     }
+#else
+    uint32_t allocSize = length + AsmJSPageSize;
+    if (allocSize <= length)
+        return nullptr;
 
+    void *p = MapMemory(allocSize, true);
+    if (!p)
+        return nullptr;
+#endif
     uint8_t *buffer = reinterpret_cast<uint8_t*>(p) + AsmJSPageSize;
     uint8_t *base = buffer - sizeof(SharedArrayRawBuffer);
     return new (base) SharedArrayRawBuffer(buffer, length);
-#else
-    uint32_t allocSize = sizeof(SharedArrayRawBuffer) + length;
-    if (allocSize <= length)
-        return nullptr;
-
-    void *base = MapMemory(allocSize, true);
-    if (!base)
-        return nullptr;
-
-    uint8_t *buffer = reinterpret_cast<uint8_t*>(base) + sizeof(SharedArrayRawBuffer);
-    return new (base) SharedArrayRawBuffer(buffer, length);
-#endif
 }
 
 void
 SharedArrayRawBuffer::addReference()
 {
     JS_ASSERT(this->refcount > 0);
     ++this->refcount; // Atomic.
 }
@@ -113,23 +109,22 @@ SharedArrayRawBuffer::addReference()
 void
 SharedArrayRawBuffer::dropReference()
 {
     // Drop the reference to the buffer.
     uint32_t refcount = --this->refcount; // Atomic.
 
     // If this was the final reference, release the buffer.
     if (refcount == 0) {
-#ifdef JS_CPU_X64
         uint8_t *p = this->dataPointer() - AsmJSPageSize;
         JS_ASSERT(uintptr_t(p) % AsmJSPageSize == 0);
+#ifdef JS_CPU_X64
         UnmapMemory(p, AsmJSMappedSize);
 #else
-        uint8_t *p = (uint8_t *)this;
-        UnmapMemory(p, this->length);
+        UnmapMemory(p, this->length + AsmJSPageSize);
 #endif
     }
 }
 
 /*
  * SharedArrayBufferObject
  */
 bool
--- a/js/xpconnect/loader/mozJSComponentLoader.h
+++ b/js/xpconnect/loader/mozJSComponentLoader.h
@@ -9,16 +9,17 @@
 
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/ModuleLoader.h"
 #include "nsISupports.h"
 #include "nsIObserver.h"
 #include "nsIURI.h"
 #include "xpcIJSModuleLoader.h"
 #include "nsClassHashtable.h"
+#include "nsCxPusher.h"
 #include "nsDataHashtable.h"
 #include "jsapi.h"
 
 #include "xpcIJSGetFactory.h"
 
 class nsIFile;
 class nsIJSRuntimeService;
 class nsIPrincipal;
@@ -110,24 +111,23 @@ class mozJSComponentLoader : public mozi
         ~ModuleEntry() {
             Clear();
         }
 
         void Clear() {
             getfactoryobj = nullptr;
 
             if (obj) {
-                JSAutoRequest ar(sSelf->mContext);
-
-                JSAutoCompartment ac(sSelf->mContext, obj);
+                mozilla::AutoJSContext cx;
+                JSAutoCompartment ac(cx, obj);
 
-                JS_SetAllNonReservedSlotsToUndefined(sSelf->mContext, obj);
-                JS_RemoveObjectRoot(sSelf->mContext, &obj);
+                JS_SetAllNonReservedSlotsToUndefined(cx, obj);
+                JS_RemoveObjectRoot(cx, &obj);
                 if (thisObjectKey)
-                    JS_RemoveScriptRoot(sSelf->mContext, &thisObjectKey);
+                    JS_RemoveScriptRoot(cx, &thisObjectKey);
             }
 
             if (location)
                 NS_Free(location);
 
             obj = nullptr;
             thisObjectKey = nullptr;
             location = nullptr;
--- a/js/xpconnect/src/Sandbox.cpp
+++ b/js/xpconnect/src/Sandbox.cpp
@@ -505,16 +505,17 @@ EvalInWindow(JSContext *cx, const nsAStr
     nsCString filename;
     unsigned lineNo;
     if (!GetFilenameAndLineNumber(cx, filename, lineNo)) {
         // Default values for non-scripted callers.
         filename.Assign("Unknown");
         lineNo = 0;
     }
 
+    RootedObject cxGlobal(cx, JS::CurrentGlobalOrNull(cx));
     {
         // CompileOptions must be created from the context
         // we will execute this script in.
         JSContext *wndCx = context->GetNativeContext();
         AutoCxPusher pusher(wndCx);
         JS::CompileOptions compileOptions(wndCx);
         compileOptions.setFileAndLine(filename.get(), lineNo);
 
@@ -543,18 +544,19 @@ EvalInWindow(JSContext *cx, const nsAStr
 
             // If there was an exception thrown we should set it
             // on the calling context.
             RootedValue exn(wndCx, rval);
             // First we should reset the return value.
             rval.set(UndefinedValue());
 
             // Then clone the exception.
-            if (CloneNonReflectors(cx, &exn))
-                JS_SetPendingException(cx, exn);
+            JSAutoCompartment ac(wndCx, cxGlobal);
+            if (CloneNonReflectors(wndCx, &exn))
+                js::SetPendingExceptionCrossContext(cx, exn);
 
             return false;
         }
     }
 
     // Let's clone the return value back to the callers compartment.
     if (!CloneNonReflectors(cx, rval)) {
         rval.set(UndefinedValue());
--- a/js/xpconnect/src/XPCJSContextStack.cpp
+++ b/js/xpconnect/src/XPCJSContextStack.cpp
@@ -33,34 +33,38 @@ XPCJSContextStack::Pop()
 {
     MOZ_ASSERT(!mStack.IsEmpty());
 
     uint32_t idx = mStack.Length() - 1; // The thing we're popping
 
     JSContext *cx = mStack[idx].cx;
 
     mStack.RemoveElementAt(idx);
-    if (idx == 0)
+    if (idx == 0) {
+        js::Debug_SetActiveJSContext(mRuntime->Runtime(), nullptr);
         return cx;
+    }
 
     --idx; // Advance to new top of the stack
 
     XPCJSContextInfo &e = mStack[idx];
     if (e.cx && e.savedFrameChain) {
         // Pop() can be called outside any request for e.cx.
         JSAutoRequest ar(e.cx);
         JS_RestoreFrameChain(e.cx);
         e.savedFrameChain = false;
     }
+    js::Debug_SetActiveJSContext(mRuntime->Runtime(), e.cx);
     return cx;
 }
 
 bool
 XPCJSContextStack::Push(JSContext *cx)
 {
+    js::Debug_SetActiveJSContext(mRuntime->Runtime(), cx);
     if (mStack.Length() == 0) {
         mStack.AppendElement(cx);
         return true;
     }
 
     XPCJSContextInfo &e = mStack[mStack.Length() - 1];
     if (e.cx) {
         // The cx we're pushing is also stack-top. In general we still need to
--- a/js/xpconnect/src/XPCJSRuntime.cpp
+++ b/js/xpconnect/src/XPCJSRuntime.cpp
@@ -2951,17 +2951,17 @@ class XPCJSSourceHook: public js::Source
 static const JSWrapObjectCallbacks WrapObjectCallbacks = {
     xpc::WrapperFactory::Rewrap,
     xpc::WrapperFactory::WrapForSameCompartment,
     xpc::WrapperFactory::PrepareForWrapping
 };
 
 XPCJSRuntime::XPCJSRuntime(nsXPConnect* aXPConnect)
    : CycleCollectedJSRuntime(nullptr, 32L * 1024L * 1024L, JS_USE_HELPER_THREADS),
-   mJSContextStack(new XPCJSContextStack()),
+   mJSContextStack(new XPCJSContextStack(MOZ_THIS_IN_INITIALIZER_LIST())),
    mCallContext(nullptr),
    mAutoRoots(nullptr),
    mResolveName(JSID_VOID),
    mResolvingWrapper(nullptr),
    mWrappedJSMap(JSObject2WrappedJSMap::newMap(XPC_JS_MAP_SIZE)),
    mWrappedJSClassMap(IID2WrappedJSClassMap::newMap(XPC_JS_CLASS_MAP_SIZE)),
    mIID2NativeInterfaceMap(IID2NativeInterfaceMap::newMap(XPC_NATIVE_INTERFACE_MAP_SIZE)),
    mClassInfo2NativeSetMap(ClassInfo2NativeSetMap::newMap(XPC_NATIVE_SET_MAP_SIZE)),
--- a/js/xpconnect/src/xpcprivate.h
+++ b/js/xpconnect/src/xpcprivate.h
@@ -2768,18 +2768,19 @@ namespace xpc {
 bool PushJSContextNoScriptContext(JSContext *aCx);
 void PopJSContextNoScriptContext();
 
 } /* namespace xpc */
 
 class XPCJSContextStack
 {
 public:
-    XPCJSContextStack()
-      : mSafeJSContext(nullptr)
+    XPCJSContextStack(XPCJSRuntime *aRuntime)
+      : mRuntime(aRuntime)
+      , mSafeJSContext(nullptr)
     { }
 
     virtual ~XPCJSContextStack();
 
     uint32_t Count()
     {
         return mStack.Length();
     }
@@ -2802,16 +2803,17 @@ private:
     friend void xpc::PopJSContextNoScriptContext();
 
     // We make these private so that stack manipulation can only happen
     // through one of the above friends.
     JSContext *Pop();
     bool Push(JSContext *cx);
 
     AutoInfallibleTArray<XPCJSContextInfo, 16> mStack;
+    XPCJSRuntime* mRuntime;
     JSContext*  mSafeJSContext;
 };
 
 /***************************************************************************/
 // 'Components' object implementations. nsXPCComponentsBase has the
 // less-privileged stuff that we're willing to expose to XBL.
 
 class nsXPCComponentsBase : public nsIXPCComponentsBase
--- a/js/xpconnect/src/xpcpublic.h
+++ b/js/xpconnect/src/xpcpublic.h
@@ -97,16 +97,25 @@ UseXBLScope(JSCompartment *c);
 bool
 IsSandboxPrototypeProxy(JSObject *obj);
 
 bool
 IsReflector(JSObject *obj);
 
 bool
 IsXrayWrapper(JSObject *obj);
+
+// If this function was created for a given XrayWrapper, returns the global of
+// the Xrayed object. Otherwise, returns the global of the function.
+//
+// To emphasize the obvious: the return value here is not necessarily same-
+// compartment with the argument.
+JSObject *
+XrayAwareCalleeGlobal(JSObject *fun);
+
 } /* namespace xpc */
 
 namespace JS {
 
 struct RuntimeStats;
 
 }
 
--- a/js/xpconnect/wrappers/XrayWrapper.cpp
+++ b/js/xpconnect/wrappers/XrayWrapper.cpp
@@ -48,16 +48,26 @@ GetXrayType(JSObject *obj)
 
     const js::Class* clasp = js::GetObjectClass(obj);
     if (IS_WN_CLASS(clasp) || clasp->ext.innerObject)
         return XrayForWrappedNative;
 
     return NotXray;
 }
 
+JSObject *
+XrayAwareCalleeGlobal(JSObject *fun)
+{
+  MOZ_ASSERT(js::IsFunctionObject(fun));
+  JSObject *scope = js::GetObjectParent(fun);
+  if (IsXrayWrapper(scope))
+    scope = js::UncheckedUnwrap(scope);
+  return js::GetGlobalForObjectCrossCompartment(scope);
+}
+
 const uint32_t JSSLOT_RESOLVING = 0;
 ResolvingId::ResolvingId(JSContext *cx, HandleObject wrapper, HandleId id)
   : mId(id),
     mHolder(cx, getHolderObject(wrapper)),
     mPrev(getResolvingId(mHolder)),
     mXrayShadowing(false)
 {
     js::SetReservedSlot(mHolder, JSSLOT_RESOLVING, js::PrivateValue(this));
@@ -1535,17 +1545,17 @@ XrayWrapper<Base, Traits>::getPropertyDe
             return JS_WrapPropertyDescriptor(cx, desc);
         }
     }
 
     if (!desc.object() &&
         id == nsXPConnect::GetRuntimeInstance()->GetStringID(XPCJSRuntime::IDX_TO_STRING))
     {
 
-        JSFunction *toString = JS_NewFunction(cx, XrayToString, 0, 0, holder, "toString");
+        JSFunction *toString = JS_NewFunction(cx, XrayToString, 0, 0, wrapper, "toString");
         if (!toString)
             return false;
 
         desc.object().set(wrapper);
         desc.setAttributes(0);
         desc.setGetter(nullptr);
         desc.setSetter(nullptr);
         desc.value().setObject(*JS_GetFunctionObject(toString));
--- a/layout/base/nsPresContext.cpp
+++ b/layout/base/nsPresContext.cpp
@@ -48,16 +48,17 @@
 #include "nsIMessageManager.h"
 #include "mozilla/dom/MediaQueryList.h"
 #include "nsSMILAnimationController.h"
 #include "mozilla/css/ImageLoader.h"
 #include "mozilla/dom/TabChild.h"
 #include "nsRefreshDriver.h"
 #include "Layers.h"
 #include "nsIDOMEvent.h"
+#include "gfxPrefs.h"
 
 #include "nsContentUtils.h"
 #include "nsCxPusher.h"
 #include "nsPIWindowRoot.h"
 #include "mozilla/Preferences.h"
 
 // Needed for Start/Stop of Image Animation
 #include "imgIContainer.h"
@@ -683,16 +684,21 @@ nsPresContext::GetFontPrefsForLang(nsIAt
   }
 
   return prefs;
 }
 
 void
 nsPresContext::GetDocumentColorPreferences()
 {
+  // Make sure the preferences are initialized.  In the normal run,
+  // they would already be, because gfxPlatform would have been created,
+  // but in some reference tests, that is not the case.
+  gfxPrefs::GetSingleton();
+
   int32_t useAccessibilityTheme = 0;
   bool usePrefColors = true;
   nsCOMPtr<nsIDocShellTreeItem> docShell(mContainer);
   if (docShell) {
     if (nsIDocShellTreeItem::typeChrome == docShell->ItemType()) {
       usePrefColors = false;
     } else {
       useAccessibilityTheme =
--- a/media/libpng/mozpngconf.h
+++ b/media/libpng/mozpngconf.h
@@ -61,29 +61,35 @@
 #define PNG_READ_COMPRESSED_TEXT_SUPPORTED
 #define PNG_READ_EXPAND_SUPPORTED
 #define PNG_READ_GAMMA_SUPPORTED
 #define PNG_READ_GRAY_TO_RGB_SUPPORTED
 #define PNG_READ_INTERLACING_SUPPORTED
 #define PNG_READ_SCALE_16_TO_8_SUPPORTED
 #define PNG_READ_TRANSFORMS_SUPPORTED
 
-/* necessary for boot animation code */
+/* necessary for freetype color bitmap support (Android & B2G)
+   and boot animation code (Gonk) */
+#if defined(ANDROID) || defined(FT_CONFIG_OPTION_USE_PNG)
+#define PNG_READ_PACK_SUPPORTED
+#define PNG_READ_FILLER_SUPPORTED
+#define PNG_READ_STRIP_16_TO_8_SUPPORTED
+#define PNG_READ_USER_TRANSFORM_SUPPORTED
+#define PNG_SEQUENTIAL_READ_SUPPORTED
+#endif
+
+/* necessary for boot animation code (Gonk) */
 #ifdef MOZ_WIDGET_GONK
 #define PNG_UNKNOWN_CHUNKS_SUPPORTED
 #define PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
 #define PNG_HANDLE_AS_UNKNOWN_SUPPORTED
 #define PNG_EASY_ACCESS_SUPPORTED
 #define PNG_READ_BGR_SUPPORTED
-#define PNG_READ_FILLER_SUPPORTED
 #define PNG_READ_GRAY_TO_RGB_SUPPORTED
-#define PNG_READ_STRIP_16_TO_8_SUPPORTED
 #define PNG_READ_STRIP_ALPHA_SUPPORTED
-#define PNG_READ_USER_TRANSFORM_SUPPORTED
-#define PNG_SEQUENTIAL_READ_SUPPORTED
 #endif
 
 #define PNG_WRITE_SUPPORTED
 #define PNG_WRITE_APNG_SUPPORTED
 #define PNG_WRITE_tRNS_SUPPORTED
 #define PNG_WRITE_16BIT_SUPPORTED
 #define PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED
 #define PNG_WRITE_FLUSH_SUPPORTED
@@ -104,21 +110,18 @@
 #define PNG_16BIT_SUPPORTED
 #define PNG_CHECK_cHRM_SUPPORTED
 #define PNG_FLOATING_ARITHMETIC_SUPPORTED
 #define PNG_FLOATING_POINT_SUPPORTED
 #define PNG_POINTER_INDEXING_SUPPORTED
 #define PNG_SETJMP_SUPPORTED
 #define PNG_STDIO_SUPPORTED
 #define PNG_TEXT_SUPPORTED
-
-#ifdef PR_LOGGING
 #define PNG_ERROR_TEXT_SUPPORTED
 #define PNG_WARNINGS_SUPPORTED
-#endif
 
 /* Mangle names of exported libpng functions so different libpng versions
    can coexist. It is recommended that if you do this, you give your
    library a different name such as "mozlibpng" instead of "libpng". */
 
 /* The following has been present since libpng-0.88, has never changed, and
    is unaffected by conditional compilation macros.  It will not be mangled
    and it is the only choice for use in configure scripts for detecting the
@@ -639,21 +642,27 @@
 #define png_icc_check_length                      MOZ_PNG_icc_check_length
 #define png_icc_check_tag_table                   MOZ_PNG_icc_check_tags
 #define png_icc_set_sRGB                          MOZ_PNG_icc_set_sRGB
 #define png_malloc_array                          MOZ_PNG_malloc_array
 #define png_malloc_base                           MOZ_PNG_malloc_base
 #define png_realloc_array                         MOZ_PNG_realloc_array
 #define png_zstream_error                         MOZ_PNG_zstream_error
 
+/* needed by FreeType's PNG support */
+#define png_error                       MOZ_PNG_error
+
 #if defined(PR_LOGGING) && defined(PNG_WARNINGS_SUPPORTED)
 #define png_warning                     MOZ_PNG_warning
-#define png_error                       MOZ_PNG_error
 #define png_chunk_error                 MOZ_PNG_chunk_err
 #define png_fixed_error                 MOZ_PNG_fixed_err
 #define png_formatted_warning           MOZ_PNG_formatted_warning
 #define png_chunk_warning               MOZ_PNG_chunk_warn
 #define png_warning_parameter           MOZ_PNG_warn_param
 #define png_warning_parameter_signed    MOZ_PNG_warn_param_signed
 #define png_warning_parameter_unsigned  MOZ_PNG_warn_param_unsigned
 #endif
 
+#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
+#define png_set_packing  MOZ_PNG_set_packing
+#endif
+
 #endif /* MOZPNGCONF_H */
deleted file mode 100644
--- a/media/libsoundtouch/src/Makefile.in
+++ /dev/null
@@ -1,16 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-include $(topsrcdir)/config/rules.mk
-
-ifneq (,$(INTEL_ARCHITECTURE))
-ifdef GNU_CC
-mmx_optimized.$(OBJ_SUFFIX): CXXFLAGS+=-msse2
-sse_optimized.$(OBJ_SUFFIX): CXXFLAGS+=-msse2
-endif
-ifdef SOLARIS_SUNPRO_CXX
-mmx_optimized.$(OBJ_SUFFIX): OS_CXXFLAGS += -xarch=sse2 -xO4
-sse_optimized.$(OBJ_SUFFIX): OS_CXXFLAGS += -xarch=sse2 -xO4
-endif
-endif
--- a/media/libsoundtouch/src/moz.build
+++ b/media/libsoundtouch/src/moz.build
@@ -18,23 +18,27 @@ UNIFIED_SOURCES += [
     'FIRFilter.cpp',
     'RateTransposer.cpp',
     'SoundTouch.cpp',
     'TDStretch.cpp',
 ]
 
 if CONFIG['INTEL_ARCHITECTURE']:
     if CONFIG['MOZ_SAMPLE_TYPE_FLOAT32']:
-        UNIFIED_SOURCES += [
-            'sse_optimized.cpp',
-        ]
+        SOURCES += ['sse_optimized.cpp']
+        if CONFIG['GNU_CC']:
+            SOURCES['sse_optimized.cpp'].flags += ['-msse2']
+        if CONFIG['SOLARIS_SUNPRO_CXX']:
+            SOURCES['sse_optimized.cpp'].flags += ['-xarch=sse2', '-xO4']
     else:
-        UNIFIED_SOURCES += [
-            'mmx_optimized.cpp',
-        ]
+        SOURCES += ['mmx_optimized.cpp']
+        if CONFIG['GNU_CC']:
+            SOURCES['mmx_optimized.cpp'].flags += ['-mmmx']
+        if CONFIG['SOLARIS_SUNPRO_CXX']:
+            SOURCES['mmx_optimized.cpp'].flags += ['-xarch=mmx', '-xO4']
 
 MSVC_ENABLE_PGO = True
 if CONFIG['GKMEDIAS_SHARED_LIBRARY']:
     NO_VISIBILITY_FLAGS = True
 
 FINAL_LIBRARY = 'gkmedias'
 
 # Use abort() instead of exception in SoundTouch.
deleted file mode 100644
--- a/media/libspeex_resampler/src/Makefile.in
+++ /dev/null
@@ -1,14 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this file,
-# You can obtain one at http://mozilla.org/MPL/2.0/.
-
-include $(topsrcdir)/config/rules.mk
-
-# Only use SSE code when using floating point samples, and on x86
-ifneq (,$(INTEL_ARCHITECTURE))
-ifneq ($(OS_TARGET),Android)
-ifdef GNU_CC
-resample.$(OBJ_SUFFIX): CFLAGS+=-msse2
-endif
-endif
-endif
--- a/media/libspeex_resampler/src/moz.build
+++ b/media/libspeex_resampler/src/moz.build
@@ -34,8 +34,10 @@ if CONFIG['OS_TARGET'] == 'Android':
     DEFINES['FIXED_POINT'] = True
 else:
     DEFINES['FLOATING_POINT'] = True
 
 # Only use SSE code when using floating point samples, and on x86
 if CONFIG['INTEL_ARCHITECTURE'] and CONFIG['OS_TARGET'] != 'Android':
     DEFINES['_USE_SSE'] = True
     DEFINES['_USE_SSE2'] = True
+    if CONFIG['GNU_CC']:
+        SOURCES['resample.c'].flags += ['-msse2']
--- a/netwerk/protocol/http/nsHttpChannel.cpp
+++ b/netwerk/protocol/http/nsHttpChannel.cpp
@@ -5721,35 +5721,35 @@ nsHttpChannel::DoAuthRetry(nsAHttpConnec
     // notify "http-on-modify-request" observers
     CallOnModifyRequestObservers();
 
     mIsPending = true;
 
     // get rid of the old response headers
     mResponseHead = nullptr;
 
+    // rewind the upload stream
+    if (mUploadStream) {
+        nsCOMPtr<nsISeekableStream> seekable = do_QueryInterface(mUploadStream);
+        if (seekable)
+            seekable->Seek(nsISeekableStream::NS_SEEK_SET, 0);
+    }
+
     // set sticky connection flag and disable pipelining.
     mCaps |=  NS_HTTP_STICKY_CONNECTION;
     mCaps &= ~NS_HTTP_ALLOW_PIPELINING;
 
     // and create a new one...
     rv = SetupTransaction();
     if (NS_FAILED(rv)) return rv;
 
     // transfer ownership of connection to transaction
     if (conn)
         mTransaction->SetConnection(conn);
 
-    // rewind the upload stream
-    if (mUploadStream) {
-        nsCOMPtr<nsISeekableStream> seekable = do_QueryInterface(mUploadStream);
-        if (seekable)
-            seekable->Seek(nsISeekableStream::NS_SEEK_SET, 0);
-    }
-
     rv = gHttpHandler->InitiateTransaction(mTransaction, mPriority);
     if (NS_FAILED(rv)) return rv;
 
     rv = mTransactionPump->AsyncRead(this, nullptr);
     if (NS_FAILED(rv)) return rv;
 
     uint32_t suspendCount = mSuspendCount;
     while (suspendCount--)
--- a/python/mozboot/mozboot/base.py
+++ b/python/mozboot/mozboot/base.py
@@ -138,17 +138,17 @@ class BaseBootstrapper(object):
 
     def apt_update(self):
         command = ['apt-get', 'update']
 
         self.run_as_root(command)
 
     def apt_add_architecture(self, arch):
         command = ['dpkg', '--add-architecture']
-        command.extemd(arch)
+        command.extend(arch)
 
         self.run_as_root(command)
 
     def check_output(self, *args, **kwargs):
         """Run subprocess.check_output even if Python doesn't provide it."""
         fn = getattr(subprocess, 'check_output', BaseBootstrapper._check_output)
 
         return fn(*args, **kwargs)
--- a/python/mozbuild/mozbuild/backend/recursivemake.py
+++ b/python/mozbuild/mozbuild/backend/recursivemake.py
@@ -32,16 +32,17 @@ from ..frontend.data import (
     HostProgram,
     HostSimpleProgram,
     InstallationTarget,
     IPDLFile,
     JARManifest,
     JavaJarData,
     LibraryDefinition,
     LocalInclude,
+    PerSourceFlag,
     Program,
     Resources,
     SandboxDerived,
     SandboxWrapped,
     SimpleProgram,
     TestManifest,
     VariablePassthru,
     XPIDLFile,
@@ -437,16 +438,19 @@ class RecursiveMakeBackend(CommonBackend
             self._process_host_simple_program(obj.program, backend_file)
 
         elif isinstance(obj, LocalInclude):
             self._process_local_include(obj.path, backend_file)
 
         elif isinstance(obj, GeneratedInclude):
             self._process_generated_include(obj.path, backend_file)
 
+        elif isinstance(obj, PerSourceFlag):
+            self._process_per_source_flag(obj, backend_file)
+
         elif isinstance(obj, InstallationTarget):
             self._process_installation_target(obj, backend_file)
 
         elif isinstance(obj, SandboxWrapped):
             # Process a rich build system object from the front-end
             # as-is.  Please follow precedent and handle CamelCaseData
             # in a function named _process_camel_case_data.  At some
             # point in the future, this unwrapping process may be
@@ -1080,16 +1084,20 @@ class RecursiveMakeBackend(CommonBackend
 
     def _process_generated_include(self, generated_include, backend_file):
         if generated_include.startswith('/'):
             path = self.environment.topobjdir.replace('\\', '/')
         else:
             path = ''
         backend_file.write('LOCAL_INCLUDES += -I%s%s\n' % (path, generated_include))
 
+    def _process_per_source_flag(self, per_source_flag, backend_file):
+        for flag in per_source_flag.flags:
+            backend_file.write('%s_FLAGS += %s\n' % (per_source_flag.file_name, flag))
+
     def _process_java_jar_data(self, jar, backend_file):
         target = jar.name
         backend_file.write('JAVA_JAR_TARGETS += %s\n' % target)
         backend_file.write('%s_DEST := %s.jar\n' % (target, jar.name))
         if jar.sources:
             backend_file.write('%s_JAVAFILES := %s\n' %
                 (target, ' '.join(jar.sources)))
         if jar.generated_sources:
--- a/python/mozbuild/mozbuild/frontend/data.py
+++ b/python/mozbuild/mozbuild/frontend/data.py
@@ -465,16 +465,31 @@ class GeneratedInclude(SandboxDerived):
     )
 
     def __init__(self, sandbox, path):
         SandboxDerived.__init__(self, sandbox)
 
         self.path = path
 
 
+class PerSourceFlag(SandboxDerived):
+    """Describes compiler flags specified for individual source files."""
+
+    __slots__ = (
+        'file_name',
+        'flags',
+    )
+
+    def __init__(self, sandbox, file_name, flags):
+        SandboxDerived.__init__(self, sandbox)
+
+        self.file_name = file_name
+        self.flags = flags
+
+
 class JARManifest(SandboxDerived):
     """Describes an individual JAR manifest file and how to process it.
 
     This class isn't very useful for optimizing backends yet because we don't
     capture defines. We can't capture defines safely until all of them are
     defined in moz.build and not Makefile.in files.
     """
     __slots__ = (
--- a/python/mozbuild/mozbuild/frontend/emitter.py
+++ b/python/mozbuild/mozbuild/frontend/emitter.py
@@ -28,16 +28,17 @@ from .data import (
     HeaderFileSubstitution,
     HostProgram,
     HostSimpleProgram,
     InstallationTarget,
     IPDLFile,
     JARManifest,
     LibraryDefinition,
     LocalInclude,
+    PerSourceFlag,
     PreprocessedTestWebIDLFile,
     PreprocessedWebIDLFile,
     Program,
     ReaderSummary,
     Resources,
     SandboxWrapped,
     SimpleProgram,
     TestWebIDLFile,
@@ -302,16 +303,21 @@ class TreeMetadataEmitter(LoggingMixin):
         no_pgo_sources = [f for f in sources if sources[f].no_pgo]
         if no_pgo:
             if no_pgo_sources:
                 raise SandboxValidationError('NO_PGO and SOURCES[...].no_pgo cannot be set at the same time')
             passthru.variables['NO_PROFILE_GUIDED_OPTIMIZE'] = no_pgo
         if no_pgo_sources:
             passthru.variables['NO_PROFILE_GUIDED_OPTIMIZE'] = no_pgo_sources
 
+        sources_with_flags = [f for f in sources if sources[f].flags]
+        for f in sources_with_flags:
+            ext = mozpath.splitext(f)[1]
+            yield PerSourceFlag(sandbox, f, sources[f].flags)
+
         exports = sandbox.get('EXPORTS')
         if exports:
             yield Exports(sandbox, exports,
                 dist_install=not sandbox.get('NO_DIST_INSTALL', False))
 
         defines = sandbox.get('DEFINES')
         if defines:
             yield Defines(sandbox, defines)
--- a/python/mozbuild/mozbuild/frontend/sandbox_symbols.py
+++ b/python/mozbuild/mozbuild/frontend/sandbox_symbols.py
@@ -79,17 +79,17 @@ VARIABLES = {
 
     'ANDROID_ECLIPSE_PROJECT_TARGETS': (dict, dict,
         """Defines Android Eclipse project targets.
 
         This variable should not be populated directly. Instead, it should
         populated by calling add_android_eclipse{_library}_project().
         """, 'export'),
 
-    'SOURCES': (StrictOrderingOnAppendListWithFlagsFactory({'no_pgo': bool}), list,
+    'SOURCES': (StrictOrderingOnAppendListWithFlagsFactory({'no_pgo': bool, 'flags': list}), list,
         """Source code files.
 
         This variable contains a list of source code files to compile.
         Accepts assembler, C, C++, Objective C/C++.
         """, 'compile'),
 
     'GENERATED_SOURCES': (StrictOrderingOnAppendList, list,
         """Generated source code files.
--- a/security/manager/ssl/src/NSSErrorsService.cpp
+++ b/security/manager/ssl/src/NSSErrorsService.cpp
@@ -95,17 +95,16 @@ NSSErrorsService::GetErrorClass(nsresult
 
   switch (aNSPRCode)
   {
     case SEC_ERROR_UNKNOWN_ISSUER:
     case SEC_ERROR_CA_CERT_INVALID:
     case SEC_ERROR_UNTRUSTED_ISSUER:
     case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE:
     case SEC_ERROR_UNTRUSTED_CERT:
-    case SEC_ERROR_INADEQUATE_KEY_USAGE:
     case SSL_ERROR_BAD_CERT_DOMAIN:
     case SEC_ERROR_EXPIRED_CERTIFICATE:
     case SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED:
       *aErrorClass = ERROR_CLASS_BAD_CERT;
       break;
     default:
       *aErrorClass = ERROR_CLASS_SSL_PROTOCOL;
       break;
--- a/security/manager/ssl/src/TransportSecurityInfo.cpp
+++ b/security/manager/ssl/src/TransportSecurityInfo.cpp
@@ -629,19 +629,16 @@ AppendErrorTextUntrusted(PRErrorCode err
         if (chain && NS_FAILED(chain->GetLength(&length)))
           length = 0;
         if (length == 1)
           errorID = "certErrorTrust_MissingChain";
         else
           errorID = "certErrorTrust_UnknownIssuer";
         break;
       }
-      case SEC_ERROR_INADEQUATE_KEY_USAGE:
-        // Should get an individual string in the future
-        // For now, use the same as CaInvalid
       case SEC_ERROR_CA_CERT_INVALID:
         errorID = "certErrorTrust_CaInvalid";
         break;
       case SEC_ERROR_UNTRUSTED_ISSUER:
         errorID = "certErrorTrust_Issuer";
         break;
       case SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED:
         errorID = "certErrorTrust_SignatureAlgorithmDisabled";
--- a/security/manager/ssl/tests/unit/test_cert_overrides.js
+++ b/security/manager/ssl/tests/unit/test_cert_overrides.js
@@ -108,16 +108,28 @@ function add_simple_tests(useInsanity) {
                                         : SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE));
   add_cert_override_test("md5signature.example.com",
                          Ci.nsICertOverrideService.ERROR_UNTRUSTED,
                          getXPCOMStatusFromNSS(
                             SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED));
   add_cert_override_test("mismatch.example.com",
                          Ci.nsICertOverrideService.ERROR_MISMATCH,
                          getXPCOMStatusFromNSS(SSL_ERROR_BAD_CERT_DOMAIN));
+
+  // Inadequate key usage is no longer overridable.
+  add_connection_test("inadequatekeyusage.example.com",
+                      getXPCOMStatusFromNSS(SEC_ERROR_INADEQUATE_KEY_USAGE),
+                      null,
+                      function (securityInfo) {
+                        // bug 754369 - no SSLStatus probably means this is
+                        // a non-overridable error, which is what we're testing
+                        // (although it would be best to test this directly).
+                        securityInfo.QueryInterface(Ci.nsISSLStatusProvider);
+                        do_check_eq(securityInfo.SSLStatus, null);
+                      });
 }
 
 function add_combo_tests(useInsanity) {
   // Note that "untrusted" here really is "unknown issuer" in the
   // insanity::pkix case.
 
   add_cert_override_test("mismatch-expired.example.com",
                          Ci.nsICertOverrideService.ERROR_MISMATCH |
@@ -166,17 +178,16 @@ function add_distrust_tests(useInsanity)
   // XXX(Bug 975777): Active distrust is an overridable error when NSS-based
   // verification is used.
   add_distrust_override_test("tlsserver/other-test-ca.der",
                              "untrustedissuer.example.com",
                              getXPCOMStatusFromNSS(SEC_ERROR_UNTRUSTED_ISSUER),
                              useInsanity
                                 ? getXPCOMStatusFromNSS(SEC_ERROR_UNTRUSTED_ISSUER)
                                 : Cr.NS_OK);
-
 }
 
 function add_distrust_override_test(certFileName, hostName,
                                     expectedResultBefore, expectedResultAfter) {
   let certToDistrust = constructCertFromFile(certFileName);
 
   add_test(function () {
     // "pu" means the cert is actively distrusted.
index 82f76a6ed791e47c4078f18a19fdeade3ad97a2e..ab5dffe785a67ba80741b7979178ec92ef5a96c3
GIT binary patch
literal 65536
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
v000000000000000000000000000000000000000000000000000H*&RU4>)C
--- a/security/manager/ssl/tests/unit/tlsserver/cmd/BadCertServer.cpp
+++ b/security/manager/ssl/tests/unit/tlsserver/cmd/BadCertServer.cpp
@@ -34,16 +34,17 @@ const BadCertHost sBadCertHosts[] =
   { "md5signature.example.com", "md5signature" },
   { "untrusted.example.com", "localhostAndExampleCom" },
   { "untrustedissuer.example.com", "untrustedissuer" },
   { "mismatch-expired.example.com", "mismatch-expired" },
   { "mismatch-untrusted.example.com", "mismatch-untrusted" },
   { "untrusted-expired.example.com", "untrusted-expired" },
   { "md5signature-expired.example.com", "md5signature-expired" },
   { "mismatch-untrusted-expired.example.com", "mismatch-untrusted-expired" },
+  { "inadequatekeyusage.example.com", "inadequatekeyusage" },
   { nullptr, nullptr }
 };
 
 int32_t
 DoSNISocketConfig(PRFileDesc *aFd, const SECItem *aSrvNameArr,
                   uint32_t aSrvNameArrSize, void *aArg)
 {
   const BadCertHost *host = GetHostForSNI(aSrvNameArr, aSrvNameArrSize,
index 9100328605be1f4db33e0528bfbfa979052af957..7e6f9654dabd2a6220f7cecccda64a707059f9cc
GIT binary patch
literal 527
zc$_n6V&XPvVk}v}%*4pV#K>sC%f_kI=F#?@mywZ`mBB#BP{4qXjX9KsS(rT}wYWsV
z+0j5woY&CAz{tSZ$k5c%$Sg{n*94hsAY~|FAO_LH57y(Fm!g}RSCUy$Y0x+y*#<^d
z2Ij_I27|^<rp88whh}aQ^IwHXKAiZ~Ik#20ciZXDI?;bp52Q~1Qdh;|Ijgwy*0043
zx3;<;74kCibD9vYqi{QnrMSAiVwSj1RpILU-?h^tL=Bp28V}}f{WR^aDf5dD%(g{q
z+CDZdIJ-YfW<kI0;V|h%3L=edZMqBXrh7+99%Xs@ea4gAo1C|{=pAKZW@KPooN175
zpbT`qtRRbwfm9P`PJVJ?PDXxlNfWP@UTQ^RZb43}UUGh}fe{;rHXAUI*clmF)C^P%
zlwf=V#x}8xl9B=|eSNrQD+>b)1APM?kio)?jQ?4f3>eVDni&`b9&>BtZgkApYsa7e
z<=`QYwvWdBN`_I77-BnnUw(TcC0du?s<N=4f8{BONBjAcA~cH@y)zYwRg|0aF8&EG
zbANyPf&JEr6`%9IuQr>J{FtxZ(SfC4)rmt7*`s&!Y4nJ!`h3OHwmAFir7!!~cSS7N
WVd`OE$iDW~{f;j6qz)PJ=otVHe6~#h
--- a/security/manager/ssl/tests/unit/tlsserver/generate_certs.sh
+++ b/security/manager/ssl/tests/unit/tlsserver/generate_certs.sh
@@ -139,9 +139,11 @@ NSS_ALLOW_WEAK_SIGNATURE_ALG=1 make_EE m
 make_EE untrustedissuer 'CN=Test End-entity with untrusted issuer' otherCA "untrustedissuer.example.com"
 
 make_EE mismatch-expired 'CN=Mismatch-Expired Test End-entity' testCA "doesntmatch.example.com" "-w -400"
 make_EE mismatch-untrusted 'CN=Mismatch-Untrusted Test End-entity' otherCA "doesntmatch.example.com"
 make_EE untrusted-expired 'CN=Untrusted-Expired Test End-entity' otherCA "untrusted-expired.example.com" "-w -400"
 make_EE mismatch-untrusted-expired 'CN=Mismatch-Untrusted-Expired Test End-entity' otherCA "doesntmatch.example.com" "-w -400"
 NSS_ALLOW_WEAK_SIGNATURE_ALG=1 make_EE md5signature-expired 'CN=Test MD5Signature-Expired End-entity' testCA "md5signature-expired.example.com" "-Z MD5" "-w -400"
 
+make_EE inadequatekeyusage 'CN=Inadequate Key Usage Test End-entity' testCA "inadequatekeyusage.example.com" "--keyUsage crlSigning"
+
 cleanup
index c5ae5df7a2045460217167d36a047ddc75e0a376..6793d58fa6a354fe7a401c4fa9dd6f85d82975fb
GIT binary patch
literal 53248
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
M2~Qyve5q12`*r7$*8l(j
index e3d76676da15d3bde5ac053f8ce43fb8a0c0ae0e..357c00a748f8ba04d5aeaac0242179b20e8d2ff4
GIT binary patch
literal 452
zc$_n6Vmx5b#HhJ|nTe5!iIrhqdCXM<UN%mxHjlRNyo`*jtPBPchGGUHY|No7%)-3>
zB^jwj3MHw<B?``t26E!Oh9(9^2F6B)rj|x#QR2KN$Xq-+8|Ne2!pO?N+}O)t(Ade;
z*vPQB|J><CQf1E1I&S<em|R|T-ib&1=PLCx1+%hJE==``{PfE?bXrV$e%3VYuMN66
z63Z3kAKTt6UT{0ebfc4P&+b{Fia$T(=X~2*qq^<<<vliwJoU>bPF-mxa%b<SKg``0
z?yDO1FPT?ucH{d(`;XzPY_n&7+rE6_=^pM&Tb2e#KWt@UW@KPo40O4H5YX+i!i<dn
zSvU;XfD{uWBU<1v1Klf95%gi@^xw?+yDl!7{{Og#GSjomHmlw)S)J9p`|hD{QRn<(
z)Adch+$xzn;dktw&OD~ivb=_yV#_(4zt7jGmYKis*SgPahnZBh(%Cj2xDhoa`04Fe
yUc9wO|7c9$;*!*^GIW|PomCcjbkj@yjEC1AJ2;E1ZdxZ>!>r%2PJK^Ji#q_tgRN2k
index d499ddd477252fee875c6d3f702e3dfe30959a74..080be8ed53e6bf1cd3f248c9d67e083275088c01
GIT binary patch
literal 440
zc$_n6V%%cT#3;LfnTe5!iIrhqdCV09UN%mxHjlRNyo`*jtPBQ1h5`nBY|No7%);y;
zsl_D<&W;9h;=G0?21W+PMuw)AMrKjsye7z8ta=*fBb&^~%D~*%%V5yh$<)}$aEjNd
z^?Uid)t?Q1YAWmH)En|eeAYU2anlU{MQr!(oqMwWyG&H;NsSX0JU)&WzKEzeyf?`|
z7~5GtOa4q!vdzIsS0Df1Ep#<GxOskG%GWlJ9L|t^&owumjeStPgZJ774><;fx2)W&
z6JLs+k1O1p<Mrvw)jx+i?}t8Gp6>U1$vn;3Ow5c7jElt#L=1$0u9g*MWc<&<VZa8Y
zm>3z+0)!dpUZn%;oTJ)(v;T`PU`;*Pc6!yp(x*j9^=!V2mreh3=Y;<+Qy$eFA&;Dv
ze2d=Ho}b(l-u0+aw&T#F>rA;?sefhpX4|PM&u7?lS8Zvke9z(ITf^%Pm_@vixi;%^
sM`CwxlEF^xx$7H3bvySwZY~ylUsl(0N>N|?;WQhsjr9UG_jw)z00U#EC;$Ke
--- a/testing/marionette/marionette-server.js
+++ b/testing/marionette/marionette-server.js
@@ -34,17 +34,19 @@ Cu.import("resource://gre/modules/NetUti
 
 Services.prefs.setBoolPref("marionette.contentListener", false);
 let appName = Services.appinfo.name;
 
 // dumpn needed/used by dbg-transport.js
 this.dumpn = function dumpn(str) {
   logger.trace(str);
 }
-loader.loadSubScript("resource://gre/modules/devtools/DevToolsUtils.js");
+let { devtools } = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
+let DevToolsUtils = devtools.require("devtools/toolkit/DevToolsUtils.js");
+this.DevToolsUtils = DevToolsUtils;
 loader.loadSubScript("resource://gre/modules/devtools/server/transport.js");
 
 let bypassOffline = false;
 let qemu = "0";
 let device = null;
 
 try {
   XPCOMUtils.defineLazyGetter(this, "libcutils", function () {
--- a/testing/mochitest/b2g-debug.json
+++ b/testing/mochitest/b2g-debug.json
@@ -9,16 +9,17 @@
     "toolkit/devtools/apps": ""
   },
 "excludetests": {
     "content/xul":"tests that use xul",
     "layout/xul" : "",
     "dom/apps":"bug 972927, nearly perma-fail",
     "dom/datastore":"bug 974270, frequent failures",
     "dom/datastore/tests/test_changes.html":"intermittent failures, bug 961021",
+    "dom/downloads":"bug 979446, frequent failures",
     "dom/tests/mochitest/general/test_focusrings.xul":"",
     "layout/base/tests/test_bug465448.xul":"",
 
     "layout/forms/test/test_bug478219.xhtml":"window.closed not working, bug 907795",
     "content/media/test":"bug 918299",
     "content/media/test/test_bug448534.html": "Timed out, bug 894922? Bug 902677 is for the timing out of a lot of media tests",
     "content/media/mediasource/test/test_MediaSource.html": " ReferenceError: MediaSource is not defined",
     "content/media/test/test_autoplay_contentEditable.html": "bug 899074 - timeouts",
--- a/testing/mochitest/b2g-desktop.json
+++ b/testing/mochitest/b2g-desktop.json
@@ -7,16 +7,17 @@
     "dom": "",
     "layout": "",
     "toolkit/devtools/apps": ""
   },
 "excludetests": {
     "b2g/chrome/content/test/mochitest": "require OOP support for mochitest-b2g-desktop, Bug 957554",
     "content/xul":"tests that use xul",
     "layout/xul" : "",
+    "dom/downloads":"bug 979446, frequent failures",
     "dom/plugins": "tests that use plugins",
     "dom/tests/mochitest/general/test_focusrings.xul":"",
     "layout/base/tests/test_bug465448.xul":"",
     "layout/forms/test/test_bug287446.html": "bug 947789",
 
     "layout/forms/test/test_bug478219.xhtml":"window.closed not working, bug 907795",
     "content/media/test":"bug 918299",
     "content/media/test/test_bug448534.html": "Timed out, bug 894922? Bug 902677 is for the timing out of a lot of media tests",
--- a/testing/mochitest/b2g.json
+++ b/testing/mochitest/b2g.json
@@ -8,16 +8,17 @@
     "layout": "",
     "toolkit/devtools/apps": ""
   },
 "excludetests": {
     "content/xul":"tests that use xul",
     "layout/xul" : "",
     "dom/apps":"bug 972927, nearly perma-fail",
     "dom/datastore":"bug 974270, frequent failures",
+    "dom/downloads":"bug 979446, frequent failures",
     "dom/tests/mochitest/general/test_focusrings.xul":"",
     "layout/base/tests/test_bug465448.xul":"",
 
     "layout/forms/test/test_bug478219.xhtml":"window.closed not working, bug 907795",
     "content/media/test/test_bug448534.html": "Timed out, bug 894922? Bug 902677 is for the timing out of a lot of media tests",
     "content/media/mediasource/test/test_MediaSource.html": " ReferenceError: MediaSource is not defined",
     "content/media/test/test_autoplay_contentEditable.html": "bug 899074 - timeouts",
     "content/media/test/test_bug465498.html":"",
--- a/testing/mochitest/tests/SimpleTest/EventUtils.js
+++ b/testing/mochitest/tests/SimpleTest/EventUtils.js
@@ -941,18 +941,31 @@ function synthesizeText(aEvent, aWindow)
       !aEvent.composition.clauses[0]) {
     return;
   }
 
   var compositionString = utils.createCompositionStringSynthesizer();
   compositionString.setString(aEvent.composition.string);
   if (aEvent.composition.clauses[0].length) {
     for (var i = 0; i < aEvent.composition.clauses.length; i++) {
-      compositionString.appendClause(aEvent.composition.clauses[i].length,
-                                     aEvent.composition.clauses[i].attr);
+      switch (aEvent.composition.clauses[i].attr) {
+        case compositionString.ATTR_RAWINPUT:
+        case compositionString.ATTR_SELECTEDRAWTEXT:
+        case compositionString.ATTR_CONVERTEDTEXT:
+        case compositionString.ATTR_SELECTEDCONVERTEDTEXT:
+          compositionString.appendClause(aEvent.composition.clauses[i].length,
+                                         aEvent.composition.clauses[i].attr);
+          break;
+        case 0:
+          // Ignore dummy clause for the argument.
+          break;
+        default:
+          throw new Error("invalid clause attribute specified");
+          break;
+      }
     }
   }
 
   if (aEvent.caret) {
     compositionString.setCaret(aEvent.caret.start, aEvent.caret.length);
   }
 
   compositionString.dispatchEvent();
--- a/testing/mozbase/mozdevice/mozdevice/devicemanagerADB.py
+++ b/testing/mozbase/mozdevice/mozdevice/devicemanagerADB.py
@@ -202,17 +202,17 @@ class DeviceManagerADB(DeviceManager):
         self._checkCmd(["push", os.path.realpath(localname), destname],
                        retryLimit=retryLimit)
 
     def mkDir(self, name):
         result = self._runCmd(["shell", "mkdir", name]).stdout.read()
         if 'read-only file system' in result.lower():
             raise DMError("Error creating directory: read only file system")
 
-    def pushDir(self, localDir, remoteDir, retryLimit=None):
+    def pushDir(self, localDir, remoteDir, retryLimit=None, timeout=None):
         # adb "push" accepts a directory as an argument, but if the directory
         # contains symbolic links, the links are pushed, rather than the linked
         # files; we either zip/unzip or re-copy the directory into a temporary
         # one to get around this limitation
         retryLimit = retryLimit or self.retryLimit
         if not self.dirExists(remoteDir):
             self.mkDirs(remoteDir+"/x")
         if self._useZip:
@@ -221,17 +221,17 @@ class DeviceManagerADB(DeviceManager):
                 remoteZip = remoteDir + "/adbdmtmp.zip"
                 subprocess.Popen(["zip", "-r", localZip, '.'], cwd=localDir,
                                  stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
                 self.pushFile(localZip, remoteZip, retryLimit=retryLimit, createDir=False)
                 mozfile.remove(localZip)
                 data = self._runCmd(["shell", "unzip", "-o", remoteZip,
                                      "-d", remoteDir]).stdout.read()
                 self._checkCmd(["shell", "rm", remoteZip],
-                               retryLimit=retryLimit)
+                               retryLimit=retryLimit, timeout=timeout)
                 if re.search("unzip: exiting", data) or re.search("Operation not permitted", data):
                     raise Exception("unzip failed, or permissions error")
             except:
                 self._logger.info("zip/unzip failure: falling back to normal push")
                 self._useZip = False
                 self.pushDir(localDir, remoteDir, retryLimit=retryLimit)
         else:
             tmpDir = tempfile.mkdtemp()
--- a/toolkit/devtools/DevToolsUtils.js
+++ b/toolkit/devtools/DevToolsUtils.js
@@ -1,24 +1,24 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 /* General utilities used throughout devtools. */
+const { Ci, Cu } = require("chrome");
 
-let Cu = Components.utils;
-let { Promise: promise } = Components.utils.import("resource://gre/modules/commonjs/sdk/core/promise.js", {});
-let { Services } = Components.utils.import("resource://gre/modules/Services.jsm", {});
+let { Promise: promise } = Cu.import("resource://gre/modules/commonjs/sdk/core/promise.js", {});
+let { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
 
 /**
  * Turn the error |aError| into a string, without fail.
  */
-this.safeErrorString = function safeErrorString(aError) {
+exports.safeErrorString = function safeErrorString(aError) {
   try {
     let errorString = aError.toString();
     if (typeof errorString == "string") {
       // Attempt to attach a stack to |errorString|. If it throws an error, or
       // isn't a string, don't use it.
       try {
         if (aError.stack) {
           let stack = aError.stack.toString();
@@ -37,28 +37,28 @@ this.safeErrorString = function safeErro
   } catch (ee) { }
 
   return "<failed trying to find error description>";
 }
 
 /**
  * Report that |aWho| threw an exception, |aException|.
  */
-this.reportException = function reportException(aWho, aException) {
-  let msg = aWho + " threw an exception: " + safeErrorString(aException);
+exports.reportException = function reportException(aWho, aException) {
+  let msg = aWho + " threw an exception: " + exports.safeErrorString(aException);
 
   dump(msg + "\n");
 
-  if (Components.utils.reportError) {
+  if (Cu.reportError) {
     /*
      * Note that the xpcshell test harness registers an observer for
      * console messages, so when we're running tests, this will cause
      * the test to quit.
      */
-    Components.utils.reportError(msg);
+    Cu.reportError(msg);
   }
 }
 
 /**
  * Given a handler function that may throw, return an infallible handler
  * function that calls the fallible handler, and logs any exceptions it
  * throws.
  *
@@ -66,44 +66,44 @@ this.reportException = function reportEx
  *      A handler function, which may throw.
  * @param aName string
  *      A name for aHandler, for use in error messages. If omitted, we use
  *      aHandler.name.
  *
  * (SpiderMonkey does generate good names for anonymous functions, but we
  * don't have a way to get at them from JavaScript at the moment.)
  */
-this.makeInfallible = function makeInfallible(aHandler, aName) {
+exports.makeInfallible = function makeInfallible(aHandler, aName) {
   if (!aName)
     aName = aHandler.name;
 
   return function (/* arguments */) {
     try {
       return aHandler.apply(this, arguments);
     } catch (ex) {
       let who = "Handler function";
       if (aName) {
         who += " " + aName;
       }
-      reportException(who, ex);
+      exports.reportException(who, ex);
     }
   }
 }
 
 /**
  * Interleaves two arrays element by element, returning the combined array, like
  * a zip. In the case of arrays with different sizes, undefined values will be
  * interleaved at the end along with the extra values of the larger array.
  *
  * @param Array a
  * @param Array b
  * @returns Array
  *          The combined array, in the form [a1, b1, a2, b2, ...]
  */
-this.zip = function zip(a, b) {
+exports.zip = function zip(a, b) {
   if (!b) {
     return a;
   }
   if (!a) {
     return b;
   }
   const pairs = [];
   for (let i = 0, aLength = a.length, bLength = b.length;
@@ -111,34 +111,34 @@ this.zip = function zip(a, b) {
        i++) {
     pairs.push([a[i], b[i]]);
   }
   return pairs;
 };
 
 const executeSoon = aFn => {
   Services.tm.mainThread.dispatch({
-    run: this.makeInfallible(aFn)
-  }, Components.interfaces.nsIThread.DISPATCH_NORMAL);
+    run: exports.makeInfallible(aFn)
+  }, Ci.nsIThread.DISPATCH_NORMAL);
 };
 
 /**
  * Like Array.prototype.forEach, but doesn't cause jankiness when iterating over
  * very large arrays by yielding to the browser and continuing execution on the
  * next tick.
  *
  * @param Array aArray
  *        The array being iterated over.
  * @param Function aFn
  *        The function called on each item in the array.
  * @returns Promise
  *          A promise that is resolved once the whole array has been iterated
  *          over.
  */
-this.yieldingEach = function yieldingEach(aArray, aFn) {
+exports.yieldingEach = function yieldingEach(aArray, aFn) {
   const deferred = promise.defer();
 
   let i = 0;
   let len = aArray.length;
 
   (function loop() {
     const start = Date.now();
 
@@ -175,17 +175,17 @@ this.yieldingEach = function yieldingEac
  * @param Object aObject
  *        The prototype object to define the lazy getter on.
  * @param String aKey
  *        The key to define the lazy getter on.
  * @param Function aCallback
  *        The callback that will be called to determine the value. Will be
  *        called with the |this| value of the current instance.
  */
-this.defineLazyPrototypeGetter =
+exports.defineLazyPrototypeGetter =
 function defineLazyPrototypeGetter(aObject, aKey, aCallback) {
   Object.defineProperty(aObject, aKey, {
     configurable: true,
     get: function() {
       const value = aCallback.call(this);
 
       Object.defineProperty(this, aKey, {
         configurable: true,
@@ -203,65 +203,65 @@ function defineLazyPrototypeGetter(aObje
  * the prototype chain until the property is found.
  *
  * @param Debugger.Object aObject
  *        The Debugger.Object to get the value from.
  * @param String aKey
  *        The key to look for.
  * @return Any
  */
-this.getProperty = function getProperty(aObj, aKey) {
+exports.getProperty = function getProperty(aObj, aKey) {
   let root = aObj;
   try {
     do {
       const desc = aObj.getOwnPropertyDescriptor(aKey);
       if (desc) {
         if ("value" in desc) {
           return desc.value;
         }
         // Call the getter if it's safe.
-        return hasSafeGetter(desc) ? desc.get.call(root).return : undefined;
+        return exports.hasSafeGetter(desc) ? desc.get.call(root).return : undefined;
       }
       aObj = aObj.proto;
     } while (aObj);
   } catch (e) {
     // If anything goes wrong report the error and return undefined.
-    reportException("getProperty", e);
+    exports.reportException("getProperty", e);
   }
   return undefined;
 };
 
 /**
  * Determines if a descriptor has a getter which doesn't call into JavaScript.
  *
  * @param Object aDesc
  *        The descriptor to check for a safe getter.
  * @return Boolean
  *         Whether a safe getter was found.
  */
-this.hasSafeGetter = function hasSafeGetter(aDesc) {
+exports.hasSafeGetter = function hasSafeGetter(aDesc) {
   let fn = aDesc.get;
   return fn && fn.callable && fn.class == "Function" && fn.script === undefined;
 };
 
 /**
  * Check if it is safe to read properties and execute methods from the given JS
  * object. Safety is defined as being protected from unintended code execution
  * from content scripts (or cross-compartment code).
  *
  * See bugs 945920 and 946752 for discussion.
  *
  * @type Object aObj
  *       The object to check.
  * @return Boolean
  *         True if it is safe to read properties from aObj, or false otherwise.
  */
-this.isSafeJSObject = function isSafeJSObject(aObj) {
+exports.isSafeJSObject = function isSafeJSObject(aObj) {
   if (Cu.getGlobalForObject(aObj) ==
-      Cu.getGlobalForObject(isSafeJSObject)) {
+      Cu.getGlobalForObject(exports.isSafeJSObject)) {
     return true; // aObj is not a cross-compartment wrapper.
   }
 
   let principal = Services.scriptSecurityManager.getObjectPrincipal(aObj);
   if (Services.scriptSecurityManager.isSystemPrincipal(principal)) {
     return true; // allow chrome objects
   }
 
--- a/toolkit/devtools/DevToolsUtils.jsm
+++ b/toolkit/devtools/DevToolsUtils.jsm
@@ -2,31 +2,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 /*
  * General utilities used throughout devtools.
  *
- * To support chrome debugging, the debugger server needs to have all its
- * code in one global, so it must use loadSubScript directly. Everyone else,
- * though, prefers a JSM.
+ * When using chrome debugging, the debugger server is unable to debug itself.
+ * To avoid this, it must be loaded with a custom devtools loader with the
+ * invisibleToDebugger flag set to true. Everyone else, though, prefers a JSM.
  */
 
 this.EXPORTED_SYMBOLS = [ "DevToolsUtils" ];
 
-Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
-  .getService(Components.interfaces.mozIJSSubScriptLoader)
-  .loadSubScript("resource://gre/modules/devtools/DevToolsUtils.js", this);
-
-this.DevToolsUtils = {
-  safeErrorString: safeErrorString,
-  reportException: reportException,
-  makeInfallible: makeInfallible,
-  zip: zip,
-  yieldingEach: yieldingEach,
-  reportingDisabled: false , // Used by tests.
-  defineLazyPrototypeGetter: defineLazyPrototypeGetter,
-  getProperty: getProperty,
-  hasSafeGetter: hasSafeGetter,
-  isSafeJSObject: isSafeJSObject,
-};
+const { devtools } = Components.utils.import("resource://gre/modules/devtools/Loader.jsm", {});
+this.DevToolsUtils = devtools.require("devtools/toolkit/DevToolsUtils.js");
--- a/toolkit/devtools/server/actors/profiler.js
+++ b/toolkit/devtools/server/actors/profiler.js
@@ -136,17 +136,17 @@ ProfilerActor.prototype = {
       if (idx == -1)
         continue;
       Services.obs.removeObserver(this, event);
       this._observedEvents.splice(idx, 1);
       unregistered.push(event);
     }
     return { unregistered: unregistered }
   },
-  observe: makeInfallible(function(aSubject, aTopic, aData) {
+  observe: DevToolsUtils.makeInfallible(function(aSubject, aTopic, aData) {
     /*
      * this.conn.send can only transmit acyclic values. However, it is
      * idiomatic for wrapped JS objects like aSubject (and possibly aData?)
      * to have a 'wrappedJSObject' property pointing to themselves.
      *
      * this.conn.send also assumes that it can retain the object it is
      * passed to be handled on later event ticks; and that it's okay to
      * freeze it. Since we don't really know what aSubject and aData are,
--- a/toolkit/devtools/server/actors/script.js
+++ b/toolkit/devtools/server/actors/script.js
@@ -1071,17 +1071,17 @@ ThreadActor.prototype = {
       }
 
       let packet = this._resumed();
       this._popThreadPause();
       return packet;
     }, error => {
       return error instanceof Error
         ? { error: "unknownError",
-            message: safeErrorString(error) }
+            message: DevToolsUtils.safeErrorString(error) }
         // It is a known error, and the promise was rejected with an error
         // packet.
         : error;
     });
   },
 
   /**
    * Spin up a nested event loop so we can synchronously resolve a promise.
@@ -2504,17 +2504,17 @@ SourceActor.prototype = {
         };
       })
       .then(null, aError => {
         reportError(aError, "Got an exception during SA_onSource: ");
         return {
           "from": this.actorID,
           "error": "loadSourceError",
           "message": "Could not load the source for " + this._url + ".\n"
-            + safeErrorString(aError)
+            + DevToolsUtils.safeErrorString(aError)
         };
       });
   },
 
   /**
    * Handler for the "prettyPrint" packet.
    */
   onPrettyPrint: function ({ indent }) {
--- a/toolkit/devtools/server/actors/tracer.js
+++ b/toolkit/devtools/server/actors/tracer.js
@@ -1,19 +1,15 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 const { Cu } = require("chrome");
-
-const { reportException } =
-  Cu.import("resource://gre/modules/devtools/DevToolsUtils.jsm", {}).DevToolsUtils;
-
 const { DebuggerServer } = Cu.import("resource://gre/modules/devtools/dbg-server.jsm", {});
 
 Cu.import("resource://gre/modules/jsdebugger.jsm");
 addDebuggerToGlobal(this);
 
 // TODO bug 943125: remove this polyfill and use Debugger.Frame.prototype.depth
 // once it is implemented.
 if (!Object.getOwnPropertyDescriptor(Debugger.Frame.prototype, "depth")) {
@@ -135,17 +131,17 @@ TraceActor.prototype = {
   /**
    * Add a debuggee global to the Debugger object.
    */
   _addDebuggee: function(aGlobal) {
     try {
       this.dbg.addDebuggee(aGlobal);
     } catch (e) {
       // Ignore attempts to add the debugger's compartment as a debuggee.
-      reportException("TraceActor",
+      DevToolsUtils.reportException("TraceActor",
                       new Error("Ignoring request to add the debugger's "
                                 + "compartment as a debuggee"));
     }
   },
 
   /**
    * Add the provided window and all windows in its frame tree as debuggees.
    */
@@ -604,17 +600,17 @@ function createValueSnapshot(aValue, aDe
     case "object":
       if (aValue === null) {
         return { type: "null" };
       }
       return aDetailed
         ? detailedObjectSnapshot(aValue)
         : objectSnapshot(aValue);
     default:
-      reportException("TraceActor",
+      DevToolsUtils.reportException("TraceActor",
                       new Error("Failed to provide a grip for: " + aValue));
       return null;
   }
 }
 
 /**
  * Create a very minimal snapshot of the given debuggee object.
  *
--- a/toolkit/devtools/server/actors/webapps.js
+++ b/toolkit/devtools/server/actors/webapps.js
@@ -792,17 +792,17 @@ WebappsActor.prototype = {
   _connectToApp: function (aFrame) {
     let deferred = Promise.defer();
 
     let mm = aFrame.QueryInterface(Ci.nsIFrameLoaderOwner).frameLoader.messageManager;
     mm.loadFrameScript("resource://gre/modules/devtools/server/child.js", false);
 
     let childTransport, prefix;
 
-    let onActorCreated = makeInfallible(function (msg) {
+    let onActorCreated = DevToolsUtils.makeInfallible(function (msg) {
       mm.removeMessageListener("debug:actor", onActorCreated);
 
       dump("***** Got debug:actor\n");
       let { actor, appId } = msg.json;
       prefix = msg.json.prefix;
 
       // Pipe Debugger message from/to parent/child via the message manager
       childTransport = new ChildDebuggerTransport(mm, prefix);
@@ -817,17 +817,17 @@ WebappsActor.prototype = {
       debug("establishing forwarding for app with prefix " + prefix);
 
       this._appActorsMap.set(mm, actor);
 
       deferred.resolve(actor);
     }).bind(this);
     mm.addMessageListener("debug:actor", onActorCreated);
 
-    let onMessageManagerDisconnect = makeInfallible(function (subject, topic, data) {
+    let onMessageManagerDisconnect = DevToolsUtils.makeInfallible(function (subject, topic, data) {
       if (subject == mm) {
         Services.obs.removeObserver(onMessageManagerDisconnect, topic);
         if (childTransport) {
           // If we have a child transport, the actor has already
           // been created. We need to stop using this message manager.
           childTransport.close();
           this.conn.cancelForwarding(prefix);
         } else {
--- a/toolkit/devtools/server/actors/webbrowser.js
+++ b/toolkit/devtools/server/actors/webbrowser.js
@@ -352,17 +352,17 @@ BrowserTabList.prototype._listenForEvent
     }
     this[aGuard] = aShouldListen;
   }
 };
 
 /**
  * Implement nsIDOMEventListener.
  */
-BrowserTabList.prototype.handleEvent = makeInfallible(function(aEvent) {
+BrowserTabList.prototype.handleEvent = DevToolsUtils.makeInfallible(function(aEvent) {
   switch (aEvent.type) {
   case "TabOpen":
   case "TabSelect":
     /* Don't create a new actor; iterate will take care of that. Just notify. */
     this._notifyListChanged();
     this._checkListening();
     break;
   case "TabClose":
@@ -393,18 +393,18 @@ BrowserTabList.prototype._listenToMediat
  * See _onTabClosed for explanation of why we needn't actually tweak any
  * actors or tables here.
  *
  * An nsIWindowMediatorListener's methods get passed all sorts of windows; we
  * only care about the tab containers. Those have 'getBrowser' methods.
  */
 BrowserTabList.prototype.onWindowTitleChange = () => { };
 
-BrowserTabList.prototype.onOpenWindow = makeInfallible(function(aWindow) {
-  let handleLoad = makeInfallible(() => {
+BrowserTabList.prototype.onOpenWindow = DevToolsUtils.makeInfallible(function(aWindow) {
+  let handleLoad = DevToolsUtils.makeInfallible(() => {
     /* We don't want any further load events from this window. */
     aWindow.removeEventListener("load", handleLoad, false);
 
     if (appShellDOMWindowType(aWindow) !== DebuggerServer.chromeWindowType)
       return;
 
     // Listen for future tab activity.
     if (this._listeningForTabOpen) {
@@ -428,29 +428,29 @@ BrowserTabList.prototype.onOpenWindow = 
    * nsIWindowMediator enumeration from within listeners (bug 873589).
    */
   aWindow = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
                    .getInterface(Ci.nsIDOMWindow);
 
   aWindow.addEventListener("load", handleLoad, false);
 }, "BrowserTabList.prototype.onOpenWindow");
 
-BrowserTabList.prototype.onCloseWindow = makeInfallible(function(aWindow) {
+BrowserTabList.prototype.onCloseWindow = DevToolsUtils.makeInfallible(function(aWindow) {
   aWindow = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
                    .getInterface(Ci.nsIDOMWindow);
 
   if (appShellDOMWindowType(aWindow) !== DebuggerServer.chromeWindowType)
     return;
 
   /*
    * nsIWindowMediator deadlocks if you call its GetEnumerator method from
    * a nsIWindowMediatorListener's onCloseWindow hook (bug 873589), so
    * handle the close in a different tick.
    */
-  Services.tm.currentThread.dispatch(makeInfallible(() => {
+  Services.tm.currentThread.dispatch(DevToolsUtils.makeInfallible(() => {
     /*
      * Scan the entire map for actors representing tabs that were in this
      * top-level window, and exit them.
      */
     for (let [browser, actor] of this._actorByBrowser) {
       /* The browser document of a closed window has no default view. */
       if (!browser.ownerDocument.defaultView) {
         this._handleActorClose(actor, browser);
@@ -729,29 +729,29 @@ BrowserTabActor.prototype = {
   },
 
   /**
    * Reload the page in this tab.
    */
   onReload: function(aRequest) {
     // Wait a tick so that the response packet can be dispatched before the
     // subsequent navigation event packet.
-    Services.tm.currentThread.dispatch(makeInfallible(() => {
+    Services.tm.currentThread.dispatch(DevToolsUtils.makeInfallible(() => {
       this.window.location.reload();
     }, "BrowserTabActor.prototype.onReload's delayed body"), 0);
     return {};
   },
 
   /**
    * Navigate this tab to a new location
    */
   onNavigateTo: function(aRequest) {
     // Wait a tick so that the response packet can be dispatched before the
     // subsequent navigation event packet.
-    Services.tm.currentThread.dispatch(makeInfallible(() => {
+    Services.tm.currentThread.dispatch(DevToolsUtils.makeInfallible(() => {
       this.window.location = aRequest.url;
     }, "BrowserTabActor.prototype.onNavigateTo's delayed body"), 0);
     return {};
   },
 
   /**
    * Reconfigure options.
    */
@@ -889,17 +889,17 @@ BrowserTabActor.prototype = {
   },
 
   /**
    * Handle location changes, by clearing the previous debuggees and enabling
    * debugging, which may have been disabled temporarily by the
    * DebuggerProgressListener.
    */
   onWindowCreated:
-  makeInfallible(function BTA_onWindowCreated(evt) {
+  DevToolsUtils.makeInfallible(function BTA_onWindowCreated(evt) {
     // pageshow events for non-persisted pages have already been handled by a
     // prior DOMWindowCreated event.
     if (!this._attached || (evt.type == "pageshow" && !evt.persisted)) {
       return;
     }
     if (evt.target === this.browser.contentDocument ) {
       this.threadActor.clearDebuggees();
       if (this.threadActor.dbg) {
@@ -1042,17 +1042,17 @@ function DebuggerProgressListener(aBrows
   this._tabActor = aBrowserTabActor;
   this._tabActor._tabbrowser.addProgressListener(this);
   let EventEmitter = devtools.require("devtools/toolkit/event-emitter");
   EventEmitter.decorate(this);
 }
 
 DebuggerProgressListener.prototype = {
   onStateChange:
-  makeInfallible(function DPL_onStateChange(aProgress, aRequest, aFlag, aStatus) {
+  DevToolsUtils.makeInfallible(function DPL_onStateChange(aProgress, aRequest, aFlag, aStatus) {
     let isStart = aFlag & Ci.nsIWebProgressListener.STATE_START;
     let isStop = aFlag & Ci.nsIWebProgressListener.STATE_STOP;
     let isDocument = aFlag & Ci.nsIWebProgressListener.STATE_IS_DOCUMENT;
     let isNetwork = aFlag & Ci.nsIWebProgressListener.STATE_IS_NETWORK;
     let isRequest = aFlag & Ci.nsIWebProgressListener.STATE_IS_REQUEST;
     let isWindow = aFlag & Ci.nsIWebProgressListener.STATE_IS_WINDOW;
 
     // Skip non-interesting states.
--- a/toolkit/devtools/server/child.js
+++ b/toolkit/devtools/server/child.js
@@ -2,17 +2,18 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 // Encapsulate in its own scope to allows loading this frame script
 // more than once.
 (function () {
-  const {DevToolsUtils} = Cu.import("resource://gre/modules/devtools/DevToolsUtils.jsm", {});
+  let { devtools } = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
+  const DevToolsUtils = devtools.require("devtools/toolkit/DevToolsUtils.js");
   const {DebuggerServer, ActorPool} = Cu.import("resource://gre/modules/devtools/dbg-server.jsm", {});
 
   if (!DebuggerServer.initialized) {
     DebuggerServer.init();
   }
 
   // In case of apps being loaded in parent process, DebuggerServer is already
   // initialized, but child specific actors are not registered.
--- a/toolkit/devtools/server/main.js
+++ b/toolkit/devtools/server/main.js
@@ -4,39 +4,41 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 /**
  * Toolkit glue for the remote debugging protocol, loaded into the
  * debugging global.
  */
+let DevToolsUtils = require("devtools/toolkit/DevToolsUtils.js");
 
 // Until all Debugger server code is converted to SDK modules,
 // imports Components.* alias from chrome module.
 var { Ci, Cc, CC, Cu, Cr } = require("chrome");
 // On B2G, `this` != Global scope, so `Ci` won't be binded on `this`
 // (i.e. this.Ci is undefined) Then later, when using loadSubScript,
 // Ci,... won't be defined for sub scripts.
 this.Ci = Ci;
 this.Cc = Cc;
 this.CC = CC;
 this.Cu = Cu;
 this.Cr = Cr;
+this.DevToolsUtils = DevToolsUtils;
+
 // Overload `Components` to prevent SDK loader exception on Components
 // object usage
 Object.defineProperty(this, "Components", {
   get: function () require("chrome").components
 });
 
 const DBG_STRINGS_URI = "chrome://global/locale/devtools/debugger.properties";
 
 const nsFile = CC("@mozilla.org/file/local;1", "nsIFile", "initWithPath");
 Cu.import("resource://gre/modules/reflect.jsm");
-Cu.import("resource://gre/modules/devtools/DevToolsUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 let wantLogging = Services.prefs.getBoolPref("devtools.debugger.log");
 
 Cu.import("resource://gre/modules/jsdebugger.jsm");
 addDebuggerToGlobal(this);
 
 function loadSubScript(aURL)
@@ -57,18 +59,16 @@ let {defer, resolve, reject, promised, a
 this.defer = defer;
 this.resolve = resolve;
 this.reject = reject;
 this.promised = promised;
 this.all = all;
 
 Cu.import("resource://gre/modules/devtools/SourceMap.jsm");
 
-loadSubScript.call(this, "resource://gre/modules/devtools/DevToolsUtils.js");
-
 function dumpn(str) {
   if (wantLogging) {
     dump("DBG-SERVER: " + str + "\n");
   }
 }
 this.dumpn = dumpn;
 
 function dbg_assert(cond, e) {
@@ -522,17 +522,17 @@ var DebuggerServer = {
 
     let transport = new ChildDebuggerTransport(aMessageManager, aPrefix);
     return this._onConnection(transport, aPrefix, true);
   },
 
   // nsIServerSocketListener implementation
 
   onSocketAccepted:
-  makeInfallible(function DS_onSocketAccepted(aSocket, aTransport) {
+  DevToolsUtils.makeInfallible(function DS_onSocketAccepted(aSocket, aTransport) {
     if (Services.prefs.getBoolPref("devtools.debugger.prompt-connection") && !this._allowConnection()) {
       return;
     }
     dumpn("New debugging connection on " + aTransport.host + ":" + aTransport.port);
 
     let input = aTransport.openInputStream(0, 0, 0);
     let output = aTransport.openOutputStream(0, 0, 0);
     let transport = new DebuggerTransport(input, output);
@@ -926,17 +926,17 @@ DebuggerServerConnection.prototype = {
       if (pool.has(aActorID)) {
         return pool;
       }
     }
     return null;
   },
 
   _unknownError: function DSC__unknownError(aPrefix, aError) {
-    let errorString = aPrefix + ": " + safeErrorString(aError);
+    let errorString = aPrefix + ": " + DevToolsUtils.safeErrorString(aError);
     Cu.reportError(errorString);
     dumpn(errorString);
     return {
       error: "unknownError",
       message: errorString
     };
   },
 
--- a/toolkit/devtools/server/tests/unit/head_dbg.js
+++ b/toolkit/devtools/server/tests/unit/head_dbg.js
@@ -10,17 +10,18 @@ const Cr = Components.results;
 Cu.import("resource://gre/modules/Services.jsm");
 
 // Always log packets when running tests. runxpcshelltests.py will throw
 // the output away anyway, unless you give it the --verbose flag.
 Services.prefs.setBoolPref("devtools.debugger.log", true);
 // Enable remote debugging for the relevant tests.
 Services.prefs.setBoolPref("devtools.debugger.remote-enabled", true);
 
-Cu.import("resource://gre/modules/devtools/DevToolsUtils.jsm");
+const { devtools } = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
+const DevToolsUtils = devtools.require("devtools/toolkit/DevToolsUtils.js");
 
 function tryImport(url) {
   try {
     Cu.import(url);
   } catch (e) {
     dump("Error importing " + url + "\n");
     dump(DevToolsUtils.safeErrorString(e) + "\n");
     throw e;
--- a/toolkit/devtools/server/tests/unit/test_dbgsocket.js
+++ b/toolkit/devtools/server/tests/unit/test_dbgsocket.js
@@ -1,16 +1,13 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 Cu.import("resource://gre/modules/devtools/dbg-server.jsm");
 Cu.import("resource://gre/modules/devtools/dbg-client.jsm");
-Cu.import("resource://gre/modules/devtools/DevToolsUtils.jsm");
-
-var { safeErrorString } = DevToolsUtils;
 
 let port = 2929;
 
 function run_test()
 {
   do_print("Starting test at " + new Date().toTimeString());
   initTestDebuggerServer();
 
@@ -139,17 +136,17 @@ function makeInfallible(aHandler, aName)
   return function (/* arguments */) {
     try {
       return aHandler.apply(this, arguments);
     } catch (ex) {
       let msg = "Handler function ";
       if (aName) {
         msg += aName + " ";
       }
-      msg += "threw an exception: " + safeErrorString(ex);
+      msg += "threw an exception: " + DevToolsUtils.safeErrorString(ex);
       if (ex.stack) {
         msg += "\nCall stack:\n" + ex.stack;
       }
 
       do_print(msg + "\n");
 
       if (Cu.reportError) {
         /*
--- a/toolkit/devtools/server/tests/unit/test_dbgsocket_connection_drop.js
+++ b/toolkit/devtools/server/tests/unit/test_dbgsocket_connection_drop.js
@@ -5,17 +5,16 @@
 
 /**
  * Bug 755412 - checks if the server drops the connection on an improperly
  * framed packet, i.e. when the length header is invalid.
  */
 
 Cu.import("resource://gre/modules/devtools/dbg-server.jsm");
 Cu.import("resource://gre/modules/devtools/dbg-client.jsm");
-Cu.import("resource://gre/modules/devtools/DevToolsUtils.jsm");
 
 let port = 2929;
 
 function run_test()
 {
   do_print("Starting test at " + new Date().toTimeString());
   initTestDebuggerServer();
 
--- a/toolkit/devtools/server/transport.js
+++ b/toolkit/devtools/server/transport.js
@@ -89,17 +89,17 @@ DebuggerTransport.prototype = {
   _flushOutgoing: function DT_flushOutgoing() {
     if (this._outgoing.length > 0) {
       var threadManager = Cc["@mozilla.org/thread-manager;1"].getService();
       this._output.asyncWait(this, 0, 0, threadManager.currentThread);
     }
   },
 
   onOutputStreamReady:
-  makeInfallible(function DT_onOutputStreamReady(aStream) {
+  DevToolsUtils.makeInfallible(function DT_onOutputStreamReady(aStream) {
     let written = 0;
     try {
       written = aStream.write(this._outgoing, this._outgoing.length);
     } catch(e if e.result == Components.results.NS_BASE_STREAM_CLOSED) {
       dumpn("Connection closed.");
       this.close();
       return;
     }
@@ -116,30 +116,30 @@ DebuggerTransport.prototype = {
     let pump = Cc["@mozilla.org/network/input-stream-pump;1"]
       .createInstance(Ci.nsIInputStreamPump);
     pump.init(this._input, -1, -1, 0, 0, false);
     pump.asyncRead(this, null);
   },
 
   // nsIStreamListener
   onStartRequest:
-  makeInfallible(function DT_onStartRequest(aRequest, aContext) {},
+  DevToolsUtils.makeInfallible(function DT_onStartRequest(aRequest, aContext) {},
                  "DebuggerTransport.prototype.onStartRequest"),
 
   onStopRequest:
-  makeInfallible(function DT_onStopRequest(aRequest, aContext, aStatus) {
+  DevToolsUtils.makeInfallible(function DT_onStopRequest(aRequest, aContext, aStatus) {
     this.close();
     if (this.hooks) {
       this.hooks.onClosed(aStatus);
       this.hooks = null;
     }
   }, "DebuggerTransport.prototype.onStopRequest"),
 
   onDataAvailable:
-  makeInfallible(function DT_onDataAvailable(aRequest, aContext,
+  DevToolsUtils.makeInfallible(function DT_onDataAvailable(aRequest, aContext,
                                              aStream, aOffset, aCount) {
     this._incoming += NetUtil.readInputStreamToString(aStream,
                                                       aStream.available());
     while (this._processIncoming()) {};
   }, "DebuggerTransport.prototype.onDataAvailable"),
 
   /**
    * Process incoming packets. Returns true if a packet has been received, either
@@ -189,17 +189,17 @@ DebuggerTransport.prototype = {
       dump(msg + "\n");
       return true;
     }
 
     if (wantLogging) {
       dumpn("Got: " + JSON.stringify(parsed, null, 2));
     }
     let self = this;
-    Services.tm.currentThread.dispatch(makeInfallible(function() {
+    Services.tm.currentThread.dispatch(DevToolsUtils.makeInfallible(function() {
       // Ensure the hooks are still around by the time this runs (they will go
       // away when the transport is closed).
       if (self.hooks) {
         self.hooks.onPacket(parsed);
       }
     }, "DebuggerTransport instance's this.hooks.onPacket"), 0);
 
     return true;
@@ -244,17 +244,17 @@ LocalDebuggerTransport.prototype = {
         dumpn("Packet " + serial + " sent from " + uneval(aPacket.from));
       } else if (aPacket.to) {
         dumpn("Packet " + serial + " sent to " + uneval(aPacket.to));
       }
     }
     this._deepFreeze(aPacket);
     let other = this.other;
     if (other) {
-      Services.tm.currentThread.dispatch(makeInfallible(function() {
+      Services.tm.currentThread.dispatch(DevToolsUtils.makeInfallible(function() {
         // Avoid the cost of JSON.stringify() when logging is disabled.
         if (wantLogging) {
           dumpn("Received packet " + serial + ": " + JSON.stringify(aPacket, null, 2));
         }
         if (other.hooks) {
           other.hooks.onPacket(aPacket);
         }
       }, "LocalDebuggerTransport instance's this.other.hooks.onPacket"), 0);
--- a/toolkit/mozapps/downloads/nsHelperAppDlg.js
+++ b/toolkit/mozapps/downloads/nsHelperAppDlg.js
@@ -1,10 +1,10 @@
-/* -*- Mode: javascript; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=2 et sw=2 tw=80: */
+/* -*- Mode: javascript; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2; js-indent-level: 2; -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /*
 # 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/.
 */
 
 Components.utils.import("resource://gre/modules/Services.jsm");
 
@@ -30,22 +30,19 @@ function nsUnknownContentTypeDialogProgr
   this.helperAppDlg = aHelperAppDialog;
 }
 
 nsUnknownContentTypeDialogProgressListener.prototype = {
   // nsIWebProgressListener methods.
   // Look for error notifications and display alert to user.
   onStatusChange: function( aWebProgress, aRequest, aStatus, aMessage ) {
     if ( aStatus != Components.results.NS_OK ) {
-      // Get prompt service.
-      var prompter = Components.classes[ "@mozilla.org/embedcomp/prompt-service;1" ]
-                               .getService( Components.interfaces.nsIPromptService );
       // Display error alert (using text supplied by back-end).
       // FIXME this.dialog is undefined?
-      prompter.alert( this.dialog, this.helperAppDlg.mTitle, aMessage );
+      Services.prompt.alert( this.dialog, this.helperAppDlg.mTitle, aMessage );
       // Close the dialog.
       this.helperAppDlg.onCancel();
       if ( this.helperAppDlg.mDialog ) {
         this.helperAppDlg.mDialog.close();
       }
     }
   },
 
@@ -177,41 +174,56 @@ nsUnknownContentTypeDialog.prototype = {
     // Hook up utility functions.
     this.getSpecialFolderKey = this.mDialog.getSpecialFolderKey;
 
     // Watch for error notifications.
     var progressListener = new nsUnknownContentTypeDialogProgressListener(this);
     this.mLauncher.setWebProgressListener(progressListener);
   },
 
+  //
+  // displayBadPermissionAlert()
+  //
+  // Diplay an alert panel about the bad permission of folder/directory.
+  //
+  displayBadPermissionAlert: function () {
+    let bundle =
+      Services.strings.createBundle("chrome://mozapps/locale/downloads/unknownContentType.properties");
+
+    Services.prompt.alert(this.dialog,
+                   bundle.GetStringFromName("badPermissions.title"),
+                   bundle.GetStringFromName("badPermissions"));
+  },
+
   // promptForSaveToFile:  Display file picker dialog and return selected file.
   //                       This is called by the External Helper App Service
   //                       after the ucth dialog calls |saveToDisk| with a null
   //                       target filename (no target, therefore user must pick).
   //
   //                       Alternatively, if the user has selected to have all
   //                       files download to a specific location, return that
   //                       location and don't ask via the dialog.
   //
   // Note - this function is called without a dialog, so it cannot access any part
   // of the dialog XUL as other functions on this object do.
+
   promptForSaveToFile: function(aLauncher, aContext, aDefaultFile, aSuggestedFileExtension, aForcePrompt) {
     throw new Components.Exception("Async version must be used", Components.results.NS_ERROR_NOT_AVAILABLE);
   },
 
   promptForSaveToFileAsync: function(aLauncher, aContext, aDefaultFile, aSuggestedFileExtension, aForcePrompt) {
     var result = null;
 
     this.mLauncher = aLauncher;
 
     let prefs = Components.classes["@mozilla.org/preferences-service;1"]
                           .getService(Components.interfaces.nsIPrefBranch);
-    let bundle = Components.classes["@mozilla.org/intl/stringbundle;1"].
-                            getService(Components.interfaces.nsIStringBundleService).
-                            createBundle("chrome://mozapps/locale/downloads/unknownContentType.properties");
+    let bundle =
+      Services.strings
+              .createBundle("chrome://mozapps/locale/downloads/unknownContentType.properties");
 
     Task.spawn(function() {
       if (!aForcePrompt) {
         // Check to see if the user wishes to auto save to the default download
         // folder without prompting. Note that preference might not be set.
         let autodownload = false;
         try {
           autodownload = prefs.getBoolPref(PREF_BD_USEDOWNLOADDIR);
@@ -221,32 +233,23 @@ nsUnknownContentTypeDialog.prototype = {
           // Retrieve the user's default download directory
           let preferredDir = yield Downloads.getPreferredDownloadsDirectory();
           let defaultFolder = new FileUtils.File(preferredDir);
 
           try {
             result = this.validateLeafName(defaultFolder, aDefaultFile, aSuggestedFileExtension);
           }
           catch (ex) {
-            if (ex.result == Components.results.NS_ERROR_FILE_ACCESS_DENIED) {
-              let prompter = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].
-                                        getService(Components.interfaces.nsIPromptService);
-
-              // Display error alert (using text supplied by back-end)
-              prompter.alert(this.dialog,
-                             bundle.GetStringFromName("badPermissions.title"),
-                             bundle.GetStringFromName("badPermissions"));
-
-              aLauncher.saveDestinationAvailable(null);
-              return;
-            }
+            // When the default download directory is write-protected,
+            // prompt the user for a different target file.
           }
 
           // Check to make sure we have a valid directory, otherwise, prompt
           if (result) {
+            // This path is taken when we have a writable default download directory.
             aLauncher.saveDestinationAvailable(result);
             return;
           }
         }
       }
 
       // Use file picker to show dialog.
       var nsIFilePicker = Components.interfaces.nsIFilePicker;
@@ -273,17 +276,17 @@ nsUnknownContentTypeDialog.prototype = {
       if (aSuggestedFileExtension) {
         wildCardExtension += aSuggestedFileExtension;
         picker.appendFilter(this.mLauncher.MIMEInfo.description, wildCardExtension);
       }
 
       picker.appendFilters( nsIFilePicker.filterAll );
 
       // Default to lastDir if it is valid, otherwise use the user's default
-      // downloads directory.  getPreferredDownloadsDirectory should always 
+      // downloads directory.  getPreferredDownloadsDirectory should always
       // return a valid directory path, so we can safely default to it.
       let preferredDir = yield Downloads.getPreferredDownloadsDirectory();
       picker.displayDirectory = new FileUtils.File(preferredDir);
 
       gDownloadLastDir.getFileAsync(aLauncher.source, function LastDirCallback(lastDir) {
         if (lastDir && isUsableDirectory(lastDir))
           picker.displayDirectory = lastDir;
 
@@ -301,23 +304,41 @@ nsUnknownContentTypeDialog.prototype = {
         if (result) {
           try {
             // Remove the file so that it's not there when we ensure non-existence later;
             // this is safe because for the file to exist, the user would have had to
             // confirm that he wanted the file overwritten.
             if (result.exists())
               result.remove(false);
           }
-          catch (e) { }
+          catch (ex) {
+            // As it turns out, the failure to remove the file, for example due to
+            // permission error, will be handled below eventually somehow.
+          }
+
           var newDir = result.parent.QueryInterface(Components.interfaces.nsILocalFile);
 
           // Do not store the last save directory as a pref inside the private browsing mode
           gDownloadLastDir.setFile(aLauncher.source, newDir);
 
-          result = this.validateLeafName(newDir, result.leafName, null);
+          try {
+            result = this.validateLeafName(newDir, result.leafName, null);
+          }
+          catch (ex) {
+            // When the chosen download directory is write-protected,
+            // display an informative error message.
+            // In all cases, download will be stopped.
+
+            if (ex.result == Components.results.NS_ERROR_FILE_ACCESS_DENIED) {
+              this.displayBadPermissionAlert();
+              aLauncher.saveDestinationAvailable(null);
+              return;
+            }
+
+          }
         }
         aLauncher.saveDestinationAvailable(result);
       }.bind(this));
     }.bind(this)).then(null, Components.utils.reportError);
   },
 
   /**
    * Ensures that a local folder/file combination does not already exist in
@@ -329,30 +350,35 @@ nsUnknownContentTypeDialog.prototype = {
    * @param   aLeafName
    *          the string name of the file (may be empty if no name is known,
    *          in which case a name will be chosen)
    * @param   aFileExt
    *          the extension of the file, if one is known; this will be ignored
    *          if aLeafName is non-empty
    * @return  nsILocalFile
    *          the created file
+   * @throw   an error such as permission doesn't allow creation of
+   *          file, etc.
    */
   validateLeafName: function (aLocalFolder, aLeafName, aFileExt)
   {
-    if (!(aLocalFolder && isUsableDirectory(aLocalFolder)))
-      return null;
-
+    if (!(aLocalFolder && isUsableDirectory(aLocalFolder))) {
+      throw new Components.Exception("Destination directory non-existing or permission error",
+                                     Components.results.NS_ERROR_FILE_ACCESS_DENIED);
+    }
     // Remove any leading periods, since we don't want to save hidden files
     // automatically.
     aLeafName = aLeafName.replace(/^\.+/, "");
 
     if (aLeafName == "")
       aLeafName = "unnamed" + (aFileExt ? "." + aFileExt : "");
     aLocalFolder.append(aLeafName);
 
+    // The following assignment can throw an exception, but
+    // is now caught properly in the caller of validateLeafName.
     var createdFile = DownloadPaths.createNiceUniqueFile(aLocalFolder);
 
 #ifdef XP_WIN
     let ext;
     try {
       // We can fail here if there's no primary extension set
       ext = "." + this.mLauncher.MIMEInfo.primaryExtension;
     } catch (e) { }
@@ -842,18 +868,17 @@ nsUnknownContentTypeDialog.prototype = {
     // Verify typed app path, if necessary.
     if (this.useOtherHandler) {
       var helperApp = this.helperAppChoice();
       if (!helperApp || !helperApp.executable ||
           !helperApp.executable.exists()) {
         // Show alert and try again.
         var bundle = this.dialogElement("strings");
         var msg = bundle.getFormattedString("badApp", [this.dialogElement("otherHandler").getAttribute("path")]);
-        var svc = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].getService(Components.interfaces.nsIPromptService);
-        svc.alert(this.mDialog, bundle.getString("badApp.title"), msg);
+        Services.prompt.alert(this.mDialog, bundle.getString("badApp.title"), msg);
 
         // Disable the OK button.
         this.mDialog.document.documentElement.getButton("accept").disabled = true;
         this.dialogElement("mode").focus();
 
         // Clear chosen application.
         this.chosenApp = null;
 
--- a/toolkit/mozapps/plugins/content/pluginProblemContent.css
+++ b/toolkit/mozapps/plugins/content/pluginProblemContent.css
@@ -48,17 +48,16 @@ html|applet:not([height]), html|applet[h
   /* used to block inherited properties */
   text-transform: none;
   text-indent: 0;
   cursor: initial;
   white-space: initial;
   word-spacing: initial;
   letter-spacing: initial;
   line-height: initial;
-  z-index: 2147483647;
   position: relative;
 }
 
 /* Initialize the overlay with visibility:hidden to prevent flickering if
 * the plugin is too small to show the overlay */
 .mainBox > .hoverBox,
 .mainBox > .closeIcon {
   visibility: hidden;
--- a/tools/profiler/platform.h
+++ b/tools/profiler/platform.h
@@ -70,17 +70,17 @@
     } while (0)
 # define LOGF(format, ...) \
     do { if (moz_profiler_verbose()) fprintf(stderr, "Profiler: " format \
                                              "\n", __VA_ARGS__);        \
     } while (0)
 
 #endif
 
-#if defined(XP_MACOSX) || defined(XP_WIN)
+#if defined(XP_MACOSX) || defined(XP_WIN) || defined(XP_LINUX)
 #define ENABLE_SPS_LEAF_DATA
 #endif
 
 extern mozilla::TimeStamp sStartTime;
 
 typedef uint8_t* Address;
 
 // ----------------------------------------------------------------------------
--- a/widget/EventForwards.h
+++ b/widget/EventForwards.h
@@ -64,13 +64,13 @@ struct EventFlags;
 
 // TextEvents.h
 struct AlternativeCharCode;
 
 // TextRange.h
 struct TextRangeStyle;
 struct TextRange;
 
-typedef TextRange* TextRangeArray;
+class TextRangeArray;
 
 } // namespace mozilla
 
 #endif // mozilla_EventForwards_h__
--- a/widget/TextEvents.h
+++ b/widget/TextEvents.h
@@ -176,33 +176,29 @@ class WidgetTextEvent : public WidgetGUI
 {
 private:
   friend class dom::PBrowserParent;
   friend class dom::PBrowserChild;
   friend class plugins::PPluginInstanceChild;
 
   WidgetTextEvent()
     : mSeqno(kLatestSeqno)
-    , rangeCount(0)
-    , rangeArray(nullptr)
     , isChar(false)
   {
   }
 
 public:
   uint32_t mSeqno;
 
 public:
   virtual WidgetTextEvent* AsTextEvent() MOZ_OVERRIDE { return this; }
 
   WidgetTextEvent(bool aIsTrusted, uint32_t aMessage, nsIWidget* aWidget)
     : WidgetGUIEvent(aIsTrusted, aMessage, aWidget, NS_TEXT_EVENT)
     , mSeqno(kLatestSeqno)
-    , rangeCount(0)
-    , rangeArray(nullptr)
     , isChar(false)
   {
   }
 
   virtual WidgetEvent* Duplicate() const MOZ_OVERRIDE
   {
     MOZ_ASSERT(eventStructType == NS_TEXT_EVENT,
                "Duplicate() must be overridden by sub class");
@@ -210,46 +206,46 @@ public:
     WidgetTextEvent* result = new WidgetTextEvent(false, message, nullptr);
     result->AssignTextEventData(*this, true);
     result->mFlags = mFlags;
     return result;
   }
 
   // The composition string or the commit string.
   nsString theText;
-  // Count of rangeArray.
-  uint32_t rangeCount;
-  // Pointer to the first item of the ranges (clauses).
-  // Note that the range array may not specify a caret position; in that
-  // case there will be no range of type NS_TEXTRANGE_CARETPOSITION in the
-  // array.
-  TextRangeArray rangeArray;
   // Indicates whether the event signifies printable text.
   // XXX This is not a standard, and most platforms don't set this properly.
   //     So, perhaps, we can get rid of this.
   bool isChar;
 
+  nsRefPtr<TextRangeArray> mRanges;
+
   void AssignTextEventData(const WidgetTextEvent& aEvent, bool aCopyTargets)
   {
     AssignGUIEventData(aEvent, aCopyTargets);
 
     isChar = aEvent.isChar;
 
     // Currently, we don't need to copy the other members because they are
     // for internal use only (not available from JS).
   }
 
   bool IsComposing() const
   {
-    for (uint32_t i = 0; i < rangeCount; i++) {
-      if (rangeArray[i].IsClause()) {
-        return true;
-      }
-    }
-    return false;
+    return mRanges && mRanges->IsComposing();
+  }
+
+  uint32_t TargetClauseOffset() const
+  {
+    return mRanges ? mRanges->TargetClauseOffset() : 0;
+  }
+
+  uint32_t RangeCount() const
+  {
+    return mRanges ? mRanges->Length() : 0;
   }
 };
 
 /******************************************************************************
  * mozilla::WidgetCompositionEvent
  ******************************************************************************/
 
 class WidgetCompositionEvent : public WidgetGUIEvent
--- a/widget/TextRange.h
+++ b/widget/TextRange.h
@@ -3,18 +3,20 @@
  * 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 mozilla_TextRage_h_
 #define mozilla_TextRage_h_
 
 #include <stdint.h>
 
+#include "nsAutoPtr.h"
 #include "nsColor.h"
 #include "nsStyleConsts.h"
+#include "nsTArray.h"
 
 namespace mozilla {
 
 /******************************************************************************
  * mozilla::TextRangeStyle
  ******************************************************************************/
 
 struct TextRangeStyle
@@ -119,17 +121,16 @@ struct TextRangeStyle
   nscolor mBackgroundColor;  // DEFINED_BACKGROUND_COLOR
   nscolor mUnderlineColor;   // DEFINED_UNDERLINE_COLOR
 };
 
 /******************************************************************************
  * mozilla::TextRange
  ******************************************************************************/
 
-// Sync with nsIPrivateTextRange.h when you change these constants.
 #define NS_TEXTRANGE_CARETPOSITION         0x01
 #define NS_TEXTRANGE_RAWINPUT              0x02
 #define NS_TEXTRANGE_SELECTEDRAWTEXT       0x03
 #define NS_TEXTRANGE_CONVERTEDTEXT         0x04
 #define NS_TEXTRANGE_SELECTEDCONVERTEDTEXT 0x05
 
 struct TextRange
 {
@@ -154,17 +155,42 @@ struct TextRange
                  mRangeType <= NS_TEXTRANGE_SELECTEDCONVERTEDTEXT,
                "Invalid range type");
     return mRangeType != NS_TEXTRANGE_CARETPOSITION;
   }
 };
 
 /******************************************************************************
  * mozilla::TextRangeArray
- *
- * XXX This should be replaced with nsTArray<TextRange>.
  ******************************************************************************/
+class TextRangeArray MOZ_FINAL : public nsAutoTArray<TextRange, 10>
+{
+  NS_INLINE_DECL_REFCOUNTING(TextRangeArray)
 
-typedef TextRange* TextRangeArray;
+public:
+  bool IsComposing() const
+  {
+    for (uint32_t i = 0; i < Length(); ++i) {
+      if (ElementAt(i).IsClause()) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  // Returns target clase offset.  If there are selected clauses, this returns
+  // the first selected clause offset.  Otherwise, 0.
+  uint32_t TargetClauseOffset() const
+  {
+    for (uint32_t i = 0; i < Length(); ++i) {
+      const TextRange& range = ElementAt(i);
+      if (range.mRangeType == NS_TEXTRANGE_SELECTEDRAWTEXT ||
+          range.mRangeType == NS_TEXTRANGE_SELECTEDCONVERTEDTEXT) {
+        return range.mStartOffset;
+      }
+    }
+    return 0;
+  }
+};
 
 } // namespace mozilla
 
 #endif // mozilla_TextRage_h_
--- a/widget/android/nsWindow.cpp
+++ b/widget/android/nsWindow.cpp
@@ -171,16 +171,17 @@ nsWindow::DumpWindows(const nsTArray<nsW
 nsWindow::nsWindow() :
     mIsVisible(false),
     mParent(nullptr),
     mFocus(nullptr),
     mIMEComposing(false),
     mIMEMaskSelectionUpdate(false),
     mIMEMaskTextUpdate(false),
     mIMEMaskEventsCount(1), // Mask IME events since there's no focus yet
+    mIMERanges(new TextRangeArray()),
     mIMEUpdatingContext(false),
     mIMESelectionChanged(false)
 {
 }
 
 nsWindow::~nsWindow()
 {
     gTopLevelWindows.RemoveElement(this);
@@ -1982,17 +1983,17 @@ nsWindow::OnIMEEvent(AndroidGeckoEvent *
             range.mRangeStyle.mLineStyle = ae->RangeLineStyle();
             range.mRangeStyle.mIsBoldLine = ae->RangeBoldLine();
             range.mRangeStyle.mForegroundColor =
                     ConvertAndroidColor(uint32_t(ae->RangeForeColor()));
             range.mRangeStyle.mBackgroundColor =
                     ConvertAndroidColor(uint32_t(ae->RangeBackColor()));
             range.mRangeStyle.mUnderlineColor =
                     ConvertAndroidColor(uint32_t(ae->RangeLineColor()));
-            mIMERanges.AppendElement(range);
+            mIMERanges->AppendElement(range);
         }
         break;
     case AndroidGeckoEvent::IME_UPDATE_COMPOSITION:
         {
             /*
                 Update the composition from ae->Start() to ae->End() using
                   information from added ranges. This is only used for
                   visual indication and does not affect the text content.
@@ -2005,18 +2006,18 @@ nsWindow::OnIMEEvent(AndroidGeckoEvent *
             */
             AutoIMEMask selMask(mIMEMaskSelectionUpdate);
             AutoIMEMask textMask(mIMEMaskTextUpdate);
             RemoveIMEComposition();
 
             WidgetTextEvent event(true, NS_TEXT_TEXT, this);
             InitEvent(event, nullptr);
 
-            event.rangeArray = mIMERanges.Elements();
-            event.rangeCount = mIMERanges.Length();
+            event.mRanges = new TextRangeArray();
+            mIMERanges.swap(event.mRanges);
 
             {
                 WidgetSelectionEvent event(true, NS_SELECTION_SET, this);
                 InitEvent(event, nullptr);
                 event.mOffset = uint32_t(ae->Start());
                 event.mLength = uint32_t(ae->End() - ae->Start());
                 event.mExpandToClusterBoundary = false;
                 DispatchEvent(&event);
@@ -2043,21 +2044,20 @@ nsWindow::OnIMEEvent(AndroidGeckoEvent *
                 compositionUpdate.data = event.theText;
                 DispatchEvent(&compositionUpdate);
             }
 
 #ifdef DEBUG_ANDROID_IME
             const NS_ConvertUTF16toUTF8 theText8(event.theText);
             const char* text = theText8.get();
             ALOGIME("IME: IME_SET_TEXT: text=\"%s\", length=%u, range=%u",
-                    text, event.theText.Length(), mIMERanges.Length());
+                    text, event.theText.Length(), event.mRanges->Length());
 #endif // DEBUG_ANDROID_IME
 
             DispatchEvent(&event);
-            mIMERanges.Clear();
 
             // Notify SelectionHandler of final caret position
             // Required in cases of keyboards providing autoCorrections
             AndroidGeckoEvent* broadcastEvent = AndroidGeckoEvent::MakeBroadcastEvent(
                 NS_LITERAL_CSTRING("TextSelection:UpdateCaretPos"),
                 NS_LITERAL_CSTRING(""));
             nsAppShell::gAppShell->PostEvent(broadcastEvent);
         }
@@ -2069,17 +2069,17 @@ nsWindow::OnIMEEvent(AndroidGeckoEvent *
              *    visual indication and does not affect the text content.
              *
              *  Selection and text updates are masked so the result of
              *    temporary events are not passed on to Java
              */
             AutoIMEMask selMask(mIMEMaskSelectionUpdate);
             AutoIMEMask textMask(mIMEMaskTextUpdate);
             RemoveIMEComposition();
-            mIMERanges.Clear();
+            mIMERanges->Clear();
         }
         break;
     }
 }
 
 nsWindow *
 nsWindow::FindWindowForPoint(const nsIntPoint& pt)
 {
--- a/widget/android/nsWindow.h
+++ b/widget/android/nsWindow.h
@@ -192,17 +192,17 @@ protected:
     double mLastDist;
 
     nsCOMPtr<nsIIdleServiceInternal> mIdleService;
 
     bool mIMEComposing;
     bool mIMEMaskSelectionUpdate, mIMEMaskTextUpdate;
     int32_t mIMEMaskEventsCount; // Mask events when > 0
     nsString mIMEComposingText;
-    nsAutoTArray<mozilla::TextRange, 4> mIMERanges;
+    nsRefPtr<mozilla::TextRangeArray> mIMERanges;
     bool mIMEUpdatingContext;
     nsAutoTArray<mozilla::AndroidGeckoEvent, 8> mIMEKeyEvents;
 
     struct IMEChange {
         int32_t mStart, mOldEnd, mNewEnd;
 
         IMEChange() :
             mStart(-1), mOldEnd(-1), mNewEnd(-1)
--- a/widget/cocoa/TextInputHandler.h
+++ b/widget/cocoa/TextInputHandler.h
@@ -1062,31 +1062,28 @@ private:
    *                              NSUnderlineStyleAttributeName ranges you with
    *                              to know.
    * @return                      The count of NSUnderlineStyleAttributeName
    *                              ranges in aAttrString.
    */
   uint32_t GetRangeCount(NSAttributedString *aString);
 
   /**
-   * SetTextRangeList() appends text ranges to aTextRangeList.
+   * CreateTextRangeArray() returns text ranges for clauses and/or caret.
    *
-   * @param aTextRangeList        When SetTextRangeList() returns, this will
-   *                              be set to the NSUnderlineStyleAttributeName
-   *                              ranges in aAttrString.  Note that if you pass
-   *                              in a large enough auto-range instance for most
-   *                              cases (e.g., nsAutoTArray<TextRange, 4>),
-   *                              it prevents memory fragmentation.
    * @param aAttrString           An NSAttributedString instance which indicates
    *                              current composition string.
    * @param aSelectedRange        Current selected range (or caret position).
+   * @return                      The result is set to the
+   *                              NSUnderlineStyleAttributeName ranges in
+   *                              aAttrString.
    */
-  void SetTextRangeList(nsTArray<TextRange>& aTextRangeList,
-                        NSAttributedString *aAttrString,
-                        NSRange& aSelectedRange);
+  already_AddRefed<mozilla::TextRangeArray>
+    CreateTextRangeArray(NSAttributedString *aAttrString,
+                         NSRange& aSelectedRange);
 
   /**
    * InitCompositionEvent() initializes aCompositionEvent.
    *
    * @param aCompositionEvent     A composition event which you want to
    *                              initialize.
    */
   void InitCompositionEvent(WidgetCompositionEvent& aCompositionEvent);
--- a/widget/cocoa/TextInputHandler.mm
+++ b/widget/cocoa/TextInputHandler.mm
@@ -2628,68 +2628,71 @@ IMEInputHandler::GetRangeCount(NSAttribu
     ("%p IMEInputHandler::GetRangeCount, aAttrString=\"%s\", count=%llu",
      this, GetCharacters([aAttrString string]), count));
 
   return count;
 
   NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(0);
 }
 
-void
-IMEInputHandler::SetTextRangeList(nsTArray<TextRange>& aTextRangeList,
-                                  NSAttributedString *aAttrString,
-                                  NSRange& aSelectedRange)
+already_AddRefed<mozilla::TextRangeArray>
+IMEInputHandler::CreateTextRangeArray(NSAttributedString *aAttrString,
+                                      NSRange& aSelectedRange)
 {
-  NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
+  NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
 
   // Convert the Cocoa range into the TextRange Array used in Gecko.
   // Iterate through the attributed string and map the underline attribute to
   // Gecko IME textrange attributes.  We may need to change the code here if
   // we change the implementation of validAttributesForMarkedText.
   NSRange limitRange = NSMakeRange(0, [aAttrString length]);
   uint32_t rangeCount = GetRangeCount(aAttrString);
+  nsRefPtr<mozilla::TextRangeArray> textRangeArray =
+                                      new mozilla::TextRangeArray();
   for (uint32_t i = 0; i < rangeCount && limitRange.length > 0; i++) {
     NSRange effectiveRange;
     id attributeValue = [aAttrString attribute:NSUnderlineStyleAttributeName
                                        atIndex:limitRange.location
                          longestEffectiveRange:&effectiveRange
                                        inRange:limitRange];
 
     TextRange range;
     range.mStartOffset = effectiveRange.location;
     range.mEndOffset = NSMaxRange(effectiveRange);
     range.mRangeType =
       ConvertToTextRangeType([attributeValue intValue], aSelectedRange);
-    aTextRangeList.AppendElement(range);
+    textRangeArray->AppendElement(range);
 
     PR_LOG(gLog, PR_LOG_ALWAYS,
-      ("%p IMEInputHandler::SetTextRangeList, "
+      ("%p IMEInputHandler::CreateTextRangeArray, "
        "range={ mStartOffset=%llu, mEndOffset=%llu, mRangeType=%s }",
        this, range.mStartOffset, range.mEndOffset,
        GetRangeTypeName(range.mRangeType)));
 
     limitRange =
       NSMakeRange(NSMaxRange(effectiveRange), 
                   NSMaxRange(limitRange) - NSMaxRange(effectiveRange));
   }
 
   // Get current caret position.
   TextRange range;
   range.mStartOffset = aSelectedRange.location + aSelectedRange.length;
   range.mEndOffset = range.mStartOffset;
   range.mRangeType = NS_TEXTRANGE_CARETPOSITION;
-  aTextRangeList.AppendElement(range);
+  textRangeArray->AppendElement(range);
 
   PR_LOG(gLog, PR_LOG_ALWAYS,
-    ("%p IMEInputHandler::SetTextRangeList, "
+    ("%p IMEInputHandler::CreateTextRangeArray, "
      "range={ mStartOffset=%llu, mEndOffset=%llu, mRangeType=%s }",
      this, range.mStartOffset, range.mEndOffset,
      GetRangeTypeName(range.mRangeType)));
 
-  NS_OBJC_END_TRY_ABORT_BLOCK;
+  return textRangeArray.forget();
+
+  NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
 }
 
 bool
 IMEInputHandler::DispatchTextEvent(const nsString& aText,
                                    NSAttributedString* aAttrString,
                                    NSRange& aSelectedRange,
                                    bool aDoCommit)
 {
@@ -2705,22 +2708,19 @@ IMEInputHandler::DispatchTextEvent(const
 
   NS_ENSURE_TRUE(!Destroyed(), false);
 
   nsRefPtr<IMEInputHandler> kungFuDeathGrip(this);
 
   WidgetTextEvent textEvent(true, NS_TEXT_TEXT, mWidget);
   textEvent.time = PR_IntervalNow();
   textEvent.theText = aText;
-  nsAutoTArray<TextRange, 4> textRanges;
   if (!aDoCommit) {
-    SetTextRangeList(textRanges, aAttrString, aSelectedRange);
+    textEvent.mRanges = CreateTextRangeArray(aAttrString, aSelectedRange);
   }
-  textEvent.rangeArray = textRanges.Elements();
-  textEvent.rangeCount = textRanges.Length();
 
   if (textEvent.theText != mLastDispatchedCompositionString) {
     WidgetCompositionEvent compositionUpdate(true, NS_COMPOSITION_UPDATE,
                                              mWidget);
     compositionUpdate.time = textEvent.time;
     compositionUpdate.data = textEvent.theText;
     mLastDispatchedCompositionString = textEvent.theText;
     DispatchEvent(compositionUpdate);
--- a/widget/gonk/libdisplay/BootAnimation.cpp
+++ b/widget/gonk/libdisplay/BootAnimation.cpp
@@ -262,17 +262,17 @@ struct RawReadState {
     uint32_t length;
 };
 
 static void
 RawReader(png_structp png_ptr, png_bytep data, png_size_t length)
 {
     RawReadState *state = (RawReadState *)png_get_io_ptr(png_ptr);
     if (length > (state->length - state->offset))
-        png_err(png_ptr);
+        png_error(png_ptr, "PNG read overrun");
 
     memcpy(data, state->start + state->offset, length);
     state->offset += length;
 }
 
 static void
 TransformTo565(png_structp png_ptr, png_row_infop row_info, png_bytep data)
 {
--- a/widget/gtk/nsGtkIMModule.cpp
+++ b/widget/gtk/nsGtkIMModule.cpp
@@ -1188,33 +1188,23 @@ nsGtkIMModule::DispatchTextEvent(const n
         }
     }
 
     WidgetTextEvent textEvent(true, NS_TEXT_TEXT, mLastFocusedWindow);
     InitEvent(textEvent);
 
     uint32_t targetOffset = mCompositionStart;
 
-    nsAutoTArray<TextRange, 4> textRanges;
     if (!aIsCommit) {
         // NOTE: SetTextRangeList() assumes that mDispatchedCompositionString
         //       has been updated already.
-        SetTextRangeList(textRanges);
-        for (uint32_t i = 0; i < textRanges.Length(); i++) {
-            TextRange& range = textRanges[i];
-            if (range.mRangeType == NS_TEXTRANGE_SELECTEDRAWTEXT ||
-                range.mRangeType == NS_TEXTRANGE_SELECTEDCONVERTEDTEXT) {
-                targetOffset += range.mStartOffset;
-                break;
-            }
-        }
+        textEvent.mRanges = CreateTextRangeArray();
+        targetOffset += textEvent.mRanges->TargetClauseOffset();
     }
 
-    textEvent.rangeCount = textRanges.Length();
-    textEvent.rangeArray = textRanges.Elements();
     textEvent.theText = mDispatchedCompositionString.get();
 
     mCompositionState = aIsCommit ?
         eCompositionState_CommitTextEventDispatched :
         eCompositionState_TextEventDispatched;
 
     mLastFocusedWindow->DispatchEvent(&textEvent, status);
     if (lastFocusedWindow->IsDestroyed() ||
@@ -1227,45 +1217,45 @@ nsGtkIMModule::DispatchTextEvent(const n
     // We cannot call SetCursorPosition for e10s-aware.
     // DispatchEvent is async on e10s, so composition rect isn't updated now
     // on tab parent.
     mCompositionTargetOffset = targetOffset;
 
     return true;
 }
 
-void
-nsGtkIMModule::SetTextRangeList(nsTArray<TextRange> &aTextRangeList)
+already_AddRefed<TextRangeArray>
+nsGtkIMModule::CreateTextRangeArray()
 {
     PR_LOG(gGtkIMLog, PR_LOG_ALWAYS,
-        ("GtkIMModule(%p): SetTextRangeList", this));
+        ("GtkIMModule(%p): CreateTextRangeArray", this));
 
-    NS_PRECONDITION(aTextRangeList.IsEmpty(), "aTextRangeList must be empty");
+    nsRefPtr<TextRangeArray> textRangeArray = new TextRangeArray();
 
     gchar *preedit_string;
     gint cursor_pos;
     PangoAttrList *feedback_list;
     gtk_im_context_get_preedit_string(GetContext(), &preedit_string,
                                       &feedback_list, &cursor_pos);
     if (!preedit_string || !*preedit_string) {
         PR_LOG(gGtkIMLog, PR_LOG_ALWAYS,
             ("    preedit_string is null"));
         pango_attr_list_unref(feedback_list);
         g_free(preedit_string);
-        return;
+        return textRangeArray.forget();
     }
 
     PangoAttrIterator* iter;
     iter = pango_attr_list_get_iterator(feedback_list);
     if (!iter) {
         PR_LOG(gGtkIMLog, PR_LOG_ALWAYS,
             ("    FAILED, iterator couldn't be allocated"));
         pango_attr_list_unref(feedback_list);
         g_free(preedit_string);
-        return;
+        return textRangeArray.forget();
     }
 
     /*
      * Depend on gtk2's implementation on XIM support.
      * In aFeedback got from gtk2, there are only three types of data:
      * PANGO_ATTR_UNDERLINE, PANGO_ATTR_FOREGROUND, PANGO_ATTR_BACKGROUND.
      * Corresponding to XIMUnderline, XIMReverse.
      * Don't take PANGO_ATTR_BACKGROUND into account, since
@@ -1321,17 +1311,17 @@ nsGtkIMModule::SetTextRangeList(nsTArray
         if (!uniStr) {
             range.mEndOffset = range.mStartOffset;
         } else {
             range.mEndOffset = range.mStartOffset + uniStrLen;
             g_free(uniStr);
             uniStr = nullptr;
         }
 
-        aTextRangeList.AppendElement(range);
+        textRangeArray->AppendElement(range);
 
         PR_LOG(gGtkIMLog, PR_LOG_ALWAYS,
             ("    mStartOffset=%u, mEndOffset=%u, mRangeType=%s",
              range.mStartOffset, range.mEndOffset,
              GetRangeTypeName(range.mRangeType)));
     } while (pango_attr_iterator_next(iter));
 
     TextRange range;
@@ -1339,26 +1329,28 @@ nsGtkIMModule::SetTextRangeList(nsTArray
         range.mStartOffset = 0;
     } else if (uint32_t(cursor_pos) > mDispatchedCompositionString.Length()) {
         range.mStartOffset = mDispatchedCompositionString.Length();
     } else {
         range.mStartOffset = uint32_t(cursor_pos);
     }
     range.mEndOffset = range.mStartOffset;
     range.mRangeType = NS_TEXTRANGE_CARETPOSITION;
-    aTextRangeList.AppendElement(range);
+    textRangeArray->AppendElement(range);
 
     PR_LOG(gGtkIMLog, PR_LOG_ALWAYS,
         ("    mStartOffset=%u, mEndOffset=%u, mRangeType=%s",
          range.mStartOffset, range.mEndOffset,
          GetRangeTypeName(range.mRangeType)));
 
     pango_attr_iterator_destroy(iter);
     pango_attr_list_unref(feedback_list);
     g_free(preedit_string);
+
+    return textRangeArray.forget();
 }
 
 void
 nsGtkIMModule::SetCursorPosition(uint32_t aTargetOffset)
 {
     PR_LOG(gGtkIMLog, PR_LOG_ALWAYS,
         ("GtkIMModule(%p): SetCursorPosition, aTargetOffset=%u",
          this, aTargetOffset));
--- a/widget/gtk/nsGtkIMModule.h
+++ b/widget/gtk/nsGtkIMModule.h
@@ -8,16 +8,17 @@
 #ifndef __nsGtkIMModule_h__
 #define __nsGtkIMModule_h__
 
 #include <gdk/gdk.h>
 #include <gtk/gtk.h>
 
 #include "nsString.h"
 #include "nsAutoPtr.h"
+#include "nsCOMPtr.h"
 #include "nsTArray.h"
 #include "nsIWidget.h"
 #include "mozilla/EventForwards.h"
 
 class nsWindow;
 
 class nsGtkIMModule
 {
@@ -262,18 +263,18 @@ protected:
 
     // Reset the current composition of IME.  All native composition events
     // during this processing are ignored.
     void ResetIME();
 
     // Gets the current composition string by the native APIs.
     void GetCompositionString(nsAString &aCompositionString);
 
-    // Generates our text range list from current composition string.
-    void SetTextRangeList(nsTArray<mozilla::TextRange>& aTextRangeList);
+    // Generates our text range array from current composition string.
+    already_AddRefed<mozilla::TextRangeArray> CreateTextRangeArray();
 
     // Sets the offset's cursor position to IME.
     void SetCursorPosition(uint32_t aTargetOffset);
 
     // Queries the current selection offset of the window.
     uint32_t GetSelectionOffset(nsWindow* aWindow);
 
     // Get current paragraph text content and cursor position
--- a/widget/nsGUIEventIPC.h
+++ b/widget/nsGUIEventIPC.h
@@ -374,63 +374,89 @@ struct ParamTraits<mozilla::TextRange>
     return ReadParam(aMsg, aIter, &aResult->mStartOffset) &&
            ReadParam(aMsg, aIter, &aResult->mEndOffset) &&
            ReadParam(aMsg, aIter, &aResult->mRangeType) &&
            ReadParam(aMsg, aIter, &aResult->mRangeStyle);
   }
 };
 
 template<>
+struct ParamTraits<mozilla::TextRangeArray>
+{
+  typedef mozilla::TextRangeArray paramType;
+
+  static void Write(Message* aMsg, const paramType& aParam)
+  {
+    WriteParam(aMsg, aParam.Length());
+    for (uint32_t index = 0; index < aParam.Length(); index++) {
+      WriteParam(aMsg, aParam[index]);
+    }
+  }
+
+  static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
+  {
+    uint32_t length;
+    if (!ReadParam(aMsg, aIter, &length)) {
+      return false;
+    }
+    for (uint32_t index = 0; index < length; index++) {
+      mozilla::TextRange textRange;
+      if (!ReadParam(aMsg, aIter, &textRange)) {
+        aResult->Clear();
+        return false;
+      }
+      aResult->AppendElement(textRange);
+    }
+    return true;
+  }
+};
+
+template<>
 struct ParamTraits<mozilla::WidgetTextEvent>
 {
   typedef mozilla::WidgetTextEvent paramType;
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, static_cast<mozilla::WidgetGUIEvent>(aParam));
     WriteParam(aMsg, aParam.mSeqno);
     WriteParam(aMsg, aParam.theText);
     WriteParam(aMsg, aParam.isChar);
-    WriteParam(aMsg, aParam.rangeCount);
-    for (uint32_t index = 0; index < aParam.rangeCount; index++)
-      WriteParam(aMsg, aParam.rangeArray[index]);
+    bool hasRanges = !!aParam.mRanges;
+    WriteParam(aMsg, hasRanges);
+    if (hasRanges) {
+      WriteParam(aMsg, *aParam.mRanges.get());
+    }
   }
 
   static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
   {
+    bool hasRanges;
     if (!ReadParam(aMsg, aIter,
                    static_cast<mozilla::WidgetGUIEvent*>(aResult)) ||
         !ReadParam(aMsg, aIter, &aResult->mSeqno) ||
         !ReadParam(aMsg, aIter, &aResult->theText) ||
         !ReadParam(aMsg, aIter, &aResult->isChar) ||
-        !ReadParam(aMsg, aIter, &aResult->rangeCount))
+        !ReadParam(aMsg, aIter, &hasRanges)) {
       return false;
-
-    if (!aResult->rangeCount) {
-      aResult->rangeArray = nullptr;
-      return true;
     }
 
-    aResult->rangeArray = new mozilla::TextRange[aResult->rangeCount];
-    if (!aResult->rangeArray)
-      return false;
-
-    for (uint32_t index = 0; index < aResult->rangeCount; index++)
-      if (!ReadParam(aMsg, aIter, &aResult->rangeArray[index])) {
-        Free(*aResult);
+    if (!hasRanges) {
+      aResult->mRanges = nullptr;
+    } else {
+      aResult->mRanges = new mozilla::TextRangeArray();
+      if (!aResult->mRanges) {
         return false;
       }
+      if (!ReadParam(aMsg, aIter, aResult->mRanges.get())) {
+        return false;
+      }
+    }
     return true;
   }
-
-  static void Free(const paramType& aResult)
-  {
-    if (aResult.rangeArray)
-      delete [] aResult.rangeArray;
-  }
 };
 
 template<>
 struct ParamTraits<mozilla::WidgetCompositionEvent>
 {
   typedef mozilla::WidgetCompositionEvent paramType;
 
   static void Write(Message* aMsg, const paramType& aParam)
--- a/widget/tests/test_composition_text_querycontent.xul
+++ b/widget/tests/test_composition_text_querycontent.xul
@@ -14,17 +14,17 @@
 </div>
 <pre id="test">
 </pre>
 </body>
 
 <script class="testbody" type="application/javascript">
 <![CDATA[
 
-SimpleTest.expectAssertions(4);
+SimpleTest.expectAssertions(2);
 
 SimpleTest.waitForExplicitFinish();
 window.open("window_composition_text_querycontent.xul", "_blank", 
             "chrome,width=600,height=600");
 
 ]]>
 </script>
 </window>
--- a/widget/windows/nsIMM32Handler.cpp
+++ b/widget/windows/nsIMM32Handler.cpp
@@ -1605,102 +1605,103 @@ nsIMM32Handler::DispatchTextEvent(nsWind
     }
     SetIMERelatedWindowsPos(aWindow, aIMEContext);
   }
 
   WidgetTextEvent event(true, NS_TEXT_TEXT, aWindow);
 
   aWindow->InitEvent(event, &point);
 
-  nsAutoTArray<TextRange, 4> textRanges;
-
   if (aCheckAttr) {
-    SetTextRangeList(textRanges);
+    event.mRanges = CreateTextRangeArray();
   }
 
-  event.rangeCount = textRanges.Length();
-  event.rangeArray = textRanges.Elements();
-
   event.theText = mCompositionString.get();
 
   aWindow->DispatchWindowEvent(&event);
 
   // Calling SetIMERelatedWindowsPos will be failure on e10s at this point.
   // text event will notify NOTIFY_IME_OF_COMPOSITION_UPDATE, then
   // it will call SetIMERelatedWindowsPos.
 }
 
-void
-nsIMM32Handler::SetTextRangeList(nsTArray<TextRange> &aTextRangeList)
+already_AddRefed<TextRangeArray>
+nsIMM32Handler::CreateTextRangeArray()
 {
   // Sogou (Simplified Chinese IME) returns contradictory values: The cursor
   // position is actual cursor position. However, other values (composition
   // string and attributes) are empty. So, if you want to remove following
   // assertion, be careful.
   NS_ASSERTION(ShouldDrawCompositionStringOurselves(),
-    "SetTextRangeList is called when we don't need to fire text event");
+    "CreateTextRangeArray is called when we don't need to fire text event");
+
+  nsRefPtr<TextRangeArray> textRangeArray = new TextRangeArray();
 
   TextRange range;
   if (mClauseArray.Length() == 0) {
     // Some IMEs don't return clause array information, then, we assume that
     // all characters in the composition string are in one clause.
     range.mStartOffset = 0;
     range.mEndOffset = mCompositionString.Length();
     range.mRangeType = NS_TEXTRANGE_RAWINPUT;
-    aTextRangeList.AppendElement(range);
+    textRangeArray->AppendElement(range);
 
     PR_LOG(gIMM32Log, PR_LOG_ALWAYS,
-      ("IMM32: SetTextRangeList, mClauseLength=0\n"));
+      ("IMM32: CreateTextRangeArray, mClauseLength=0\n"));
   } else {
     // iterate over the attributes
     uint32_t lastOffset = 0;
     for (uint32_t i = 0; i < mClauseArray.Length() - 1; i++) {
       uint32_t current = mClauseArray[i + 1];
       if (current > mCompositionString.Length()) {
         PR_LOG(gIMM32Log, PR_LOG_ALWAYS,
-          ("IMM32: SetTextRangeList, mClauseArray[%ld]=%lu. This is larger than mCompositionString.Length()=%lu\n",
+          ("IMM32: CreateTextRangeArray, mClauseArray[%ld]=%lu. "
+           "This is larger than mCompositionString.Length()=%lu\n",
            i + 1, current, mCompositionString.Length()));
         current = int32_t(mCompositionString.Length());
       }
 
       range.mRangeType = PlatformToNSAttr(mAttributeArray[lastOffset]);
       range.mStartOffset = lastOffset;
       range.mEndOffset = current;
-      aTextRangeList.AppendElement(range);
+      textRangeArray->AppendElement(range);
 
       lastOffset = current;
 
       PR_LOG(gIMM32Log, PR_LOG_ALWAYS,
-        ("IMM32: SetTextRangeList, index=%ld, rangeType=%s, range=[%lu-%lu]\n",
+        ("IMM32: CreateTextRangeArray, index=%ld, rangeType=%s, range=[%lu-%lu]\n",
          i, GetRangeTypeName(range.mRangeType), range.mStartOffset,
          range.mEndOffset));
     }
   }
 
   if (mCursorPosition == NO_IME_CARET) {
     PR_LOG(gIMM32Log, PR_LOG_ALWAYS,
-      ("IMM32: GetTextRangeList, no caret\n"));
-    return;
+      ("IMM32: CreateTextRangeArray, no caret\n"));
+    return textRangeArray.forget();
   }
 
   int32_t cursor = mCursorPosition;
   if (uint32_t(cursor) > mCompositionString.Length()) {
     PR_LOG(gIMM32Log, PR_LOG_ALWAYS,
-      ("IMM32: SetTextRangeList, mCursorPosition=%ld. This is larger than mCompositionString.Length()=%lu\n",
+      ("IMM32: CreateTextRangeArray, mCursorPosition=%ld. "
+       "This is larger than mCompositionString.Length()=%lu\n",
        mCursorPosition, mCompositionString.Length()));