merge mozilla-central to mozilla-inbound
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Tue, 10 Sep 2013 10:35:46 +0200
changeset 146403 097fd1744dfe0bc0670caee7dcd5846b38a268a9
parent 146402 d660739f74981545b16aeee25fae6a4bcb10bc8a (current diff)
parent 146334 680c89c761007e26015ac3450820d28463b97dff (diff)
child 146404 2f406d02bf24557af3d463d885d1551da7eccf90
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
milestone26.0a1
merge mozilla-central to mozilla-inbound
dom/bluetooth/BluetoothTelephonyListener.cpp
dom/bluetooth/BluetoothTelephonyListener.h
ipc/chromium/src/base/foundation_utils_mac.h
ipc/chromium/src/base/string_escape.cc
ipc/chromium/src/base/string_escape.h
--- a/browser/base/content/newtab/newTab.js
+++ b/browser/base/content/newtab/newTab.js
@@ -5,16 +5,19 @@
 "use strict";
 
 let Cu = Components.utils;
 let Ci = Components.interfaces;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/PageThumbs.jsm");
+#ifndef RELEASE_BUILD
+Cu.import("resource://gre/modules/BackgroundPageThumbs.jsm");
+#endif
 Cu.import("resource://gre/modules/NewTabUtils.jsm");
 Cu.import("resource://gre/modules/commonjs/sdk/core/promise.js");
 
 XPCOMUtils.defineLazyModuleGetter(this, "Rect",
   "resource://gre/modules/Geometry.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils",
   "resource://gre/modules/PrivateBrowsingUtils.jsm");
 
--- a/browser/base/content/newtab/sites.js
+++ b/browser/base/content/newtab/sites.js
@@ -126,20 +126,22 @@ Site.prototype = {
 
     let link = this._querySelector(".newtab-link");
     link.setAttribute("title", tooltip);
     link.setAttribute("href", url);
     this._querySelector(".newtab-title").textContent = title;
 
     if (this.isPinned())
       this._updateAttributes(true);
+#ifndef RELEASE_BUILD
     // request a staleness check for the thumbnail, which will cause page.js
     // to be notified and call our refreshThumbnail() method.
-    PageThumbs.captureIfStale(this.url);
+    BackgroundPageThumbs.captureIfStale(this.url);
     // but still display whatever thumbnail might be available now.
+#endif
     this.refreshThumbnail();
   },
 
   /**
    * Refreshes the thumbnail for the site.
    */
   refreshThumbnail: function Site_refreshThumbnail() {
     let thumbnailURL = PageThumbs.getThumbnailURL(this.url);
--- a/browser/metro/base/content/downloads.js
+++ b/browser/metro/base/content/downloads.js
@@ -57,28 +57,50 @@ var Downloads = {
     Services.obs.addObserver(this, "dl-request", true);
 
     this._notificationBox = Browser.getNotificationBox();
 
     this._progress = new DownloadProgressListener(this);
     this.manager.addListener(this._progress);
 
     this._downloadProgressIndicator = document.getElementById("download-progress");
+
+    if (this.manager.activeDownloadCount) {
+      setTimeout (this._restartWithActiveDownloads.bind(this), 0);
+    }
   },
 
   uninit: function dh_uninit() {
     if (this._inited) {
       Services.obs.removeObserver(this, "dl-start");
       Services.obs.removeObserver(this, "dl-done");
       Services.obs.removeObserver(this, "dl-run");
       Services.obs.removeObserver(this, "dl-failed");
       Services.obs.removeObserver(this, "dl-request");
     }
   },
 
+  _restartWithActiveDownloads: function() {
+    let activeDownloads = this.manager.activeDownloads;
+
+    while (activeDownloads.hasMoreElements()) {
+      let dl = activeDownloads.getNext();
+      switch (dl.state) {
+        case 0: // Downloading
+        case 5: // Queued
+          this.watchDownload(dl);
+          this.updateInfobar(dl);
+          break;
+      }
+    }
+    if (this.manager.activeDownloadCount) {
+      Services.obs.notifyObservers(null, "dl-request", "");
+    }
+  },
+
   openDownload: function dh_openDownload(aDownload) {
     let fileURI = aDownload.target
 
     if (!(fileURI && fileURI.spec)) {
       Util.dumpLn("Cant open download "+id+", fileURI is invalid");
       return;
     }
 
@@ -126,18 +148,18 @@ var Downloads = {
     } catch (ex) {
       Util.dumpLn("Failed to cancel download, with id: "+aDownload.id+", download target URI spec: " + fileURI.spec);
       Util.dumpLn("Failed download source:"+(aDownload.source && aDownload.source.spec));
     }
   },
 
   // Cancels all downloads.
   cancelDownloads: function dh_cancelDownloads() {
-    for (let info of this._progressNotificationInfo) {
-      this.cancelDownload(info[1].download);
+    for (let [guid, info] of this._progressNotificationInfo) {
+      this.cancelDownload(info.download);
     }
     this._downloadCount = 0;
     this._progressNotificationInfo.clear();
     this._runDownloadBooleanMap.clear();
   },
 
   pauseDownload: function dh_pauseDownload(aDownload) {
     let id = aDownload.getAttribute("downloadId");
@@ -167,21 +189,22 @@ var Downloads = {
     if (!aIcon)
       aIcon = TOAST_URI_GENERIC_ICON_DOWNLOAD;
 
     notifier.showAlertNotification(aIcon, aTitle, aMessage, true, "", aObserver, aName);
   },
 
   showNotification: function dh_showNotification(title, msg, buttons, priority) {
     this._notificationBox.notificationsHidden = false;
-    return this._notificationBox.appendNotification(msg,
+    let notification = this._notificationBox.appendNotification(msg,
                                               title,
                                               URI_GENERIC_ICON_DOWNLOAD,
                                               priority,
                                               buttons);
+    return notification;
   },
 
   _showDownloadFailedNotification: function (aDownload) {
     let tryAgainButtonText =
       Strings.browser.GetStringFromName("downloadTryAgain");
     let cancelButtonText =
       Strings.browser.GetStringFromName("downloadCancel");
 
@@ -296,32 +319,31 @@ var Downloads = {
   },
 
   _updateCircularProgressMeter: function dv_updateCircularProgressMeter() {
     if (!this._progressNotificationInfo) {
       return;
     }
 
     let totPercent = 0;
-    for (let info of this._progressNotificationInfo) {
-      // info[0]          => download guid
-      // info[1].download => nsIDownload
-      totPercent += info[1].download.percentComplete;
+    for (let [guid, info] of this._progressNotificationInfo) {
+      // info.download => nsIDownload
+      totPercent += info.download.percentComplete;
     }
 
     let percentComplete = totPercent / this._progressNotificationInfo.size;
     this._downloadProgressIndicator.updateProgress(percentComplete);
   },
 
   _computeDownloadProgressString: function dv_computeDownloadProgressString(aDownload) {
     let totTransferred = 0, totSize = 0, totSecondsLeft = 0;
-    for (let info of this._progressNotificationInfo) {
-      let size = info[1].download.size;
-      let amountTransferred = info[1].download.amountTransferred;
-      let speed = info[1].download.speed;
+    for (let [guid, info] of this._progressNotificationInfo) {
+      let size = info.download.size;
+      let amountTransferred = info.download.amountTransferred;
+      let speed = info.download.speed;
 
       totTransferred += amountTransferred;
       totSize += size;
       totSecondsLeft += ((size - amountTransferred) / speed);
     }
 
     // Compute progress in bytes.
     let amountTransferred = Util.getDownloadSize(totTransferred);
@@ -352,23 +374,24 @@ var Downloads = {
       this._progressNotificationInfo.set(aDownload.guid, {});
     }
     let infoObj = this._progressNotificationInfo.get(aDownload.guid);
     infoObj.download = aDownload;
     this._progressNotificationInfo.set(aDownload.guid, infoObj);
   },
 
   updateInfobar: function dv_updateInfobar(aDownload) {
-    this._saveDownloadData(aDownload);
     let message = this._computeDownloadProgressString(aDownload);
     this._updateCircularProgressMeter();
 
+    if (this._notificationBox && this._notificationBox.notificationsHidden)
+      this._notificationBox.notificationsHidden = false;
+
     if (this._progressNotification == null ||
         !this._notificationBox.getNotificationWithValue("download-progress")) {
-
       let cancelButtonText =
               Strings.browser.GetStringFromName("downloadCancel");
 
       let buttons = [
         {
           isDefault: false,
           label: cancelButtonText,
           accessKey: "",
@@ -390,36 +413,41 @@ var Downloads = {
     if (this._progressNotification != null) {
       this._saveDownloadData(aDownload);
       this._progressNotification.label =
         this._computeDownloadProgressString(aDownload);
       this._updateCircularProgressMeter();
     }
   },
 
+  watchDownload: function dv_watchDownload(aDownload) {
+    this._saveDownloadData(aDownload);
+    this._downloadCount++;
+    this._downloadsInProgress++;
+    if (!this._progressNotificationInfo.get(aDownload.guid)) {
+      this._progressNotificationInfo.set(aDownload.guid, {});
+    }
+    if (!this._progressAlert) {
+      this._progressAlert = new AlertDownloadProgressListener();
+      this.manager.addListener(this._progressAlert);
+    }
+  },
+
   observe: function (aSubject, aTopic, aData) {
     let message = "";
     let msgTitle = "";
 
     switch (aTopic) {
       case "dl-run":
         let file = aSubject.QueryInterface(Ci.nsIFile);
         this._runDownloadBooleanMap.set(file.path, (aData == 'true'));
         break;
       case "dl-start":
-        this._downloadCount++;
-        this._downloadsInProgress++;
         let download = aSubject.QueryInterface(Ci.nsIDownload);
-        if (!this._progressNotificationInfo.get(download.guid)) {
-          this._progressNotificationInfo.set(download.guid, {});
-        }
-        if (!this._progressAlert) {
-          this._progressAlert = new AlertDownloadProgressListener();
-          this.manager.addListener(this._progressAlert);
-        }
+        this.watchDownload(download);
         this.updateInfobar(download);
         break;
       case "dl-done":
         this._downloadsInProgress--;
         download = aSubject.QueryInterface(Ci.nsIDownload);
         let runAfterDownload = this._runDownloadBooleanMap.get(download.targetFile.path);
         if (runAfterDownload) {
           this.openDownload(download);
--- a/browser/metro/components/HelperAppDialog.js
+++ b/browser/metro/components/HelperAppDialog.js
@@ -39,17 +39,17 @@ HelperAppLauncherDialog.prototype = {
     } else {
       let wasClicked = false;
       this._showDownloadInfobar(aLauncher);
     }
   },
 
   _getDownloadSize: function dv__getDownloadSize (aSize) {
     let displaySize = DownloadUtils.convertByteUnits(aSize);
-    if (displaySize[0] > 0) // [0] is size, [1] is units
+    if (!isNaN(displaySize[0]) && displaySize[0] > 0) // [0] is size, [1] is units
       return displaySize.join("");
     else {
       let browserBundle = Services.strings.createBundle("chrome://browser/locale/browser.properties");
       return browserBundle.GetStringFromName("downloadsUnknownSize");
     }
   },
 
   _getChromeWindow: function (aWindow) {
--- a/browser/metro/modules/CrossSlide.jsm
+++ b/browser/metro/modules/CrossSlide.jsm
@@ -235,24 +235,30 @@ CrossSlideHandler.prototype = {
 
   /**
    * Dispatches a custom Event on the drag node.
    * @param aEvent The source event.
    * @param aType The event type.
    */
   _fireProgressEvent: function CrossSliding_fireEvent(aState, aEvent) {
     if (!this.drag)
-        return;
+      return;
     let event = this.node.ownerDocument.createEvent("Events");
-    let crossAxis = this.drag.crossAxis;
+    let crossAxisName = this.drag.crossAxis;
     event.initEvent("MozCrossSliding", true, true);
     event.crossSlidingState = aState;
-    event.position = this.drag.position;
-    event.direction = this.drag.crossAxis;
-    event.delta = this.drag.position[crossAxis] - this.drag.origin[crossAxis];
+    if ('position' in this.drag) {
+      event.position = this.drag.position;
+      if (crossAxisName) {
+        event.direction = crossAxisName;
+        if('origin' in this.drag) {
+          event.delta = this.drag.position[crossAxisName] - this.drag.origin[crossAxisName];
+        }
+      }
+    }
     aEvent.target.dispatchEvent(event);
   },
 
   /**
    * Dispatches a custom Event on the given target node.
    * @param aEvent The source event.
    */
   _fireSelectEvent: function SelectTarget_fireEvent(aEvent) {
--- a/config/nspr/Makefile.in
+++ b/config/nspr/Makefile.in
@@ -18,16 +18,20 @@ ABS_DIST = $(call core_abspath,$(DIST))
 ifdef MOZ_FOLD_LIBS
 # Trick the nspr build system into not building shared libraries.
 # bug #851869.
 EXTRA_MAKE_FLAGS := SHARED_LIBRARY= IMPORT_LIBRARY= SHARED_LIB_PDB=
 
 # Work around libVersionPoint conflict between all three libraries.
 # See bug #838566.
 EXTRA_MAKE_FLAGS += XP_DEFINE=-DlibVersionPoint='libVersionPoint$$(LIBRARY_NAME)'
+else
+# nspr's make export compiles and links everything, but linking can't happen
+# during export on platforms where nspr is linked against mozcrt/mozglue.
+export:: EXTRA_MAKE_FLAGS := SHARED_LIBRARY= IMPORT_LIBRARY= SHARED_LIB_PDB=
 endif
 
 libs export clean distclean::
 	$(MAKE) -C $(DEPTH)/nsprpub $@ $(EXTRA_MAKE_FLAGS)
 
 libs::
 	$(MAKE) -C $(DEPTH)/nsprpub install prefix=$(ABS_DIST)/sdk exec_prefix=$(ABS_DIST)/sdk bindir=$(ABS_DIST)/sdk/dummy includedir=$(ABS_DIST)/include/nspr libdir=$(ABS_DIST)/sdk/lib datadir=$(ABS_DIST)/sdk/dummy DESTDIR= $(EXTRA_MAKE_FLAGS)
 	$(INSTALL) $(DEPTH)/nsprpub/config/nspr-config $(DIST)/sdk/bin
--- a/content/base/src/nsDOMMutationObserver.cpp
+++ b/content/base/src/nsDOMMutationObserver.cpp
@@ -1,23 +1,23 @@
 /* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 8; -*- */
 /* vim: set sw=4 ts=8 et 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/. */
 
-#include "nsDOMMutationObserver.h"        
-#include "nsDOMClassInfoID.h"
+#include "nsDOMMutationObserver.h"
+
+#include "mozilla/dom/OwningNonNull.h"
 #include "nsError.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsContentUtils.h"
 #include "nsThreadUtils.h"
 #include "nsIDOMMutationEvent.h"
 #include "nsTextFragment.h"
-#include "jsapi.h"
 #include "nsServiceManagerUtils.h"
 
 nsTArray<nsRefPtr<nsDOMMutationObserver> >*
   nsDOMMutationObserver::sScheduledMutationObservers = nullptr;
 
 nsDOMMutationObserver* nsDOMMutationObserver::sCurrentObserver = nullptr;
 
 uint32_t nsDOMMutationObserver::sMutationLevel = 0;
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -185,21 +185,22 @@
 
 #include "imgILoader.h"
 #include "imgRequestProxy.h"
 #include "nsWrapperCacheInlines.h"
 #include "nsSandboxFlags.h"
 #include "nsIAppsService.h"
 #include "mozilla/dom/BindingUtils.h"
 #include "mozilla/dom/DocumentFragment.h"
-#include "mozilla/dom/WebComponentsBinding.h"
 #include "mozilla/dom/HTMLBodyElement.h"
 #include "mozilla/dom/HTMLInputElement.h"
 #include "mozilla/dom/NodeFilterBinding.h"
+#include "mozilla/dom/OwningNonNull.h"
 #include "mozilla/dom/UndoManager.h"
+#include "mozilla/dom/WebComponentsBinding.h"
 #include "nsFrame.h"
 #include "nsDOMCaretPosition.h"
 #include "nsIDOMHTMLTextAreaElement.h"
 #include "nsViewportInfo.h"
 #include "nsDOMEvent.h"
 #include "nsIContentPermissionPrompt.h"
 #include "mozilla/StaticPtr.h"
 #include "nsITextControlElement.h"
--- a/content/canvas/src/CanvasRenderingContext2D.cpp
+++ b/content/canvas/src/CanvasRenderingContext2D.cpp
@@ -1,54 +1,47 @@
 /* -*- 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 "base/basictypes.h"
 #include "CanvasRenderingContext2D.h"
 
 #include "nsXULElement.h"
 
-#include "prenv.h"
-
 #include "nsIServiceManager.h"
 #include "nsMathUtils.h"
 
 #include "nsContentUtils.h"
 
 #include "nsIDocument.h"
 #include "mozilla/dom/HTMLCanvasElement.h"
 #include "nsSVGEffects.h"
 #include "nsPresContext.h"
 #include "nsIPresShell.h"
-#include "nsIVariant.h"
 
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsIFrame.h"
 #include "nsError.h"
-#include "nsIScriptError.h"
 
 #include "nsCSSParser.h"
 #include "mozilla/css/StyleRule.h"
 #include "mozilla/css/Declaration.h"
 #include "nsComputedDOMStyle.h"
 #include "nsStyleSet.h"
 
 #include "nsPrintfCString.h"
 
 #include "nsReadableUtils.h"
 
 #include "nsColor.h"
 #include "nsGfxCIID.h"
-#include "nsIScriptSecurityManager.h"
 #include "nsIDocShell.h"
 #include "nsIDOMWindow.h"
 #include "nsPIDOMWindow.h"
-#include "nsIXPConnect.h"
 #include "nsDisplayList.h"
 
 #include "nsTArray.h"
 
 #include "imgIEncoder.h"
 
 #include "gfxContext.h"
 #include "gfxASurface.h"
@@ -85,19 +78,16 @@
 #include "mozilla/ipc/DocumentRendererParent.h"
 #include "mozilla/ipc/PDocumentRendererParent.h"
 #include "mozilla/MathAlgorithms.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Telemetry.h"
 #include "mozilla/unused.h"
 #include "nsCCUncollectableMarker.h"
 #include "nsWrapperCacheInlines.h"
-#include "nsJSUtils.h"
-#include "XPCQuickStubs.h"
-#include "mozilla/dom/BindingUtils.h"
 #include "mozilla/dom/CanvasRenderingContext2DBinding.h"
 #include "mozilla/dom/HTMLImageElement.h"
 #include "mozilla/dom/HTMLVideoElement.h"
 #include "mozilla/dom/TextMetrics.h"
 #include "mozilla/dom/UnionTypes.h"
 
 #ifdef USE_SKIA_GPU
 #undef free // apparently defined by some windows header, clashing with a free()
--- a/content/html/content/src/HTMLOptionsCollection.cpp
+++ b/content/html/content/src/HTMLOptionsCollection.cpp
@@ -2,16 +2,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/dom/HTMLOptionsCollection.h"
 
 #include "HTMLOptGroupElement.h"
 #include "mozAutoDocUpdate.h"
+#include "mozilla/dom/BindingUtils.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/HTMLOptionElement.h"
 #include "mozilla/dom/HTMLOptionsCollectionBinding.h"
 #include "mozilla/dom/HTMLSelectElement.h"
 #include "mozilla/Util.h"
 #include "nsContentCreatorFunctions.h"
 #include "nsError.h"
 #include "nsEventDispatcher.h"
--- a/content/media/webaudio/AudioContext.cpp
+++ b/content/media/webaudio/AudioContext.cpp
@@ -1,21 +1,23 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* 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 "AudioContext.h"
+
 #include "nsPIDOMWindow.h"
 #include "mozilla/ErrorResult.h"
 #include "mozilla/dom/AnalyserNode.h"
 #include "mozilla/dom/AudioContextBinding.h"
 #include "mozilla/dom/HTMLMediaElement.h"
 #include "mozilla/dom/OfflineAudioContextBinding.h"
+#include "mozilla/dom/OwningNonNull.h"
 #include "MediaStreamGraph.h"
 #include "AudioDestinationNode.h"
 #include "AudioBufferSourceNode.h"
 #include "AudioBuffer.h"
 #include "GainNode.h"
 #include "MediaElementAudioSourceNode.h"
 #include "MediaStreamAudioSourceNode.h"
 #include "DelayNode.h"
--- a/dom/bindings/BindingUtils.h
+++ b/dom/bindings/BindingUtils.h
@@ -1418,70 +1418,16 @@ HasPropertyOnPrototype(JSContext* cx, JS
 // shadowPrototypeProperties is false then skip properties that are also
 // present on the proto chain of proxy.  If shadowPrototypeProperties is true,
 // then the "proxy" argument is ignored.
 bool
 AppendNamedPropertyIds(JSContext* cx, JS::Handle<JSObject*> proxy,
                        nsTArray<nsString>& names,
                        bool shadowPrototypeProperties, JS::AutoIdVector& props);
 
-template<class T>
-class OwningNonNull
-{
-public:
-  OwningNonNull()
-#ifdef DEBUG
-    : inited(false)
-#endif
-  {}
-
-  operator T&() {
-    MOZ_ASSERT(inited);
-    MOZ_ASSERT(ptr, "OwningNonNull<T> was set to null");
-    return *ptr;
-  }
-
-  void operator=(T* t) {
-    init(t);
-  }
-
-  void operator=(const already_AddRefed<T>& t) {
-    init(t);
-  }
-
-  already_AddRefed<T> forget() {
-#ifdef DEBUG
-    inited = false;
-#endif
-    return ptr.forget();
-  }
-
-  // Make us work with smart-ptr helpers that expect a get()
-  T* get() const {
-    MOZ_ASSERT(inited);
-    MOZ_ASSERT(ptr);
-    return ptr;
-  }
-
-protected:
-  template<typename U>
-  void init(U t) {
-    ptr = t;
-    MOZ_ASSERT(ptr);
-#ifdef DEBUG
-    inited = true;
-#endif
-  }
-
-  nsRefPtr<T> ptr;
-#ifdef DEBUG
-  bool inited;
-#endif
-};
-
 // A struct that has the same layout as an nsDependentString but much
 // faster constructor and destructor behavior
 struct FakeDependentString {
   FakeDependentString() :
     mFlags(nsDependentString::F_TERMINATED)
   {
   }
 
@@ -1607,50 +1553,16 @@ ConvertJSValueToString(JSContext* cx, JS
   return true;
 }
 
 bool
 ConvertJSValueToByteString(JSContext* cx, JS::Handle<JS::Value> v,
                            JS::MutableHandle<JS::Value> pval, bool nullable,
                            nsACString& result);
 
-// Class for holding the type of members of a union. The union type has an enum
-// to keep track of which of its UnionMembers has been constructed.
-template<class T>
-class UnionMember {
-    AlignedStorage2<T> storage;
-
-public:
-    T& SetValue() {
-      new (storage.addr()) T();
-      return *storage.addr();
-    }
-    template <typename T1>
-    T& SetValue(const T1 &t1)
-    {
-      new (storage.addr()) T(t1);
-      return *storage.addr();
-    }
-    template <typename T1, typename T2>
-    T& SetValue(const T1 &t1, const T2 &t2)
-    {
-      new (storage.addr()) T(t1, t2);
-      return *storage.addr();
-    }
-    T& Value() {
-      return *storage.addr();
-    }
-    const T& Value() const {
-      return *storage.addr();
-    }
-    void Destroy() {
-      storage.addr()->~T();
-    }
-};
-
 template<typename T>
 void DoTraceSequence(JSTracer* trc, FallibleTArray<T>& seq);
 template<typename T>
 void DoTraceSequence(JSTracer* trc, InfallibleTArray<T>& seq);
 
 // Class for simple sequence arguments, only used internally by codegen.
 template<typename T>
 class AutoSequence : public AutoFallibleTArray<T, 16>
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -8830,21 +8830,22 @@ class CGBindingRoot(CGThing):
                 return False
             return typeDesc.hasXPConnectImpls
         addHeaderBasedOnTypes("nsDOMQS.h", checkForXPConnectImpls)
 
         # Do codegen for all the enums
         enums = config.getEnums(webIDLFile)
         cgthings = [ CGEnum(e) for e in enums ]
 
-        bindingHeaders["mozilla/dom/BindingUtils.h"] = (
-            descriptors or callbackDescriptors or dictionaries or
-            mainCallbacks or workerCallbacks)
+        hasCode = (descriptors or callbackDescriptors or dictionaries or
+                   mainCallbacks or workerCallbacks)
+        bindingHeaders["mozilla/dom/BindingUtils.h"] = hasCode
+        bindingHeaders["mozilla/dom/OwningNonNull.h"] = hasCode
         bindingHeaders["mozilla/dom/BindingDeclarations.h"] = (
-            not bindingHeaders["mozilla/dom/BindingUtils.h"] and enums)
+            not hasCode and enums)
 
         bindingHeaders["WrapperFactory.h"] = descriptors
         bindingHeaders["mozilla/dom/DOMJSClass.h"] = descriptors
 
         # Do codegen for all the dictionaries.  We have to be a bit careful
         # here, because we have to generate these in order from least derived
         # to most derived so that class inheritance works out.  We also have to
         # generate members before the dictionary that contains them.
@@ -10548,17 +10549,18 @@ struct PrototypeTraits;
     @staticmethod
     def UnionTypes(config):
 
         (includes, implincludes,
          declarations, unions) = UnionTypes(config.getDescriptors(),
                                             config.getDictionaries(),
                                             config.getCallbacks(),
                                             config)
-        includes.add("mozilla/dom/BindingUtils.h")
+        includes.add("mozilla/dom/OwningNonNull.h")
+        includes.add("mozilla/dom/UnionMember.h")
         implincludes.add("mozilla/dom/PrimitiveConversions.h")
 
         # Wrap all of that in our namespaces.
         curr = CGNamespace.build(['mozilla', 'dom'], unions)
 
         curr = CGWrapper(curr, post='\n')
 
         namespaces = []
copy from dom/bindings/BindingUtils.h
copy to dom/bindings/OwningNonNull.h
--- a/dom/bindings/BindingUtils.h
+++ b/dom/bindings/OwningNonNull.h
@@ -1,2347 +1,80 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/
-/* vim: set ts=2 sw=2 et tw=79: */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 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/. */
-
-#ifndef mozilla_dom_BindingUtils_h__
-#define mozilla_dom_BindingUtils_h__
-
-#include <algorithm>
+ * 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 "jsfriendapi.h"
-#include "jswrapper.h"
-#include "mozilla/Alignment.h"
-#include "mozilla/dom/BindingDeclarations.h"
-#include "mozilla/dom/CallbackObject.h"
-#include "mozilla/dom/DOMJSClass.h"
-#include "mozilla/dom/DOMJSProxyHandler.h"
-#include "mozilla/dom/Exceptions.h"
-#include "mozilla/dom/NonRefcountedDOMObject.h"
-#include "mozilla/dom/Nullable.h"
-#include "mozilla/dom/workers/Workers.h"
-#include "mozilla/ErrorResult.h"
-#include "mozilla/Likely.h"
-#include "mozilla/Util.h"
-#include "nsCycleCollector.h"
-#include "nsIXPConnect.h"
-#include "nsThreadUtils.h" // Hacky work around for some bindings needing NS_IsMainThread.
-#include "nsTraceRefcnt.h"
-#include "qsObjectHelper.h"
-#include "xpcpublic.h"
-#include "nsIVariant.h"
+/* A class for non-null strong pointers to reference-counted objects. */
 
-#include "nsWrapperCacheInlines.h"
-
-class nsPIDOMWindow;
+#ifndef mozilla_dom_OwningNonNull_h
+#define mozilla_dom_OwningNonNull_h
 
-extern nsresult
-xpc_qsUnwrapArgImpl(JSContext* cx, jsval v, const nsIID& iid, void** ppArg,
-                    nsISupports** ppArgRef, jsval* vp);
+#include "nsAutoPtr.h"
 
 namespace mozilla {
 namespace dom {
 
-struct SelfRef
-{
-  SelfRef() : ptr(nullptr) {}
-  explicit SelfRef(nsISupports *p) : ptr(p) {}
-  ~SelfRef() { NS_IF_RELEASE(ptr); }
-
-  nsISupports* ptr;
-};
-
-/** Convert a jsval to an XPCOM pointer. */
-template <class Interface, class StrongRefType>
-inline nsresult
-UnwrapArg(JSContext* cx, jsval v, Interface** ppArg,
-          StrongRefType** ppArgRef, jsval* vp)
-{
-  nsISupports* argRef = *ppArgRef;
-  nsresult rv = xpc_qsUnwrapArgImpl(cx, v, NS_GET_TEMPLATE_IID(Interface),
-                                    reinterpret_cast<void**>(ppArg), &argRef,
-                                    vp);
-  *ppArgRef = static_cast<StrongRefType*>(argRef);
-  return rv;
-}
-
-bool
-ThrowInvalidThis(JSContext* aCx, const JS::CallArgs& aArgs,
-                 const ErrNum aErrorNumber,
-                 const char* aInterfaceName);
-
-inline bool
-ThrowMethodFailedWithDetails(JSContext* cx, ErrorResult& rv,
-                             const char* ifaceName,
-                             const char* memberName,
-                             bool reportJSContentExceptions = false)
-{
-  if (rv.IsTypeError()) {
-    rv.ReportTypeError(cx);
-    return false;
-  }
-  if (rv.IsJSException()) {
-    if (reportJSContentExceptions) {
-      rv.ReportJSExceptionFromJSImplementation(cx);
-    } else {
-      rv.ReportJSException(cx);
-    }
-    return false;
-  }
-  if (rv.IsNotEnoughArgsError()) {
-    rv.ReportNotEnoughArgsError(cx, ifaceName, memberName);
-  }
-  return Throw(cx, rv.ErrorCode());
-}
-
-// Returns true if the JSClass is used for DOM objects.
-inline bool
-IsDOMClass(const JSClass* clasp)
-{
-  return clasp->flags & JSCLASS_IS_DOMJSCLASS;
-}
-
-inline bool
-IsDOMClass(const js::Class* clasp)
-{
-  return IsDOMClass(Jsvalify(clasp));
-}
-
-// Returns true if the JSClass is used for DOM interface and interface 
-// prototype objects.
-inline bool
-IsDOMIfaceAndProtoClass(const JSClass* clasp)
-{
-  return clasp->flags & JSCLASS_IS_DOMIFACEANDPROTOJSCLASS;
-}
-
-inline bool
-IsDOMIfaceAndProtoClass(const js::Class* clasp)
-{
-  return IsDOMIfaceAndProtoClass(Jsvalify(clasp));
-}
-
-static_assert(DOM_OBJECT_SLOT == js::PROXY_PRIVATE_SLOT,
-              "js::PROXY_PRIVATE_SLOT doesn't match DOM_OBJECT_SLOT.  "
-              "Expect bad things");
-template <class T>
-inline T*
-UnwrapDOMObject(JSObject* obj)
-{
-  MOZ_ASSERT(IsDOMClass(js::GetObjectClass(obj)) || IsDOMProxy(obj),
-             "Don't pass non-DOM objects to this function");
-
-  JS::Value val = js::GetReservedSlot(obj, DOM_OBJECT_SLOT);
-  return static_cast<T*>(val.toPrivate());
-}
-
-inline const DOMClass*
-GetDOMClass(JSObject* obj)
-{
-  js::Class* clasp = js::GetObjectClass(obj);
-  if (IsDOMClass(clasp)) {
-    return &DOMJSClass::FromJSClass(clasp)->mClass;
-  }
-
-  if (js::IsProxyClass(clasp)) {
-    js::BaseProxyHandler* handler = js::GetProxyHandler(obj);
-    if (handler->family() == ProxyFamily()) {
-      return &static_cast<DOMProxyHandler*>(handler)->mClass;
-    }
-  }
-
-  return nullptr;
-}
-
-inline nsISupports*
-UnwrapDOMObjectToISupports(JSObject* aObject)
-{
-  const DOMClass* clasp = GetDOMClass(aObject);
-  if (!clasp || !clasp->mDOMObjectIsISupports) {
-    return nullptr;
-  }
- 
-  return UnwrapDOMObject<nsISupports>(aObject);
-}
-
-inline bool
-IsDOMObject(JSObject* obj)
-{
-  js::Class* clasp = js::GetObjectClass(obj);
-  return IsDOMClass(clasp) || IsDOMProxy(obj, clasp);
-}
-
-#define UNWRAP_OBJECT(Interface, cx, obj, value)                             \
-  mozilla::dom::UnwrapObject<mozilla::dom::prototypes::id::Interface,        \
-    mozilla::dom::Interface##Binding::NativeType>(cx, obj, value)
-
-// Some callers don't want to set an exception when unwrapping fails
-// (for example, overload resolution uses unwrapping to tell what sort
-// of thing it's looking at).
-// U must be something that a T* can be assigned to (e.g. T* or an nsRefPtr<T>).
-template <prototypes::ID PrototypeID, class T, typename U>
-MOZ_ALWAYS_INLINE nsresult
-UnwrapObject(JSContext* cx, JSObject* obj, U& value)
-{
-  /* First check to see whether we have a DOM object */
-  const DOMClass* domClass = GetDOMClass(obj);
-  if (!domClass) {
-    /* Maybe we have a security wrapper or outer window? */
-    if (!js::IsWrapper(obj)) {
-      /* Not a DOM object, not a wrapper, just bail */
-      return NS_ERROR_XPC_BAD_CONVERT_JS;
-    }
-
-    obj = js::CheckedUnwrap(obj, /* stopAtOuter = */ false);
-    if (!obj) {
-      return NS_ERROR_XPC_SECURITY_MANAGER_VETO;
-    }
-    MOZ_ASSERT(!js::IsWrapper(obj));
-    domClass = GetDOMClass(obj);
-    if (!domClass) {
-      /* We don't have a DOM object */
-      return NS_ERROR_XPC_BAD_CONVERT_JS;
-    }
-  }
-
-  /* This object is a DOM object.  Double-check that it is safely
-     castable to T by checking whether it claims to inherit from the
-     class identified by protoID. */
-  if (domClass->mInterfaceChain[PrototypeTraits<PrototypeID>::Depth] ==
-      PrototypeID) {
-    value = UnwrapDOMObject<T>(obj);
-    return NS_OK;
-  }
-
-  /* It's the wrong sort of DOM object */
-  return NS_ERROR_XPC_BAD_CONVERT_JS;
-}
-
-inline bool
-IsNotDateOrRegExp(JSContext* cx, JS::Handle<JSObject*> obj)
-{
-  MOZ_ASSERT(obj);
-  return !JS_ObjectIsDate(cx, obj) && !JS_ObjectIsRegExp(cx, obj);
-}
-
-MOZ_ALWAYS_INLINE bool
-IsArrayLike(JSContext* cx, JS::Handle<JSObject*> obj)
-{
-  return IsNotDateOrRegExp(cx, obj);
-}
-
-MOZ_ALWAYS_INLINE bool
-IsObjectValueConvertibleToDictionary(JSContext* cx,
-                                     JS::Handle<JS::Value> objVal)
-{
-  JS::Rooted<JSObject*> obj(cx, &objVal.toObject());
-  return IsNotDateOrRegExp(cx, obj);
-}
-
-MOZ_ALWAYS_INLINE bool
-IsConvertibleToDictionary(JSContext* cx, JS::Handle<JS::Value> val)
-{
-  return val.isNullOrUndefined() ||
-    (val.isObject() && IsObjectValueConvertibleToDictionary(cx, val));
-}
-
-MOZ_ALWAYS_INLINE bool
-IsConvertibleToCallbackInterface(JSContext* cx, JS::Handle<JSObject*> obj)
-{
-  return IsNotDateOrRegExp(cx, obj);
-}
-
-// The items in the protoAndIfaceArray are indexed by the prototypes::id::ID and
-// constructors::id::ID enums, in that order. The end of the prototype objects
-// should be the start of the interface objects.
-static_assert((size_t)constructors::id::_ID_Start ==
-              (size_t)prototypes::id::_ID_Count,
-              "Overlapping or discontiguous indexes.");
-const size_t kProtoAndIfaceCacheCount = constructors::id::_ID_Count;
-
-inline void
-AllocateProtoAndIfaceCache(JSObject* obj)
-{
-  MOZ_ASSERT(js::GetObjectClass(obj)->flags & JSCLASS_DOM_GLOBAL);
-  MOZ_ASSERT(js::GetReservedSlot(obj, DOM_PROTOTYPE_SLOT).isUndefined());
-
-  JS::Heap<JSObject*>* protoAndIfaceArray = new JS::Heap<JSObject*>[kProtoAndIfaceCacheCount];
-
-  js::SetReservedSlot(obj, DOM_PROTOTYPE_SLOT,
-                      JS::PrivateValue(protoAndIfaceArray));
-}
-
-inline void
-TraceProtoAndIfaceCache(JSTracer* trc, JSObject* obj)
-{
-  MOZ_ASSERT(js::GetObjectClass(obj)->flags & JSCLASS_DOM_GLOBAL);
-
-  if (!HasProtoAndIfaceArray(obj))
-    return;
-  JS::Heap<JSObject*>* protoAndIfaceArray = GetProtoAndIfaceArray(obj);
-  for (size_t i = 0; i < kProtoAndIfaceCacheCount; ++i) {
-    if (protoAndIfaceArray[i]) {
-      JS_CallHeapObjectTracer(trc, &protoAndIfaceArray[i], "protoAndIfaceArray[i]");
-    }
-  }
-}
-
-inline void
-DestroyProtoAndIfaceCache(JSObject* obj)
-{
-  MOZ_ASSERT(js::GetObjectClass(obj)->flags & JSCLASS_DOM_GLOBAL);
-
-  JS::Heap<JSObject*>* protoAndIfaceArray = GetProtoAndIfaceArray(obj);
-
-  delete [] protoAndIfaceArray;
-}
-
-/**
- * Add constants to an object.
- */
-bool
-DefineConstants(JSContext* cx, JS::Handle<JSObject*> obj,
-                const ConstantSpec* cs);
-
-struct JSNativeHolder
-{
-  JSNative mNative;
-  const NativePropertyHooks* mPropertyHooks;
-};
-
-struct NamedConstructor
-{
-  const char* mName;
-  const JSNativeHolder mHolder;
-  unsigned mNargs;
-};
-
-/*
- * Create a DOM interface object (if constructorClass is non-null) and/or a
- * DOM interface prototype object (if protoClass is non-null).
- *
- * global is used as the parent of the interface object and the interface
- *        prototype object
- * protoProto is the prototype to use for the interface prototype object.
- * interfaceProto is the prototype to use for the interface object.
- * protoClass is the JSClass to use for the interface prototype object.
- *            This is null if we should not create an interface prototype
- *            object.
- * protoCache a pointer to a JSObject pointer where we should cache the
- *            interface prototype object. This must be null if protoClass is and
- *            vice versa.
- * constructorClass is the JSClass to use for the interface object.
- *                  This is null if we should not create an interface object or
- *                  if it should be a function object.
- * constructor holds the JSNative to back the interface object which should be a
- *             Function, unless constructorClass is non-null in which case it is
- *             ignored. If this is null and constructorClass is also null then
- *             we should not create an interface object at all.
- * ctorNargs is the length of the constructor function; 0 if no constructor
- * constructorCache a pointer to a JSObject pointer where we should cache the
- *                  interface object. This must be null if both constructorClass
- *                  and constructor are null, and non-null otherwise.
- * domClass is the DOMClass of instance objects for this class.  This can be
- *          null if this is not a concrete proto.
- * properties contains the methods, attributes and constants to be defined on
- *            objects in any compartment.
- * chromeProperties contains the methods, attributes and constants to be defined
- *                  on objects in chrome compartments. This must be null if the
- *                  interface doesn't have any ChromeOnly properties or if the
- *                  object is being created in non-chrome compartment.
- * defineOnGlobal controls whether properties should be defined on the given
- *                global for the interface object (if any) and named
- *                constructors (if any) for this interface.  This can be
- *                false in situations where we want the properties to only
- *                appear on privileged Xrays but not on the unprivileged
- *                underlying global.
- *
- * At least one of protoClass, constructorClass or constructor should be
- * non-null. If constructorClass or constructor are non-null, the resulting
- * interface object will be defined on the given global with property name
- * |name|, which must also be non-null.
- */
-void
-CreateInterfaceObjects(JSContext* cx, JS::Handle<JSObject*> global,
-                       JS::Handle<JSObject*> protoProto,
-                       JSClass* protoClass, JS::Heap<JSObject*>* protoCache,
-                       JS::Handle<JSObject*> interfaceProto,
-                       JSClass* constructorClass, const JSNativeHolder* constructor,
-                       unsigned ctorNargs, const NamedConstructor* namedConstructors,
-                       JS::Heap<JSObject*>* constructorCache, const DOMClass* domClass,
-                       const NativeProperties* regularProperties,
-                       const NativeProperties* chromeOnlyProperties,
-                       const char* name, bool defineOnGlobal);
-
-/*
- * Define the unforgeable attributes on an object.
- */
-bool
-DefineUnforgeableAttributes(JSContext* cx, JS::Handle<JSObject*> obj,
-                            const Prefable<const JSPropertySpec>* props);
-
-bool
-DefineWebIDLBindingPropertiesOnXPCProto(JSContext* cx,
-                                        JS::Handle<JSObject*> proto,
-                                        const NativeProperties* properties);
-
-#ifdef _MSC_VER
-#define HAS_MEMBER_CHECK(_name)                                           \
-  template<typename V> static yes& Check(char (*)[(&V::_name == 0) + 1])
-#else
-#define HAS_MEMBER_CHECK(_name)                                           \
-  template<typename V> static yes& Check(char (*)[sizeof(&V::_name) + 1])
-#endif
-
-#define HAS_MEMBER(_name)                                                 \
-template<typename T>                                                      \
-class Has##_name##Member {                                                \
-  typedef char yes[1];                                                    \
-  typedef char no[2];                                                     \
-  HAS_MEMBER_CHECK(_name);                                                \
-  template<typename V> static no& Check(...);                             \
-                                                                          \
-public:                                                                   \
-  static bool const Value = sizeof(Check<T>(nullptr)) == sizeof(yes);     \
-};
-
-HAS_MEMBER(WrapObject)
-
-// HasWrapObject<T>::Value will be true if T has a WrapObject member but it's
-// not nsWrapperCache::WrapObject.
-template<typename T>
-struct HasWrapObject
-{
-private:
-  typedef char yes[1];
-  typedef char no[2];
-  typedef JSObject* (nsWrapperCache::*WrapObject)(JSContext*,
-                                                  JS::Handle<JSObject*>);
-  template<typename U, U> struct SFINAE;
-  template <typename V> static no& Check(SFINAE<WrapObject, &V::WrapObject>*);
-  template <typename V> static yes& Check(...);
-
-public:
-  static bool const Value = HasWrapObjectMember<T>::Value &&
-                            sizeof(Check<T>(nullptr)) == sizeof(yes);
-};
-
-#ifdef DEBUG
-template <class T, bool isISupports=IsBaseOf<nsISupports, T>::value>
-struct
-CheckWrapperCacheCast
-{
-  static bool Check()
-  {
-    return reinterpret_cast<uintptr_t>(
-      static_cast<nsWrapperCache*>(
-        reinterpret_cast<T*>(1))) == 1;
-  }
-};
-template <class T>
-struct
-CheckWrapperCacheCast<T, true>
-{
-  static bool Check()
-  {
-    return true;
-  }
-};
-#endif
-
-MOZ_ALWAYS_INLINE bool
-CouldBeDOMBinding(void*)
-{
-  return true;
-}
-
-MOZ_ALWAYS_INLINE bool
-CouldBeDOMBinding(nsWrapperCache* aCache)
-{
-  return aCache->IsDOMBinding();
-}
-
-// The DOM_OBJECT_SLOT_SOW slot contains a JS::ObjectValue which points to the
-// cached system object wrapper (SOW) or JS::UndefinedValue if this class
-// doesn't need SOWs.
-
-inline const JS::Value&
-GetSystemOnlyWrapperSlot(JSObject* obj)
-{
-  MOZ_ASSERT(IsDOMClass(js::GetObjectJSClass(obj)) &&
-             !(js::GetObjectJSClass(obj)->flags & JSCLASS_DOM_GLOBAL));
-  return js::GetReservedSlot(obj, DOM_OBJECT_SLOT_SOW);
-}
-inline void
-SetSystemOnlyWrapperSlot(JSObject* obj, const JS::Value& v)
-{
-  MOZ_ASSERT(IsDOMClass(js::GetObjectJSClass(obj)) &&
-             !(js::GetObjectJSClass(obj)->flags & JSCLASS_DOM_GLOBAL));
-  js::SetReservedSlot(obj, DOM_OBJECT_SLOT_SOW, v);
-}
-
-inline bool
-GetSameCompartmentWrapperForDOMBinding(JSObject*& obj)
-{
-  js::Class* clasp = js::GetObjectClass(obj);
-  if (dom::IsDOMClass(clasp)) {
-    if (!(clasp->flags & JSCLASS_DOM_GLOBAL)) {
-      JS::Value v = GetSystemOnlyWrapperSlot(obj);
-      if (v.isObject()) {
-        obj = &v.toObject();
-      }
-    }
-    return true;
-  }
-  return IsDOMProxy(obj, clasp);
-}
-
-inline void
-SetSystemOnlyWrapper(JSObject* obj, nsWrapperCache* cache, JSObject& wrapper)
-{
-  SetSystemOnlyWrapperSlot(obj, JS::ObjectValue(wrapper));
-  cache->SetHasSystemOnlyWrapper();
-}
-
-// Make sure to wrap the given string value into the right compartment, as
-// needed.
-MOZ_ALWAYS_INLINE
-bool
-MaybeWrapStringValue(JSContext* cx, JS::MutableHandle<JS::Value> rval)
-{
-  MOZ_ASSERT(rval.isString());
-  JSString* str = rval.toString();
-  if (JS::GetGCThingZone(str) != js::GetContextZone(cx)) {
-    return JS_WrapValue(cx, rval.address());
-  }
-  return true;
-}
-
-// Make sure to wrap the given object value into the right compartment as
-// needed.  This will work correctly, but possibly slowly, on all objects.
-MOZ_ALWAYS_INLINE
-bool
-MaybeWrapObjectValue(JSContext* cx, JS::MutableHandle<JS::Value> rval)
-{
-  MOZ_ASSERT(rval.isObject());
-
-  JSObject* obj = &rval.toObject();
-  if (js::GetObjectCompartment(obj) != js::GetContextCompartment(cx)) {
-    return JS_WrapValue(cx, rval.address());
-  }
-
-  // We're same-compartment, but even then we might need to wrap
-  // objects specially.  Check for that.
-  if (GetSameCompartmentWrapperForDOMBinding(obj)) {
-    // We're a new-binding object, and "obj" now points to the right thing
-    rval.set(JS::ObjectValue(*obj));
-    return true;
-  }
-
-  // It's not a WebIDL object.  But it might be an XPConnect one, in which case
-  // we may need to outerize here, so make sure to call JS_WrapValue.
-  return JS_WrapValue(cx, rval.address());
-}
-
-// Like MaybeWrapObjectValue, but also allows null
-MOZ_ALWAYS_INLINE
-bool
-MaybeWrapObjectOrNullValue(JSContext* cx, JS::MutableHandle<JS::Value> rval)
-{
-  MOZ_ASSERT(rval.isObjectOrNull());
-  if (rval.isNull()) {
-    return true;
-  }
-  return MaybeWrapObjectValue(cx, rval);
-}
-
-// Wrapping for objects that are known to not be DOM or XPConnect objects
-MOZ_ALWAYS_INLINE
-bool
-MaybeWrapNonDOMObjectValue(JSContext* cx, JS::MutableHandle<JS::Value> rval)
-{
-  MOZ_ASSERT(rval.isObject());
-  MOZ_ASSERT(!GetDOMClass(&rval.toObject()));
-  MOZ_ASSERT(!(js::GetObjectClass(&rval.toObject())->flags &
-               JSCLASS_PRIVATE_IS_NSISUPPORTS));
-
-  JSObject* obj = &rval.toObject();
-  if (js::GetObjectCompartment(obj) == js::GetContextCompartment(cx)) {
-    return true;
-  }
-  return JS_WrapValue(cx, rval.address());
-}
-
-// Like MaybeWrapNonDOMObjectValue but allows null
-MOZ_ALWAYS_INLINE
-bool
-MaybeWrapNonDOMObjectOrNullValue(JSContext* cx, JS::MutableHandle<JS::Value> rval)
-{
-  MOZ_ASSERT(rval.isObjectOrNull());
-  if (rval.isNull()) {
-    return true;
-  }
-  return MaybeWrapNonDOMObjectValue(cx, rval);
-}
-
-// If rval is a gcthing and is not in the compartment of cx, wrap rval
-// into the compartment of cx (typically by replacing it with an Xray or
-// cross-compartment wrapper around the original object).
-MOZ_ALWAYS_INLINE bool
-MaybeWrapValue(JSContext* cx, JS::MutableHandle<JS::Value> rval)
-{
-  if (rval.isString()) {
-    return MaybeWrapStringValue(cx, rval);
-  }
-
-  if (!rval.isObject()) {
-    return true;
-  }
-
-  return MaybeWrapObjectValue(cx, rval);
-}
-
-static inline void
-WrapNewBindingForSameCompartment(JSContext* cx, JSObject* obj, void* value,
-                                 JS::MutableHandle<JS::Value> rval)
-{
-  rval.set(JS::ObjectValue(*obj));
-}
-
-static inline void
-WrapNewBindingForSameCompartment(JSContext* cx, JSObject* obj,
-                                 nsWrapperCache* value,
-                                 JS::MutableHandle<JS::Value> rval)
-{
-  if (value->HasSystemOnlyWrapper()) {
-    rval.set(GetSystemOnlyWrapperSlot(obj));
-    MOZ_ASSERT(rval.isObject());
-  } else {
-    rval.set(JS::ObjectValue(*obj));
-  }
-}
-
-// Create a JSObject wrapping "value", if there isn't one already, and store it
-// in rval.  "value" must be a concrete class that implements a
-// GetWrapperPreserveColor() which can return its existing wrapper, if any, and
-// a WrapObject() which will try to create a wrapper. Typically, this is done by
-// having "value" inherit from nsWrapperCache.
-template <class T>
-MOZ_ALWAYS_INLINE bool
-WrapNewBindingObject(JSContext* cx, JS::Handle<JSObject*> scope, T* value,
-                     JS::MutableHandle<JS::Value> rval)
-{
-  MOZ_ASSERT(value);
-  JSObject* obj = value->GetWrapperPreserveColor();
-  bool couldBeDOMBinding = CouldBeDOMBinding(value);
-  if (obj) {
-    JS::ExposeObjectToActiveJS(obj);
-  } else {
-    // Inline this here while we have non-dom objects in wrapper caches.
-    if (!couldBeDOMBinding) {
-      return false;
-    }
-
-    obj = value->WrapObject(cx, scope);
-    if (!obj) {
-      // At this point, obj is null, so just return false.
-      // Callers seem to be testing JS_IsExceptionPending(cx) to
-      // figure out whether WrapObject() threw.
-      return false;
-    }
-  }
-
-#ifdef DEBUG
-  const DOMClass* clasp = GetDOMClass(obj);
-  // clasp can be null if the cache contained a non-DOM object from a
-  // different compartment than scope.
-  if (clasp) {
-    // Some sanity asserts about our object.  Specifically:
-    // 1)  If our class claims we're nsISupports, we better be nsISupports
-    //     XXXbz ideally, we could assert that reinterpret_cast to nsISupports
-    //     does the right thing, but I don't see a way to do it.  :(
-    // 2)  If our class doesn't claim we're nsISupports we better be
-    //     reinterpret_castable to nsWrapperCache.
-    MOZ_ASSERT(clasp, "What happened here?");
-    MOZ_ASSERT_IF(clasp->mDOMObjectIsISupports, (IsBaseOf<nsISupports, T>::value));
-    MOZ_ASSERT(CheckWrapperCacheCast<T>::Check());
-  }
-
-  // When called via XrayWrapper, we end up here while running in the
-  // chrome compartment.  But the obj we have would be created in
-  // whatever the content compartment is.  So at this point we need to
-  // make sure it's correctly wrapped for the compartment of |scope|.
-  // cx should already be in the compartment of |scope| here.
-  MOZ_ASSERT(js::IsObjectInContextCompartment(scope, cx));
-#endif
-
-  bool sameCompartment =
-    js::GetObjectCompartment(obj) == js::GetContextCompartment(cx);
-  if (sameCompartment && couldBeDOMBinding) {
-    WrapNewBindingForSameCompartment(cx, obj, value, rval);
-    return true;
-  }
-
-  rval.set(JS::ObjectValue(*obj));
-  return JS_WrapValue(cx, rval.address());
-}
-
-// Create a JSObject wrapping "value", for cases when "value" is a
-// non-wrapper-cached object using WebIDL bindings.  "value" must implement a
-// WrapObject() method taking a JSContext and a scope.
-template <class T>
-inline bool
-WrapNewBindingNonWrapperCachedObject(JSContext* cx,
-                                     JS::Handle<JSObject*> scopeArg,
-                                     T* value,
-                                     JS::MutableHandle<JS::Value> rval)
-{
-  MOZ_ASSERT(value);
-  // We try to wrap in the compartment of the underlying object of "scope"
-  JS::Rooted<JSObject*> obj(cx);
-  {
-    // scope for the JSAutoCompartment so that we restore the compartment
-    // before we call JS_WrapValue.
-    Maybe<JSAutoCompartment> ac;
-    // Maybe<Handle> doesn't so much work, and in any case, adding
-    // more Maybe (one for a Rooted and one for a Handle) adds more
-    // code (and branches!) than just adding a single rooted.
-    JS::Rooted<JSObject*> scope(cx, scopeArg);
-    if (js::IsWrapper(scope)) {
-      scope = js::CheckedUnwrap(scope, /* stopAtOuter = */ false);
-      if (!scope)
-        return false;
-      ac.construct(cx, scope);
-    }
-
-    obj = value->WrapObject(cx, scope);
-  }
-
-  if (!obj) {
-    return false;
-  }
-
-  // We can end up here in all sorts of compartments, per above.  Make
-  // sure to JS_WrapValue!
-  rval.set(JS::ObjectValue(*obj));
-  return JS_WrapValue(cx, rval.address());
-}
-
-// Create a JSObject wrapping "value", for cases when "value" is a
-// non-wrapper-cached owned object using WebIDL bindings.  "value" must implement a
-// WrapObject() method taking a JSContext, a scope, and a boolean outparam that
-// is true if the JSObject took ownership
-template <class T>
-inline bool
-WrapNewBindingNonWrapperCachedOwnedObject(JSContext* cx,
-                                          JS::Handle<JSObject*> scopeArg,
-                                          nsAutoPtr<T>& value,
-                                          JS::MutableHandle<JS::Value> rval)
-{
-  // We do a runtime check on value, because otherwise we might in
-  // fact end up wrapping a null and invoking methods on it later.
-  if (!value) {
-    NS_RUNTIMEABORT("Don't try to wrap null objects");
-  }
-  // We try to wrap in the compartment of the underlying object of "scope"
-  JS::Rooted<JSObject*> obj(cx);
-  {
-    // scope for the JSAutoCompartment so that we restore the compartment
-    // before we call JS_WrapValue.
-    Maybe<JSAutoCompartment> ac;
-    // Maybe<Handle> doesn't so much work, and in any case, adding
-    // more Maybe (one for a Rooted and one for a Handle) adds more
-    // code (and branches!) than just adding a single rooted.
-    JS::Rooted<JSObject*> scope(cx, scopeArg);
-    if (js::IsWrapper(scope)) {
-      scope = js::CheckedUnwrap(scope, /* stopAtOuter = */ false);
-      if (!scope)
-        return false;
-      ac.construct(cx, scope);
-    }
-
-    bool tookOwnership = false;
-    obj = value->WrapObject(cx, scope, &tookOwnership);
-    MOZ_ASSERT_IF(obj, tookOwnership);
-    if (tookOwnership) {
-      value.forget();
-    }
-  }
-
-  if (!obj) {
-    return false;
-  }
-
-  // We can end up here in all sorts of compartments, per above.  Make
-  // sure to JS_WrapValue!
-  rval.set(JS::ObjectValue(*obj));
-  return JS_WrapValue(cx, rval.address());
-}
-
-// Helper for smart pointers (nsAutoPtr/nsRefPtr/nsCOMPtr).
-template <template <typename> class SmartPtr, typename T>
-inline bool
-WrapNewBindingNonWrapperCachedObject(JSContext* cx, JS::Handle<JSObject*> scope,
-                                     const SmartPtr<T>& value,
-                                     JS::MutableHandle<JS::Value> rval)
-{
-  return WrapNewBindingNonWrapperCachedObject(cx, scope, value.get(), rval);
-}
-
-// Only set allowNativeWrapper to false if you really know you need it, if in
-// doubt use true. Setting it to false disables security wrappers.
-bool
-NativeInterface2JSObjectAndThrowIfFailed(JSContext* aCx,
-                                         JS::Handle<JSObject*> aScope,
-                                         JS::Value* aRetval,
-                                         xpcObjectHelper& aHelper,
-                                         const nsIID* aIID,
-                                         bool aAllowNativeWrapper);
-
-/**
- * A method to handle new-binding wrap failure, by possibly falling back to
- * wrapping as a non-new-binding object.
- */
-template <class T>
-MOZ_ALWAYS_INLINE bool
-HandleNewBindingWrappingFailure(JSContext* cx, JS::Handle<JSObject*> scope,
-                                T* value, JS::MutableHandle<JS::Value> rval)
-{
-  if (JS_IsExceptionPending(cx)) {
-    return false;
-  }
-
-  qsObjectHelper helper(value, GetWrapperCache(value));
-  return NativeInterface2JSObjectAndThrowIfFailed(cx, scope, rval.address(),
-                                                  helper, nullptr, true);
-}
-
-// Helper for calling HandleNewBindingWrappingFailure with smart pointers
-// (nsAutoPtr/nsRefPtr/nsCOMPtr) or references.
-HAS_MEMBER(get)
-
-template <class T, bool isSmartPtr=HasgetMember<T>::Value>
-struct HandleNewBindingWrappingFailureHelper
-{
-  static inline bool Wrap(JSContext* cx, JS::Handle<JSObject*> scope,
-                          const T& value, JS::MutableHandle<JS::Value> rval)
-  {
-    return HandleNewBindingWrappingFailure(cx, scope, value.get(), rval);
-  }
-};
-
-template <class T>
-struct HandleNewBindingWrappingFailureHelper<T, false>
-{
-  static inline bool Wrap(JSContext* cx, JS::Handle<JSObject*> scope, T& value,
-                          JS::MutableHandle<JS::Value> rval)
-  {
-    return HandleNewBindingWrappingFailure(cx, scope, &value, rval);
-  }
-};
-
-template<class T>
-inline bool
-HandleNewBindingWrappingFailure(JSContext* cx, JS::Handle<JSObject*> scope,
-                                T& value, JS::MutableHandle<JS::Value> rval)
-{
-  return HandleNewBindingWrappingFailureHelper<T>::Wrap(cx, scope, value, rval);
-}
-
-template<bool Fatal>
-inline bool
-EnumValueNotFound(JSContext* cx, const jschar* chars, size_t length,
-                  const char* type, const char* sourceDescription)
-{
-  return false;
-}
-
-template<>
-inline bool
-EnumValueNotFound<false>(JSContext* cx, const jschar* chars, size_t length,
-                         const char* type, const char* sourceDescription)
-{
-  // TODO: Log a warning to the console.
-  return true;
-}
-
-template<>
-inline bool
-EnumValueNotFound<true>(JSContext* cx, const jschar* chars, size_t length,
-                        const char* type, const char* sourceDescription)
-{
-  NS_LossyConvertUTF16toASCII deflated(static_cast<const PRUnichar*>(chars),
-                                       length);
-  return ThrowErrorMessage(cx, MSG_INVALID_ENUM_VALUE, sourceDescription,
-                           deflated.get(), type);
-}
-
-
-template<bool InvalidValueFatal>
-inline int
-FindEnumStringIndex(JSContext* cx, JS::Value v, const EnumEntry* values,
-                    const char* type, const char* sourceDescription, bool* ok)
-{
-  // JS_StringEqualsAscii is slow as molasses, so don't use it here.
-  JSString* str = JS_ValueToString(cx, v);
-  if (!str) {
-    *ok = false;
-    return 0;
-  }
-  JS::Anchor<JSString*> anchor(str);
-  size_t length;
-  const jschar* chars = JS_GetStringCharsAndLength(cx, str, &length);
-  if (!chars) {
-    *ok = false;
-    return 0;
-  }
-  int i = 0;
-  for (const EnumEntry* value = values; value->value; ++value, ++i) {
-    if (length != value->length) {
-      continue;
-    }
-
-    bool equal = true;
-    const char* val = value->value;
-    for (size_t j = 0; j != length; ++j) {
-      if (unsigned(val[j]) != unsigned(chars[j])) {
-        equal = false;
-        break;
-      }
-    }
-
-    if (equal) {
-      *ok = true;
-      return i;
-    }
-  }
-
-  *ok = EnumValueNotFound<InvalidValueFatal>(cx, chars, length, type,
-                                             sourceDescription);
-  return -1;
-}
-
-inline nsWrapperCache*
-GetWrapperCache(const ParentObject& aParentObject)
-{
-  return aParentObject.mWrapperCache;
-}
-
-template<class T>
-inline T*
-GetParentPointer(T* aObject)
-{
-  return aObject;
-}
-
-inline nsISupports*
-GetParentPointer(const ParentObject& aObject)
-{
-  return aObject.mObject;
-}
-
-template<class T>
-inline void
-ClearWrapper(T* p, nsWrapperCache* cache)
-{
-  cache->ClearWrapper();
-}
-
-template<class T>
-inline void
-ClearWrapper(T* p, void*)
-{
-  nsWrapperCache* cache;
-  CallQueryInterface(p, &cache);
-  ClearWrapper(p, cache);
-}
-
-// Attempt to preserve the wrapper, if any, for a Paris DOM bindings object.
-// Return true if we successfully preserved the wrapper, or there is no wrapper
-// to preserve. In the latter case we don't need to preserve the wrapper, because
-// the object can only be obtained by JS once, or they cannot be meaningfully
-// owned from the native side.
-//
-// This operation will return false only for non-nsISupports cycle-collected
-// objects, because we cannot determine if they are wrappercached or not.
-bool
-TryPreserveWrapper(JSObject* obj);
-
-// Can only be called with the immediate prototype of the instance object. Can
-// only be called on the prototype of an object known to be a DOM instance.
-bool
-InstanceClassHasProtoAtDepth(JS::Handle<JSObject*> protoObject, uint32_t protoID,
-                             uint32_t depth);
-
-// Only set allowNativeWrapper to false if you really know you need it, if in
-// doubt use true. Setting it to false disables security wrappers.
-bool
-XPCOMObjectToJsval(JSContext* cx, JS::Handle<JSObject*> scope,
-                   xpcObjectHelper& helper, const nsIID* iid,
-                   bool allowNativeWrapper, JS::Value* rval);
-
-// Special-cased wrapping for variants
-bool
-VariantToJsval(JSContext* aCx, JS::Handle<JSObject*> aScope,
-               nsIVariant* aVariant, JS::Value* aRetval);
-
-// Wrap an object "p" which is not using WebIDL bindings yet.  This _will_
-// actually work on WebIDL binding objects that are wrappercached, but will be
-// much slower than WrapNewBindingObject.  "cache" must either be null or be the
-// nsWrapperCache for "p".
-template<class T>
-inline bool
-WrapObject(JSContext* cx, JS::Handle<JSObject*> scope, T* p,
-           nsWrapperCache* cache, const nsIID* iid,
-           JS::MutableHandle<JS::Value> rval)
-{
-  if (xpc_FastGetCachedWrapper(cache, scope, rval.address()))
-    return true;
-  qsObjectHelper helper(p, cache);
-  return XPCOMObjectToJsval(cx, scope, helper, iid, true, rval.address());
-}
-
-// A specialization of the above for nsIVariant, because that needs to
-// do something different.
-template<>
-inline bool
-WrapObject<nsIVariant>(JSContext* cx, JS::Handle<JSObject*> scope, nsIVariant* p,
-                       nsWrapperCache* cache, const nsIID* iid,
-                       JS::MutableHandle<JS::Value> rval)
-{
-  MOZ_ASSERT(iid);
-  MOZ_ASSERT(iid->Equals(NS_GET_IID(nsIVariant)));
-  return VariantToJsval(cx, scope, p, rval.address());
-}
-
-// Wrap an object "p" which is not using WebIDL bindings yet.  Just like the
-// variant that takes an nsWrapperCache above, but will try to auto-derive the
-// nsWrapperCache* from "p".
-template<class T>
-inline bool
-WrapObject(JSContext* cx, JS::Handle<JSObject*> scope, T* p, const nsIID* iid,
-           JS::MutableHandle<JS::Value> rval)
-{
-  return WrapObject(cx, scope, p, GetWrapperCache(p), iid, rval);
-}
-
-// Just like the WrapObject above, but without requiring you to pick which
-// interface you're wrapping as.  This should only be used for objects that have
-// classinfo, for which it doesn't matter what IID is used to wrap.
-template<class T>
-inline bool
-WrapObject(JSContext* cx, JS::Handle<JSObject*> scope, T* p,
-           JS::MutableHandle<JS::Value> rval)
-{
-  return WrapObject(cx, scope, p, NULL, rval);
-}
-
-// Helper to make it possible to wrap directly out of an nsCOMPtr
-template<class T>
-inline bool
-WrapObject(JSContext* cx, JS::Handle<JSObject*> scope, const nsCOMPtr<T>& p,
-           const nsIID* iid, JS::MutableHandle<JS::Value> rval)
-{
-  return WrapObject(cx, scope, p.get(), iid, rval);
-}
-
-// Helper to make it possible to wrap directly out of an nsCOMPtr
-template<class T>
-inline bool
-WrapObject(JSContext* cx, JS::Handle<JSObject*> scope, const nsCOMPtr<T>& p,
-           JS::MutableHandle<JS::Value> rval)
-{
-  return WrapObject(cx, scope, p, NULL, rval);
-}
-
-// Helper to make it possible to wrap directly out of an nsRefPtr
-template<class T>
-inline bool
-WrapObject(JSContext* cx, JS::Handle<JSObject*> scope, const nsRefPtr<T>& p,
-           const nsIID* iid, JS::MutableHandle<JS::Value> rval)
-{
-  return WrapObject(cx, scope, p.get(), iid, rval);
-}
-
-// Helper to make it possible to wrap directly out of an nsRefPtr
-template<class T>
-inline bool
-WrapObject(JSContext* cx, JS::Handle<JSObject*> scope, const nsRefPtr<T>& p,
-           JS::MutableHandle<JS::Value> rval)
-{
-  return WrapObject(cx, scope, p, NULL, rval);
-}
-
-// Specialization to make it easy to use WrapObject in codegen.
-template<>
-inline bool
-WrapObject<JSObject>(JSContext* cx, JS::Handle<JSObject*> scope, JSObject* p,
-                     JS::MutableHandle<JS::Value> rval)
-{
-  rval.set(JS::ObjectOrNullValue(p));
-  return true;
-}
-
-inline bool
-WrapObject(JSContext* cx, JS::Handle<JSObject*> scope, JSObject& p,
-           JS::MutableHandle<JS::Value> rval)
-{
-  rval.set(JS::ObjectValue(p));
-  return true;
-}
-
-// Given an object "p" that inherits from nsISupports, wrap it and return the
-// result.  Null is returned on wrapping failure.  This is somewhat similar to
-// WrapObject() above, but does NOT allow Xrays around the result, since we
-// don't want those for our parent object.
-template<typename T>
-static inline JSObject*
-WrapNativeISupportsParent(JSContext* cx, JS::Handle<JSObject*> scope, T* p,
-                          nsWrapperCache* cache)
-{
-  qsObjectHelper helper(ToSupports(p), cache);
-  JS::Rooted<JS::Value> v(cx);
-  return XPCOMObjectToJsval(cx, scope, helper, nullptr, false, v.address()) ?
-         JSVAL_TO_OBJECT(v) :
-         nullptr;
-}
-
-
-// Fallback for when our parent is not a WebIDL binding object.
-template<typename T, bool isISupports=IsBaseOf<nsISupports, T>::value>
-struct WrapNativeParentFallback
-{
-  static inline JSObject* Wrap(JSContext* cx, JS::Handle<JSObject*> scope,
-                               T* parent, nsWrapperCache* cache)
-  {
-    return nullptr;
-  }
-};
-
-// Fallback for when our parent is not a WebIDL binding object but _is_ an
-// nsISupports object.
-template<typename T >
-struct WrapNativeParentFallback<T, true >
-{
-  static inline JSObject* Wrap(JSContext* cx, JS::Handle<JSObject*> scope,
-                               T* parent, nsWrapperCache* cache)
-  {
-    return WrapNativeISupportsParent(cx, scope, parent, cache);
-  }
-};
-
-// Wrapping of our native parent, for cases when it's a WebIDL object (though
-// possibly preffed off).
-template<typename T, bool hasWrapObject=HasWrapObject<T>::Value >
-struct WrapNativeParentHelper
-{
-  static inline JSObject* Wrap(JSContext* cx, JS::Handle<JSObject*> scope,
-                               T* parent, nsWrapperCache* cache)
-  {
-    MOZ_ASSERT(cache);
-
-    JSObject* obj;
-    if ((obj = cache->GetWrapper())) {
-      return obj;
-    }
-
-    // Inline this here while we have non-dom objects in wrapper caches.
-    if (!CouldBeDOMBinding(parent)) {
-      obj = WrapNativeParentFallback<T>::Wrap(cx, scope, parent, cache);
-    } else {
-      obj = parent->WrapObject(cx, scope);
-    }
-
-    return obj;
-  }
-};
-
-// Wrapping of our native parent, for cases when it's not a WebIDL object.  In
-// this case it must be nsISupports.
-template<typename T>
-struct WrapNativeParentHelper<T, false >
-{
-  static inline JSObject* Wrap(JSContext* cx, JS::Handle<JSObject*> scope,
-                               T* parent, nsWrapperCache* cache)
-  {
-    JSObject* obj;
-    if (cache && (obj = cache->GetWrapper())) {
-#ifdef DEBUG
-      NS_ASSERTION(WrapNativeISupportsParent(cx, scope, parent, cache) == obj,
-                   "Unexpected object in nsWrapperCache");
-#endif
-      return obj;
-    }
-
-    return WrapNativeISupportsParent(cx, scope, parent, cache);
-  }
-};
-
-// Wrapping of our native parent.
-template<typename T>
-static inline JSObject*
-WrapNativeParent(JSContext* cx, JS::Handle<JSObject*> scope, T* p,
-                 nsWrapperCache* cache)
-{
-  if (!p) {
-    return scope;
-  }
-
-  return WrapNativeParentHelper<T>::Wrap(cx, scope, p, cache);
-}
-
-// Wrapping of our native parent, when we don't want to explicitly pass in
-// things like the nsWrapperCache for it.
-template<typename T>
-static inline JSObject*
-WrapNativeParent(JSContext* cx, JS::Handle<JSObject*> scope, const T& p)
-{
-  return WrapNativeParent(cx, scope, GetParentPointer(p), GetWrapperCache(p));
-}
-
-// A way to differentiate between nodes, which use the parent object
-// returned by native->GetParentObject(), and all other objects, which
-// just use the parent's global.
-static inline JSObject*
-GetRealParentObject(void* aParent, JSObject* aParentObject)
-{
-  return aParentObject ?
-    js::GetGlobalForObjectCrossCompartment(aParentObject) : nullptr;
-}
-
-static inline JSObject*
-GetRealParentObject(Element* aParent, JSObject* aParentObject)
-{
-  return aParentObject;
-}
-
-HAS_MEMBER(GetParentObject)
-
-template<typename T, bool WrapperCached=HasGetParentObjectMember<T>::Value>
-struct GetParentObject
-{
-  static JSObject* Get(JSContext* cx, JS::Handle<JSObject*> obj)
-  {
-    T* native = UnwrapDOMObject<T>(obj);
-    return
-      GetRealParentObject(native,
-                          WrapNativeParent(cx, obj, native->GetParentObject()));
-  }
-};
-
-template<typename T>
-struct GetParentObject<T, false>
-{
-  static JSObject* Get(JSContext* cx, JS::Handle<JSObject*> obj)
-  {
-    MOZ_CRASH();
-    return nullptr;
-  }
-};
-
-MOZ_ALWAYS_INLINE
-JSObject* GetJSObjectFromCallback(CallbackObject* callback)
-{
-  return callback->Callback();
-}
-
-MOZ_ALWAYS_INLINE
-JSObject* GetJSObjectFromCallback(void* noncallback)
-{
-  return nullptr;
-}
-
-template<typename T>
-static inline JSObject*
-WrapCallThisObject(JSContext* cx, JS::Handle<JSObject*> scope, const T& p)
-{
-  // Callbacks are nsISupports, so WrapNativeParent will just happily wrap them
-  // up as an nsISupports XPCWrappedNative... which is not at all what we want.
-  // So we need to special-case them.
-  JS::Rooted<JSObject*> obj(cx, GetJSObjectFromCallback(p));
-  if (!obj) {
-    // WrapNativeParent is a bit of a Swiss army knife that will
-    // wrap anything for us.
-    obj = WrapNativeParent(cx, scope, p);
-    if (!obj) {
-      return nullptr;
-    }
-  }
-
-  // But all that won't necessarily put things in the compartment of cx.
-  if (!JS_WrapObject(cx, obj.address())) {
-    return nullptr;
-  }
-
-  return obj;
-}
-
-// Helper for calling WrapNewBindingObject with smart pointers
-// (nsAutoPtr/nsRefPtr/nsCOMPtr) or references.
-template <class T, bool isSmartPtr=HasgetMember<T>::Value>
-struct WrapNewBindingObjectHelper
-{
-  static inline bool Wrap(JSContext* cx, JS::Handle<JSObject*> scope,
-                          const T& value, JS::MutableHandle<JS::Value> rval)
-  {
-    return WrapNewBindingObject(cx, scope, value.get(), rval);
-  }
-};
-
-template <class T>
-struct WrapNewBindingObjectHelper<T, false>
-{
-  static inline bool Wrap(JSContext* cx, JS::Handle<JSObject*> scope, T& value,
-                          JS::MutableHandle<JS::Value> rval)
-  {
-    return WrapNewBindingObject(cx, scope, &value, rval);
-  }
-};
-
-template<class T>
-inline bool
-WrapNewBindingObject(JSContext* cx, JS::Handle<JSObject*> scope, T& value,
-                     JS::MutableHandle<JS::Value> rval)
-{
-  return WrapNewBindingObjectHelper<T>::Wrap(cx, scope, value, rval);
-}
-
-template <class T>
-inline JSObject*
-GetCallbackFromCallbackObject(T* aObj)
-{
-  return aObj->Callback();
-}
-
-// Helper for getting the callback JSObject* of a smart ptr around a
-// CallbackObject or a reference to a CallbackObject or something like
-// that.
-template <class T, bool isSmartPtr=HasgetMember<T>::Value>
-struct GetCallbackFromCallbackObjectHelper
-{
-  static inline JSObject* Get(const T& aObj)
-  {
-    return GetCallbackFromCallbackObject(aObj.get());
-  }
-};
-
-template <class T>
-struct GetCallbackFromCallbackObjectHelper<T, false>
-{
-  static inline JSObject* Get(T& aObj)
-  {
-    return GetCallbackFromCallbackObject(&aObj);
-  }
-};
-
-template<class T>
-inline JSObject*
-GetCallbackFromCallbackObject(T& aObj)
-{
-  return GetCallbackFromCallbackObjectHelper<T>::Get(aObj);
-}
-
-static inline bool
-InternJSString(JSContext* cx, jsid& id, const char* chars)
-{
-  if (JSString *str = ::JS_InternString(cx, chars)) {
-    id = INTERNED_STRING_TO_JSID(cx, str);
-    return true;
-  }
-  return false;
-}
-
-// Spec needs a name property
-template <typename Spec>
-static bool
-InitIds(JSContext* cx, const Prefable<Spec>* prefableSpecs, jsid* ids)
-{
-  MOZ_ASSERT(prefableSpecs);
-  MOZ_ASSERT(prefableSpecs->specs);
-  do {
-    // We ignore whether the set of ids is enabled and just intern all the IDs,
-    // because this is only done once per application runtime.
-    Spec* spec = prefableSpecs->specs;
-    do {
-      if (!InternJSString(cx, *ids, spec->name)) {
-        return false;
-      }
-    } while (++ids, (++spec)->name);
-
-    // We ran out of ids for that pref.  Put a JSID_VOID in on the id
-    // corresponding to the list terminator for the pref.
-    *ids = JSID_VOID;
-    ++ids;
-  } while ((++prefableSpecs)->specs);
-
-  return true;
-}
-
-bool
-QueryInterface(JSContext* cx, unsigned argc, JS::Value* vp);
-
-template <class T, bool isISupports=IsBaseOf<nsISupports, T>::value>
-struct
-WantsQueryInterface
-{
-  static bool Enabled(JSContext* aCx, JSObject* aGlobal)
-  {
-    return false;
-  }
-};
-template <class T>
-struct
-WantsQueryInterface<T, true>
-{
-  static bool Enabled(JSContext* aCx, JSObject* aGlobal)
-  {
-    return IsChromeOrXBL(aCx, aGlobal);
-  }
-};
-
-bool
-ThrowingConstructor(JSContext* cx, unsigned argc, JS::Value* vp);
-
-// vp is allowed to be null; in that case no get will be attempted,
-// and *found will simply indicate whether the property exists.
-bool
-GetPropertyOnPrototype(JSContext* cx, JS::Handle<JSObject*> proxy,
-                       JS::Handle<jsid> id, bool* found,
-                       JS::Value* vp);
-
-bool
-HasPropertyOnPrototype(JSContext* cx, JS::Handle<JSObject*> proxy,
-                       JS::Handle<jsid> id);
-
-
-// Append the property names in "names" to "props". If
-// shadowPrototypeProperties is false then skip properties that are also
-// present on the proto chain of proxy.  If shadowPrototypeProperties is true,
-// then the "proxy" argument is ignored.
-bool
-AppendNamedPropertyIds(JSContext* cx, JS::Handle<JSObject*> proxy,
-                       nsTArray<nsString>& names,
-                       bool shadowPrototypeProperties, JS::AutoIdVector& props);
-
 template<class T>
 class OwningNonNull
 {
 public:
   OwningNonNull()
 #ifdef DEBUG
-    : inited(false)
+    : mInited(false)
 #endif
   {}
 
-  operator T&() {
-    MOZ_ASSERT(inited);
-    MOZ_ASSERT(ptr, "OwningNonNull<T> was set to null");
-    return *ptr;
+  operator T&()
+  {
+    MOZ_ASSERT(mInited);
+    MOZ_ASSERT(mPtr, "OwningNonNull<T> was set to null");
+    return *mPtr;
   }
 
-  void operator=(T* t) {
-    init(t);
+  void operator=(T* aValue)
+  {
+    init(aValue);
   }
 
-  void operator=(const already_AddRefed<T>& t) {
-    init(t);
+  void operator=(const already_AddRefed<T>& aValue)
+  {
+    init(aValue);
   }
 
-  already_AddRefed<T> forget() {
+  already_AddRefed<T> forget()
+  {
 #ifdef DEBUG
-    inited = false;
+    mInited = false;
 #endif
-    return ptr.forget();
+    return mPtr.forget();
   }
 
-  // Make us work with smart-ptr helpers that expect a get()
-  T* get() const {
-    MOZ_ASSERT(inited);
-    MOZ_ASSERT(ptr);
-    return ptr;
+  // Make us work with smart pointer helpers that expect a get().
+  T* get() const
+  {
+    MOZ_ASSERT(mInited);
+    MOZ_ASSERT(mPtr);
+    return mPtr;
   }
 
 protected:
   template<typename U>
-  void init(U t) {
-    ptr = t;
-    MOZ_ASSERT(ptr);
+  void init(U aValue)
+  {
+    mPtr = aValue;
+    MOZ_ASSERT(mPtr);
 #ifdef DEBUG
-    inited = true;
+    mInited = true;
 #endif
   }
 
-  nsRefPtr<T> ptr;
+  nsRefPtr<T> mPtr;
 #ifdef DEBUG
-  bool inited;
+  bool mInited;
 #endif
 };
 
-// A struct that has the same layout as an nsDependentString but much
-// faster constructor and destructor behavior
-struct FakeDependentString {
-  FakeDependentString() :
-    mFlags(nsDependentString::F_TERMINATED)
-  {
-  }
-
-  void SetData(const nsDependentString::char_type* aData,
-               nsDependentString::size_type aLength) {
-    MOZ_ASSERT(mFlags == nsDependentString::F_TERMINATED);
-    mData = aData;
-    mLength = aLength;
-  }
-
-  void Truncate() {
-    mData = nsDependentString::char_traits::sEmptyBuffer;
-    mLength = 0;
-  }
-
-  void SetNull() {
-    Truncate();
-    mFlags |= nsDependentString::F_VOIDED;
-  }
-
-  const nsDependentString::char_type* Data() const
-  {
-    return mData;
-  }
-
-  nsDependentString::size_type Length() const
-  {
-    return mLength;
-  }
-
-  // If this ever changes, change the corresponding code in the
-  // Optional<nsAString> specialization as well.
-  const nsAString* ToAStringPtr() const {
-    return reinterpret_cast<const nsDependentString*>(this);
-  }
-
-  nsAString* ToAStringPtr() {
-    return reinterpret_cast<nsDependentString*>(this);
-  }
-
-  operator const nsAString& () const {
-    return *reinterpret_cast<const nsDependentString*>(this);
-  }
-
-private:
-  const nsDependentString::char_type* mData;
-  nsDependentString::size_type mLength;
-  uint32_t mFlags;
-
-  // A class to use for our static asserts to ensure our object layout
-  // matches that of nsDependentString.
-  class DependentStringAsserter;
-  friend class DependentStringAsserter;
-
-  class DepedentStringAsserter : public nsDependentString {
-  public:
-    static void StaticAsserts() {
-      static_assert(sizeof(FakeDependentString) == sizeof(nsDependentString),
-                    "Must have right object size");
-      static_assert(offsetof(FakeDependentString, mData) ==
-                      offsetof(DepedentStringAsserter, mData),
-                    "Offset of mData should match");
-      static_assert(offsetof(FakeDependentString, mLength) ==
-                      offsetof(DepedentStringAsserter, mLength),
-                    "Offset of mLength should match");
-      static_assert(offsetof(FakeDependentString, mFlags) ==
-                      offsetof(DepedentStringAsserter, mFlags),
-                    "Offset of mFlags should match");
-    }
-  };
-};
-
-enum StringificationBehavior {
-  eStringify,
-  eEmpty,
-  eNull
-};
-
-// pval must not be null and must point to a rooted JS::Value
-static inline bool
-ConvertJSValueToString(JSContext* cx, JS::Handle<JS::Value> v,
-                       JS::MutableHandle<JS::Value> pval,
-                       StringificationBehavior nullBehavior,
-                       StringificationBehavior undefinedBehavior,
-                       FakeDependentString& result)
-{
-  JSString *s;
-  if (v.isString()) {
-    s = v.toString();
-  } else {
-    StringificationBehavior behavior;
-    if (v.isNull()) {
-      behavior = nullBehavior;
-    } else if (v.isUndefined()) {
-      behavior = undefinedBehavior;
-    } else {
-      behavior = eStringify;
-    }
-
-    if (behavior != eStringify) {
-      if (behavior == eEmpty) {
-        result.Truncate();
-      } else {
-        result.SetNull();
-      }
-      return true;
-    }
-
-    s = JS_ValueToString(cx, v);
-    if (!s) {
-      return false;
-    }
-    pval.set(JS::StringValue(s));  // Root the new string.
-  }
-
-  size_t len;
-  const jschar *chars = JS_GetStringCharsZAndLength(cx, s, &len);
-  if (!chars) {
-    return false;
-  }
-
-  result.SetData(chars, len);
-  return true;
-}
-
-bool
-ConvertJSValueToByteString(JSContext* cx, JS::Handle<JS::Value> v,
-                           JS::MutableHandle<JS::Value> pval, bool nullable,
-                           nsACString& result);
-
-// Class for holding the type of members of a union. The union type has an enum
-// to keep track of which of its UnionMembers has been constructed.
-template<class T>
-class UnionMember {
-    AlignedStorage2<T> storage;
-
-public:
-    T& SetValue() {
-      new (storage.addr()) T();
-      return *storage.addr();
-    }
-    template <typename T1>
-    T& SetValue(const T1 &t1)
-    {
-      new (storage.addr()) T(t1);
-      return *storage.addr();
-    }
-    template <typename T1, typename T2>
-    T& SetValue(const T1 &t1, const T2 &t2)
-    {
-      new (storage.addr()) T(t1, t2);
-      return *storage.addr();
-    }
-    T& Value() {
-      return *storage.addr();
-    }
-    const T& Value() const {
-      return *storage.addr();
-    }
-    void Destroy() {
-      storage.addr()->~T();
-    }
-};
-
-template<typename T>
-void DoTraceSequence(JSTracer* trc, FallibleTArray<T>& seq);
-template<typename T>
-void DoTraceSequence(JSTracer* trc, InfallibleTArray<T>& seq);
-
-// Class for simple sequence arguments, only used internally by codegen.
-template<typename T>
-class AutoSequence : public AutoFallibleTArray<T, 16>
-{
-public:
-  AutoSequence() : AutoFallibleTArray<T, 16>()
-  {}
-
-  // Allow converting to const sequences as needed
-  operator const Sequence<T>&() const {
-    return *reinterpret_cast<const Sequence<T>*>(this);
-  }
-};
-
-// Class used to trace sequences, with specializations for various
-// sequence types.
-template<typename T,
-         bool isDictionary=IsBaseOf<DictionaryBase, T>::value,
-         bool isTypedArray=IsBaseOf<AllTypedArraysBase, T>::value>
-class SequenceTracer
-{
-  explicit SequenceTracer() MOZ_DELETE; // Should never be instantiated
-};
-
-// sequence<object> or sequence<object?>
-template<>
-class SequenceTracer<JSObject*, false, false>
-{
-  explicit SequenceTracer() MOZ_DELETE; // Should never be instantiated
-
-public:
-  static void TraceSequence(JSTracer* trc, JSObject** objp, JSObject** end) {
-    for (; objp != end; ++objp) {
-      JS_CallObjectTracer(trc, objp, "sequence<object>");
-    }
-  }
-};
-
-// sequence<any>
-template<>
-class SequenceTracer<JS::Value, false, false>
-{
-  explicit SequenceTracer() MOZ_DELETE; // Should never be instantiated
-
-public:
-  static void TraceSequence(JSTracer* trc, JS::Value* valp, JS::Value* end) {
-    for (; valp != end; ++valp) {
-      JS_CallValueTracer(trc, valp, "sequence<any>");
-    }
-  }
-};
-
-// sequence<sequence<T>>
-template<typename T>
-class SequenceTracer<Sequence<T>, false, false>
-{
-  explicit SequenceTracer() MOZ_DELETE; // Should never be instantiated
-
-public:
-  static void TraceSequence(JSTracer* trc, Sequence<T>* seqp, Sequence<T>* end) {
-    for (; seqp != end; ++seqp) {
-      DoTraceSequence(trc, *seqp);
-    }
-  }
-};
-
-// sequence<sequence<T>> as return value
-template<typename T>
-class SequenceTracer<nsTArray<T>, false, false>
-{
-  explicit SequenceTracer() MOZ_DELETE; // Should never be instantiated
-
-public:
-  static void TraceSequence(JSTracer* trc, nsTArray<T>* seqp, nsTArray<T>* end) {
-    for (; seqp != end; ++seqp) {
-      DoTraceSequence(trc, *seqp);
-    }
-  }
-};
-
-// sequence<someDictionary>
-template<typename T>
-class SequenceTracer<T, true, false>
-{
-  explicit SequenceTracer() MOZ_DELETE; // Should never be instantiated
-
-public:
-  static void TraceSequence(JSTracer* trc, T* dictp, T* end) {
-    for (; dictp != end; ++dictp) {
-      dictp->TraceDictionary(trc);
-    }
-  }
-};
-
-// sequence<SomeTypedArray>
-template<typename T>
-class SequenceTracer<T, false, true>
-{
-  explicit SequenceTracer() MOZ_DELETE; // Should never be instantiated
-
-public:
-  static void TraceSequence(JSTracer* trc, T* arrayp, T* end) {
-    for (; arrayp != end; ++arrayp) {
-      arrayp->TraceSelf(trc);
-    }
-  }
-};
-
-// sequence<T?> with T? being a Nullable<T>
-template<typename T>
-class SequenceTracer<Nullable<T>, false, false>
-{
-  explicit SequenceTracer() MOZ_DELETE; // Should never be instantiated
-
-public:
-  static void TraceSequence(JSTracer* trc, Nullable<T>* seqp,
-                            Nullable<T>* end) {
-    for (; seqp != end; ++seqp) {
-      if (!seqp->IsNull()) {
-        // Pretend like we actually have a length-one sequence here so
-        // we can do template instantiation correctly for T.
-        T& val = seqp->Value();
-        T* ptr = &val;
-        SequenceTracer<T>::TraceSequence(trc, ptr, ptr+1);
-      }
-    }
-  }
-};
-
-template<typename T>
-void DoTraceSequence(JSTracer* trc, FallibleTArray<T>& seq)
-{
-  SequenceTracer<T>::TraceSequence(trc, seq.Elements(),
-                                   seq.Elements() + seq.Length());
-}
-
-template<typename T>
-void DoTraceSequence(JSTracer* trc, InfallibleTArray<T>& seq)
-{
-  SequenceTracer<T>::TraceSequence(trc, seq.Elements(),
-                                   seq.Elements() + seq.Length());
-}
-
-// Rooter class for sequences; this is what we mostly use in the codegen
-template<typename T>
-class MOZ_STACK_CLASS SequenceRooter : private JS::CustomAutoRooter
-{
-public:
-  SequenceRooter(JSContext *aCx, FallibleTArray<T>* aSequence
-                 MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
-    : JS::CustomAutoRooter(aCx MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT),
-      mFallibleArray(aSequence),
-      mSequenceType(eFallibleArray)
-  {
-  }
-
-  SequenceRooter(JSContext *aCx, InfallibleTArray<T>* aSequence
-                 MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
-    : JS::CustomAutoRooter(aCx MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT),
-      mInfallibleArray(aSequence),
-      mSequenceType(eInfallibleArray)
-  {
-  }
-
-  SequenceRooter(JSContext *aCx, Nullable<nsTArray<T> >* aSequence
-                 MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
-    : JS::CustomAutoRooter(aCx MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT),
-      mNullableArray(aSequence),
-      mSequenceType(eNullableArray)
-  {
-  }
-
- private:
-  enum SequenceType {
-    eInfallibleArray,
-    eFallibleArray,
-    eNullableArray
-  };
-
-  virtual void trace(JSTracer *trc) MOZ_OVERRIDE
-  {
-    if (mSequenceType == eFallibleArray) {
-      DoTraceSequence(trc, *mFallibleArray);
-    } else if (mSequenceType == eInfallibleArray) {
-      DoTraceSequence(trc, *mInfallibleArray);
-    } else {
-      MOZ_ASSERT(mSequenceType == eNullableArray);
-      if (!mNullableArray->IsNull()) {
-        DoTraceSequence(trc, mNullableArray->Value());
-      }
-    }
-  }
-
-  union {
-    InfallibleTArray<T>* mInfallibleArray;
-    FallibleTArray<T>* mFallibleArray;
-    Nullable<nsTArray<T> >* mNullableArray;
-  };
-
-  SequenceType mSequenceType;
-};
-
-template<typename T>
-class MOZ_STACK_CLASS RootedDictionary : public T,
-                                         private JS::CustomAutoRooter
-{
-public:
-  RootedDictionary(JSContext* cx MOZ_GUARD_OBJECT_NOTIFIER_PARAM) :
-    T(),
-    JS::CustomAutoRooter(cx MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT)
-  {
-  }
-
-  virtual void trace(JSTracer *trc) MOZ_OVERRIDE
-  {
-    this->TraceDictionary(trc);
-  }
-};
-
-template<typename T>
-class MOZ_STACK_CLASS NullableRootedDictionary : public Nullable<T>,
-                                                 private JS::CustomAutoRooter
-{
-public:
-  NullableRootedDictionary(JSContext* cx MOZ_GUARD_OBJECT_NOTIFIER_PARAM) :
-    Nullable<T>(),
-    JS::CustomAutoRooter(cx MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT)
-  {
-  }
-
-  virtual void trace(JSTracer *trc) MOZ_OVERRIDE
-  {
-    if (!this->IsNull()) {
-      this->Value().TraceDictionary(trc);
-    }
-  }
-};
-
-inline bool
-IdEquals(jsid id, const char* string)
-{
-  return JSID_IS_STRING(id) &&
-         JS_FlatStringEqualsAscii(JSID_TO_FLAT_STRING(id), string);
-}
-
-inline bool
-AddStringToIDVector(JSContext* cx, JS::AutoIdVector& vector, const char* name)
-{
-  return vector.growBy(1) &&
-         InternJSString(cx, vector[vector.length() - 1], name);
-}
-
-// Implementation of the bits that XrayWrapper needs
-
-/**
- * This resolves indexed or named properties of obj.
- *
- * wrapper is the Xray JS object.
- * obj is the target object of the Xray, a binding's instance object or a
- *     interface or interface prototype object.
- */
-bool
-XrayResolveOwnProperty(JSContext* cx, JS::Handle<JSObject*> wrapper,
-                       JS::Handle<JSObject*> obj,
-                       JS::Handle<jsid> id,
-                       JS::MutableHandle<JSPropertyDescriptor> desc, unsigned flags);
-
-/**
- * This resolves operations, attributes and constants of the interfaces for obj.
- *
- * wrapper is the Xray JS object.
- * obj is the target object of the Xray, a binding's instance object or a
- *     interface or interface prototype object.
- */
-bool
-XrayResolveNativeProperty(JSContext* cx, JS::Handle<JSObject*> wrapper,
-                          JS::Handle<JSObject*> obj,
-                          JS::Handle<jsid> id, JS::MutableHandle<JSPropertyDescriptor> desc);
-
-/**
- * Define a property on obj through an Xray wrapper.
- *
- * wrapper is the Xray JS object.
- * obj is the target object of the Xray, a binding's instance object or a
- *     interface or interface prototype object.
- * defined will be set to true if a property was set as a result of this call.
- */
-bool
-XrayDefineProperty(JSContext* cx, JS::Handle<JSObject*> wrapper,
-                   JS::Handle<JSObject*> obj, JS::Handle<jsid> id,
-                   JS::MutableHandle<JSPropertyDescriptor> desc, bool* defined);
-
-/**
- * This enumerates indexed or named properties of obj and operations, attributes
- * and constants of the interfaces for obj.
- *
- * wrapper is the Xray JS object.
- * obj is the target object of the Xray, a binding's instance object or a
- *     interface or interface prototype object.
- * flags are JSITER_* flags.
- */
-bool
-XrayEnumerateProperties(JSContext* cx, JS::Handle<JSObject*> wrapper,
-                        JS::Handle<JSObject*> obj,
-                        unsigned flags, JS::AutoIdVector& props);
-
-extern NativePropertyHooks sWorkerNativePropertyHooks;
-
-// We use one constructor JSNative to represent all DOM interface objects (so
-// we can easily detect when we need to wrap them in an Xray wrapper). We store
-// the real JSNative in the mNative member of a JSNativeHolder in the
-// CONSTRUCTOR_NATIVE_HOLDER_RESERVED_SLOT slot of the JSFunction object for a
-// specific interface object. We also store the NativeProperties in the
-// JSNativeHolder. The CONSTRUCTOR_XRAY_EXPANDO_SLOT is used to store the
-// expando chain of the Xray for the interface object.
-// Note that some interface objects are not yet a JSFunction but a normal
-// JSObject with a DOMJSClass, those do not use these slots.
-
-enum {
-  CONSTRUCTOR_NATIVE_HOLDER_RESERVED_SLOT = 0,
-  CONSTRUCTOR_XRAY_EXPANDO_SLOT
-};
-
-bool
-Constructor(JSContext* cx, unsigned argc, JS::Value* vp);
-
-inline bool
-UseDOMXray(JSObject* obj)
-{
-  const js::Class* clasp = js::GetObjectClass(obj);
-  return IsDOMClass(clasp) ||
-         IsDOMProxy(obj, clasp) ||
-         JS_IsNativeFunction(obj, Constructor) ||
-         IsDOMIfaceAndProtoClass(clasp);
-}
-
-#ifdef DEBUG
-inline bool
-HasConstructor(JSObject* obj)
-{
-  return JS_IsNativeFunction(obj, Constructor) ||
-         js::GetObjectClass(obj)->construct;
-}
- #endif
- 
-// Transfer reference in ptr to smartPtr.
-template<class T>
-inline void
-Take(nsRefPtr<T>& smartPtr, T* ptr)
-{
-  smartPtr = dont_AddRef(ptr);
-}
-
-// Transfer ownership of ptr to smartPtr.
-template<class T>
-inline void
-Take(nsAutoPtr<T>& smartPtr, T* ptr)
-{
-  smartPtr = ptr;
-}
-
-inline void
-MustInheritFromNonRefcountedDOMObject(NonRefcountedDOMObject*)
-{
-}
-
-// Set the chain of expando objects for various consumers of the given object.
-// For Paris Bindings only. See the relevant infrastructure in XrayWrapper.cpp.
-JSObject* GetXrayExpandoChain(JSObject *obj);
-void SetXrayExpandoChain(JSObject *obj, JSObject *chain);
-
-/**
- * This creates a JSString containing the value that the toString function for
- * obj should create according to the WebIDL specification, ignoring any
- * modifications by script. The value is prefixed with pre and postfixed with
- * post, unless this is called for an object that has a stringifier. It is
- * specifically for use by Xray code.
- *
- * wrapper is the Xray JS object.
- * obj is the target object of the Xray, a binding's instance object or a
- *     interface or interface prototype object.
- * pre is a string that should be prefixed to the value.
- * post is a string that should be prefixed to the value.
- * v contains the JSString for the value if the function returns true.
- */
-bool
-NativeToString(JSContext* cx, JS::Handle<JSObject*> wrapper,
-               JS::Handle<JSObject*> obj, const char* pre,
-               const char* post, JS::Value* v);
-
-HAS_MEMBER(JSBindingFinalized)
-
-template<class T, bool hasCallback=HasJSBindingFinalizedMember<T>::Value>
-struct JSBindingFinalized
-{
-  static void Finalized(T* self)
-  {
-  }
-};
-
-template<class T>
-struct JSBindingFinalized<T, true>
-{
-  static void Finalized(T* self)
-  {
-    self->JSBindingFinalized();
-  }
-};
-
-// Helpers for creating a const version of a type.
-template<typename T>
-const T& Constify(T& arg)
-{
-  return arg;
-}
-
-// Helper for turning (Owning)NonNull<T> into T&
-template<typename T>
-T& NonNullHelper(T& aArg)
-{
-  return aArg;
-}
-
-template<typename T>
-T& NonNullHelper(NonNull<T>& aArg)
-{
-  return aArg;
-}
-
-template<typename T>
-const T& NonNullHelper(const NonNull<T>& aArg)
-{
-  return aArg;
-}
-
-template<typename T>
-T& NonNullHelper(OwningNonNull<T>& aArg)
-{
-  return aArg;
-}
-
-template<typename T>
-const T& NonNullHelper(const OwningNonNull<T>& aArg)
-{
-  return aArg;
-}
-
-// Reparent the wrapper of aObj to whatever its native now thinks its
-// parent should be.
-nsresult
-ReparentWrapper(JSContext* aCx, JS::HandleObject aObj);
-
-/**
- * Used to implement the hasInstance hook of an interface object.
- *
- * instance should not be a security wrapper.
- */
-bool
-InterfaceHasInstance(JSContext* cx, JS::Handle<JSObject*> obj,
-                     JS::Handle<JSObject*> instance,
-                     bool* bp);
-bool
-InterfaceHasInstance(JSContext* cx, JS::Handle<JSObject*> obj, JS::MutableHandle<JS::Value> vp,
-                     bool* bp);
-bool
-InterfaceHasInstance(JSContext* cx, int prototypeID, int depth,
-                     JS::Handle<JSObject*> instance,
-                     bool* bp);
-
-// Helper for lenient getters/setters to report to console.  If this
-// returns false, we couldn't even get a global.
-bool
-ReportLenientThisUnwrappingFailure(JSContext* cx, JS::Handle<JSObject*> obj);
-
-inline JSObject*
-GetUnforgeableHolder(JSObject* aGlobal, prototypes::ID aId)
-{
-  JS::Heap<JSObject*>* protoAndIfaceArray = GetProtoAndIfaceArray(aGlobal);
-  JSObject* interfaceProto = protoAndIfaceArray[aId];
-  return &js::GetReservedSlot(interfaceProto,
-                              DOM_INTERFACE_PROTO_SLOTS_BASE).toObject();
-}
-
-// Given a JSObject* that represents the chrome side of a JS-implemented WebIDL
-// interface, get the nsPIDOMWindow corresponding to the content side, if any.
-// A false return means an exception was thrown.
-bool
-GetWindowForJSImplementedObject(JSContext* cx, JS::Handle<JSObject*> obj,
-                                nsPIDOMWindow** window);
-
-already_AddRefed<nsPIDOMWindow>
-ConstructJSImplementation(JSContext* aCx, const char* aContractId,
-                          const GlobalObject& aGlobal,
-                          JS::MutableHandle<JSObject*> aObject,
-                          ErrorResult& aRv);
-
-/**
- * Convert an nsCString to jsval, returning true on success.
- * These functions are intended for ByteString implementations.
- * As such, the string is not UTF-8 encoded.  Any UTF8 strings passed to these
- * methods will be mangled.
- */
-bool NonVoidByteStringToJsval(JSContext *cx, const nsACString &str,
-                              JS::MutableHandle<JS::Value> rval);
-inline bool ByteStringToJsval(JSContext *cx, const nsACString &str,
-                              JS::MutableHandle<JS::Value> rval)
-{
-    if (str.IsVoid()) {
-        rval.setNull();
-        return true;
-    }
-    return NonVoidByteStringToJsval(cx, str, rval);
-}
-
-template<class T, bool isISupports=IsBaseOf<nsISupports, T>::value>
-struct PreserveWrapperHelper
-{
-  static void PreserveWrapper(T* aObject)
-  {
-    aObject->PreserveWrapper(aObject, NS_CYCLE_COLLECTION_PARTICIPANT(T));
-  }
-};
-
-template<class T>
-struct PreserveWrapperHelper<T, true>
-{
-  static void PreserveWrapper(T* aObject)
-  {
-    aObject->PreserveWrapper(reinterpret_cast<nsISupports*>(aObject));
-  }
-};
-
-template<class T>
-void PreserveWrapper(T* aObject)
-{
-  PreserveWrapperHelper<T>::PreserveWrapper(aObject);
-}
-
-template<class T, bool isISupports=IsBaseOf<nsISupports, T>::value>
-struct CastingAssertions
-{
-  static bool ToSupportsIsCorrect(T*)
-  {
-    return true;
-  }
-  static bool ToSupportsIsOnPrimaryInheritanceChain(T*, nsWrapperCache*)
-  {
-    return true;
-  }
-};
-
-template<class T>
-struct CastingAssertions<T, true>
-{
-  static bool ToSupportsIsCorrect(T* aObject)
-  {
-    return ToSupports(aObject) ==  reinterpret_cast<nsISupports*>(aObject);
-  }
-  static bool ToSupportsIsOnPrimaryInheritanceChain(T* aObject,
-                                                    nsWrapperCache* aCache)
-  {
-    return reinterpret_cast<void*>(aObject) != aCache;
-  }
-};
-
-template<class T>
-bool
-ToSupportsIsCorrect(T* aObject)
-{
-  return CastingAssertions<T>::ToSupportsIsCorrect(aObject);
-}
-
-template<class T>
-bool
-ToSupportsIsOnPrimaryInheritanceChain(T* aObject, nsWrapperCache* aCache)
-{
-  return CastingAssertions<T>::ToSupportsIsOnPrimaryInheritanceChain(aObject,
-                                                                     aCache);
-}
-
-template<class T, template <typename> class SmartPtr,
-         bool isISupports=IsBaseOf<nsISupports, T>::value>
-class DeferredFinalizer
-{
-  typedef nsTArray<SmartPtr<T> > SmartPtrArray;
-
-  static void*
-  AppendDeferredFinalizePointer(void* aData, void* aObject)
-  {
-    SmartPtrArray* pointers = static_cast<SmartPtrArray*>(aData);
-    if (!pointers) {
-      pointers = new SmartPtrArray();
-    }
-
-    T* self = static_cast<T*>(aObject);
-
-    SmartPtr<T>* defer = pointers->AppendElement();
-    Take(*defer, self);
-    return pointers;
-  }
-  static bool
-  DeferredFinalize(uint32_t aSlice, void* aData)
-  {
-    MOZ_ASSERT(aSlice > 0, "nonsensical/useless call with aSlice == 0");
-    SmartPtrArray* pointers = static_cast<SmartPtrArray*>(aData);
-    uint32_t oldLen = pointers->Length();
-    aSlice = std::min(oldLen, aSlice);
-    uint32_t newLen = oldLen - aSlice;
-    pointers->RemoveElementsAt(newLen, aSlice);
-    if (newLen == 0) {
-      delete pointers;
-      return true;
-    }
-    return false;
-  }
-
-public:
-  static void
-  AddForDeferredFinalization(T* aObject)
-  {
-    cyclecollector::DeferredFinalize(AppendDeferredFinalizePointer,
-                                     DeferredFinalize, aObject);
-  }
-};
-
-template<class T, template <typename> class SmartPtr>
-class DeferredFinalizer<T, SmartPtr, true>
-{
-public:
-  static void
-  AddForDeferredFinalization(T* aObject)
-  {
-    cyclecollector::DeferredFinalize(reinterpret_cast<nsISupports*>(aObject));
-  }
-};
-
-template<class T, template <typename> class SmartPtr>
-static void
-AddForDeferredFinalization(T* aObject)
-{
-  DeferredFinalizer<T, SmartPtr>::AddForDeferredFinalization(aObject);
-}
-
-// This returns T's CC participant if it participates in CC or null if it
-// doesn't. This also returns null for classes that don't inherit from
-// nsISupports (QI should be used to get the participant for those).
-template<class T, bool isISupports=IsBaseOf<nsISupports, T>::value>
-class GetCCParticipant
-{
-  // Helper for GetCCParticipant for classes that participate in CC.
-  template<class U>
-  static MOZ_CONSTEXPR nsCycleCollectionParticipant*
-  GetHelper(int, typename U::NS_CYCLE_COLLECTION_INNERCLASS* dummy=nullptr)
-  {
-    return T::NS_CYCLE_COLLECTION_INNERCLASS::GetParticipant();
-  }
-  // Helper for GetCCParticipant for classes that don't participate in CC.
-  template<class U>
-  static MOZ_CONSTEXPR nsCycleCollectionParticipant*
-  GetHelper(double)
-  {
-    return nullptr;
-  }
-
-public:
-  static MOZ_CONSTEXPR nsCycleCollectionParticipant*
-  Get()
-  {
-    // Passing int() here will try to call the GetHelper that takes an int as
-    // its firt argument. If T doesn't participate in CC then substitution for
-    // the second argument (with a default value) will fail and because of
-    // SFINAE the next best match (the variant taking a double) will be called.
-    return GetHelper<T>(int());
-  }
-};
-
-template<class T>
-class GetCCParticipant<T, true>
-{
-public:
-  static MOZ_CONSTEXPR nsCycleCollectionParticipant*
-  Get()
-  {
-    return nullptr;
-  }
-};
-
-bool
-ThreadsafeCheckIsChrome(JSContext* aCx, JSObject* aObj);
-
 } // namespace dom
 } // namespace mozilla
 
-#endif /* mozilla_dom_BindingUtils_h__ */
+#endif // mozilla_dom_OwningNonNull_h
new file mode 100644
--- /dev/null
+++ b/dom/bindings/UnionMember.h
@@ -0,0 +1,59 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 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/. */
+
+/* A class for holding the members of a union. */
+
+#ifndef mozilla_dom_UnionMember_h
+#define mozilla_dom_UnionMember_h
+
+#include "mozilla/Alignment.h"
+
+namespace mozilla {
+namespace dom {
+
+// The union type has an enum to keep track of which of its UnionMembers has
+// been constructed.
+template<class T>
+class UnionMember
+{
+  AlignedStorage2<T> mStorage;
+
+public:
+  T& SetValue()
+  {
+    new (mStorage.addr()) T();
+    return *mStorage.addr();
+  }
+  template <typename T1>
+  T& SetValue(const T1& aValue)
+  {
+    new (mStorage.addr()) T(aValue);
+    return *mStorage.addr();
+  }
+  template<typename T1, typename T2>
+  T& SetValue(const T1& aValue1, const T2& aValue2)
+  {
+    new (mStorage.addr()) T(aValue1, aValue2);
+    return *mStorage.addr();
+  }
+  T& Value()
+  {
+    return *mStorage.addr();
+  }
+  const T& Value() const
+  {
+    return *mStorage.addr();
+  }
+  void Destroy()
+  {
+    mStorage.addr()->~T();
+  }
+};
+
+} // namespace dom
+} // namespace mozilla
+
+#endif // mozilla_dom_UnionMember_h
--- a/dom/bindings/moz.build
+++ b/dom/bindings/moz.build
@@ -20,18 +20,20 @@ EXPORTS.mozilla.dom += [
     'DOMJSClass.h',
     'DOMJSProxyHandler.h',
     'Date.h',
     'Errors.msg',
     'Exceptions.h',
     'JSSlots.h',
     'NonRefcountedDOMObject.h',
     'Nullable.h',
+    'OwningNonNull.h',
     'PrimitiveConversions.h',
     'TypedArray.h',
+    'UnionMember.h',
 ]
 
 FAIL_ON_WARNINGS = True
 
 LIBXUL_LIBRARY = True
 
 MSVC_ENABLE_PGO = True
 
--- a/dom/bluetooth/BluetoothHfpManager.cpp
+++ b/dom/bluetooth/BluetoothHfpManager.cpp
@@ -49,18 +49,16 @@
  * ril_consts.js
  */
 #define TOA_UNKNOWN 0x81
 #define TOA_INTERNATIONAL 0x91
 
 #define CR_LF "\xd\xa";
 
 #define MOZSETTINGS_CHANGED_ID               "mozsettings-changed"
-#define MOBILE_CONNECTION_ICCINFO_CHANGED_ID "mobile-connection-iccinfo-changed"
-#define MOBILE_CONNECTION_VOICE_CHANGED_ID   "mobile-connection-voice-changed"
 #define AUDIO_VOLUME_BT_SCO_ID               "audio.volume.bt_sco"
 
 using namespace mozilla;
 using namespace mozilla::ipc;
 USING_BLUETOOTH_NAMESPACE
 
 namespace {
   StaticRefPtr<BluetoothHfpManager> sBluetoothHfpManager;
@@ -198,20 +196,16 @@ NS_IMETHODIMP
 BluetoothHfpManager::Observe(nsISupports* aSubject,
                              const char* aTopic,
                              const PRUnichar* aData)
 {
   if (!strcmp(aTopic, MOZSETTINGS_CHANGED_ID)) {
     HandleVolumeChanged(nsDependentString(aData));
   } else if (!strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID)) {
     HandleShutdown();
-  } else if (!strcmp(aTopic, MOBILE_CONNECTION_ICCINFO_CHANGED_ID)) {
-    HandleIccInfoChanged();
-  } else if (!strcmp(aTopic, MOBILE_CONNECTION_VOICE_CHANGED_ID)) {
-    HandleVoiceConnectionChanged();
   } else {
     MOZ_ASSERT(false, "BluetoothHfpManager got unexpected topic!");
     return NS_ERROR_UNEXPECTED;
   }
 
   return NS_OK;
 }
 
@@ -367,26 +361,24 @@ bool
 BluetoothHfpManager::Init()
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
   NS_ENSURE_TRUE(obs, false);
 
   if (NS_FAILED(obs->AddObserver(this, MOZSETTINGS_CHANGED_ID, false)) ||
-      NS_FAILED(obs->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false)) ||
-      NS_FAILED(obs->AddObserver(this, MOBILE_CONNECTION_ICCINFO_CHANGED_ID, false)) ||
-      NS_FAILED(obs->AddObserver(this, MOBILE_CONNECTION_VOICE_CHANGED_ID, false))) {
+      NS_FAILED(obs->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false))) {
     BT_WARNING("Failed to add observers!");
     return false;
   }
 
   hal::RegisterBatteryObserver(this);
 
-  mListener = new BluetoothTelephonyListener();
+  mListener = new BluetoothRilListener();
   if (!mListener->StartListening()) {
     NS_WARNING("Failed to start listening RIL");
     return false;
   }
 
   nsCOMPtr<nsISettingsService> settings =
     do_GetService("@mozilla.org/settingsService;1");
   NS_ENSURE_TRUE(settings, false);
@@ -416,19 +408,17 @@ BluetoothHfpManager::~BluetoothHfpManage
     NS_WARNING("Failed to stop listening RIL");
   }
   mListener = nullptr;
 
   nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
   NS_ENSURE_TRUE_VOID(obs);
 
   if (NS_FAILED(obs->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID)) ||
-      NS_FAILED(obs->RemoveObserver(this, MOZSETTINGS_CHANGED_ID)) ||
-      NS_FAILED(obs->RemoveObserver(this, MOBILE_CONNECTION_ICCINFO_CHANGED_ID)) ||
-      NS_FAILED(obs->RemoveObserver(this, MOBILE_CONNECTION_VOICE_CHANGED_ID))) {
+      NS_FAILED(obs->RemoveObserver(this, MOZSETTINGS_CHANGED_ID))) {
     BT_WARNING("Failed to remove observers!");
   }
 
   hal::UnregisterBatteryObserver(this);
 }
 
 //static
 BluetoothHfpManager*
@@ -1449,16 +1439,17 @@ BluetoothHfpManager::HandleCallStateChan
       break;
   }
 }
 
 void
 BluetoothHfpManager::OnSocketConnectSuccess(BluetoothSocket* aSocket)
 {
   MOZ_ASSERT(aSocket);
+  MOZ_ASSERT(mListener);
 
   // Success to create a SCO socket
   if (aSocket == mScoSocket) {
     OnScoConnectSuccess();
     return;
   }
 
   /**
@@ -1477,20 +1468,18 @@ BluetoothHfpManager::OnSocketConnectSucc
   } else if (aSocket == mHeadsetSocket) {
     MOZ_ASSERT(!mSocket);
     mHeadsetSocket.swap(mSocket);
 
     mHandsfreeSocket->Disconnect();
     mHandsfreeSocket = nullptr;
   }
 
-  nsCOMPtr<nsITelephonyProvider> provider =
-    do_GetService(TELEPHONY_PROVIDER_CONTRACTID);
-  NS_ENSURE_TRUE_VOID(provider);
-  provider->EnumerateCalls(mListener->GetListener());
+  // Enumerate current calls
+  mListener->EnumerateCalls();
 
   mFirstCKPD = true;
 
   // Cache device path for NotifySettings() since we can't get socket address
   // when a headset disconnect with us
   mSocket->GetAddress(mDeviceAddress);
   NotifyConnectionStatusChanged(NS_LITERAL_STRING(BLUETOOTH_HFP_STATUS_CHANGED_ID));
   DispatchConnectionStatusChanged(NS_LITERAL_STRING(HFP_STATUS_CHANGED_ID));
--- a/dom/bluetooth/BluetoothHfpManager.h
+++ b/dom/bluetooth/BluetoothHfpManager.h
@@ -4,18 +4,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/. */
 
 #ifndef mozilla_dom_bluetooth_bluetoothhfpmanager_h__
 #define mozilla_dom_bluetooth_bluetoothhfpmanager_h__
 
 #include "BluetoothCommon.h"
 #include "BluetoothProfileManagerBase.h"
+#include "BluetoothRilListener.h"
 #include "BluetoothSocketObserver.h"
-#include "BluetoothTelephonyListener.h"
 #include "mozilla/ipc/UnixSocket.h"
 #include "mozilla/Hal.h"
 
 BEGIN_BLUETOOTH_NAMESPACE
 
 class BluetoothReplyRunnable;
 class BluetoothSocket;
 class Call;
@@ -87,16 +87,18 @@ public:
   bool ListenSco();
 
   /**
    * @param aSend A boolean indicates whether we need to notify headset or not
    */
   void HandleCallStateChanged(uint32_t aCallIndex, uint16_t aCallState,
                               const nsAString& aError, const nsAString& aNumber,
                               const bool aIsOutgoing, bool aSend);
+  void HandleIccInfoChanged();
+  void HandleVoiceConnectionChanged();
 
   bool IsConnected();
   bool IsScoConnected();
 
 private:
   class CloseScoTask;
   class GetVolumeTask;
   class RespondToBLDNTask;
@@ -104,20 +106,18 @@ private:
 
   friend class CloseScoTask;
   friend class GetVolumeTask;
   friend class RespondToBLDNTask;
   friend class SendRingIndicatorTask;
   friend class BluetoothHfpManagerObserver;
 
   BluetoothHfpManager();
-  void HandleIccInfoChanged();
   void HandleShutdown();
   void HandleVolumeChanged(const nsAString& aData);
-  void HandleVoiceConnectionChanged();
 
   bool Init();
   void Notify(const hal::BatteryInformation& aBatteryInfo);
   void Reset();
   void ResetCallArray();
   uint32_t FindFirstCall(uint16_t aState);
   uint32_t GetNumberOfCalls(uint16_t aState);
 
@@ -145,17 +145,17 @@ private:
   bool mDialingRequestProcessed;
   bool mIsHandsfree;
   bool mNeedsUpdatingSdpRecords;
   nsString mDeviceAddress;
   nsString mMsisdn;
   nsString mOperatorName;
 
   nsTArray<Call> mCurrentCallArray;
-  nsAutoPtr<BluetoothTelephonyListener> mListener;
+  nsAutoPtr<BluetoothRilListener> mListener;
   nsRefPtr<BluetoothReplyRunnable> mRunnable;
   BluetoothProfileController* mController;
   nsRefPtr<BluetoothReplyRunnable> mScoRunnable;
 
   // If a connection has been established, mSocket will be the socket
   // communicating with the remote socket. We maintain the invariant that if
   // mSocket is non-null, mHandsfreeSocket and mHeadsetSocket must be null (and
   // vice versa).
new file mode 100644
--- /dev/null
+++ b/dom/bluetooth/BluetoothRilListener.cpp
@@ -0,0 +1,336 @@
+/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
+/* vim: set ts=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/. */
+
+#include "BluetoothRilListener.h"
+
+#include "BluetoothHfpManager.h"
+#include "nsIIccProvider.h"
+#include "nsIMobileConnectionProvider.h"
+#include "nsITelephonyProvider.h"
+#include "nsRadioInterfaceLayer.h"
+#include "nsServiceManagerUtils.h"
+#include "nsString.h"
+
+USING_BLUETOOTH_NAMESPACE
+
+namespace {
+
+/**
+ *  IccListener
+ */
+class IccListener : public nsIIccListener
+{
+public:
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSIICCLISTENER
+
+  IccListener() { }
+};
+
+NS_IMPL_ISUPPORTS1(IccListener, nsIIccListener)
+
+NS_IMETHODIMP
+IccListener::NotifyIccInfoChanged()
+{
+  BluetoothHfpManager* hfp = BluetoothHfpManager::Get();
+  hfp->HandleIccInfoChanged();
+
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+IccListener::NotifyStkCommand(const nsAString & aMessage)
+{
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+IccListener::NotifyStkSessionEnd()
+{
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+IccListener::NotifyIccCardLockError(const nsAString & lockType,
+                                    uint32_t retryCount)
+{
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+IccListener::NotifyCardStateChanged()
+{
+  return NS_OK;
+}
+
+/**
+ *  MobileConnectionListener
+ */
+class MobileConnectionListener : public nsIMobileConnectionListener
+{
+public:
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSIMOBILECONNECTIONLISTENER
+
+  MobileConnectionListener() { }
+};
+
+NS_IMPL_ISUPPORTS1(MobileConnectionListener, nsIMobileConnectionListener)
+
+NS_IMETHODIMP
+MobileConnectionListener::NotifyVoiceChanged()
+{
+  BluetoothHfpManager* hfp = BluetoothHfpManager::Get();
+  hfp->HandleVoiceConnectionChanged();
+
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+MobileConnectionListener::NotifyDataChanged()
+{
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+MobileConnectionListener::NotifyUssdReceived(const nsAString & message,
+                                             bool sessionEnded)
+{
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+MobileConnectionListener::NotifyDataError(const nsAString & message)
+{
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+MobileConnectionListener::NotifyCFStateChange(bool success,
+                                              uint16_t action,
+                                              uint16_t reason,
+                                              const nsAString& number,
+                                              uint16_t timeSeconds,
+                                              uint16_t serviceClass)
+{
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+MobileConnectionListener::NotifyEmergencyCbModeChanged(bool active,
+                                                       uint32_t timeoutMs)
+{
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+MobileConnectionListener::NotifyOtaStatusChanged(const nsAString & status)
+{
+  return NS_OK;
+}
+
+/**
+ *  TelephonyListener Implementation
+ */
+class TelephonyListener : public nsITelephonyListener
+{
+public:
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSITELEPHONYLISTENER
+
+  TelephonyListener() { }
+};
+
+NS_IMPL_ISUPPORTS1(TelephonyListener, nsITelephonyListener)
+
+NS_IMETHODIMP
+TelephonyListener::CallStateChanged(uint32_t aCallIndex,
+                                    uint16_t aCallState,
+                                    const nsAString& aNumber,
+                                    bool aIsActive,
+                                    bool aIsOutgoing,
+                                    bool aIsEmergency,
+                                    bool aIsConference)
+{
+  BluetoothHfpManager* hfp = BluetoothHfpManager::Get();
+  hfp->HandleCallStateChanged(aCallIndex, aCallState, EmptyString(), aNumber,
+                              aIsOutgoing, true);
+
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+TelephonyListener::EnumerateCallState(uint32_t aCallIndex,
+                                      uint16_t aCallState,
+                                      const nsAString_internal& aNumber,
+                                      bool aIsActive,
+                                      bool aIsOutgoing,
+                                      bool aIsEmergency,
+                                      bool aIsConference)
+{
+  BluetoothHfpManager* hfp = BluetoothHfpManager::Get();
+  hfp->HandleCallStateChanged(aCallIndex, aCallState, EmptyString(), aNumber,
+                              aIsOutgoing, false);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+TelephonyListener::NotifyError(int32_t aCallIndex,
+                               const nsAString& aError)
+{
+  BluetoothHfpManager* hfp = BluetoothHfpManager::Get();
+
+  if (aCallIndex > 0) {
+    // In order to not miss any related call state transition.
+    // It's possible that 3G network signal lost for unknown reason.
+    // If a call is released abnormally, NotifyError() will be called,
+    // instead of CallStateChanged(). We need to reset the call array state
+    // via setting CALL_STATE_DISCONNECTED
+    hfp->HandleCallStateChanged(aCallIndex,
+                                nsITelephonyProvider::CALL_STATE_DISCONNECTED,
+                                aError, EmptyString(), false, true);
+    NS_WARNING("Reset the call state due to call transition ends abnormally");
+  }
+
+  NS_WARNING(NS_ConvertUTF16toUTF8(aError).get());
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+TelephonyListener::ConferenceCallStateChanged(uint16_t aCallState)
+{
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+TelephonyListener::EnumerateCallStateComplete()
+{
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+TelephonyListener::SupplementaryServiceNotification(int32_t aCallIndex,
+                                                    uint16_t aNotification)
+{
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+TelephonyListener::NotifyCdmaCallWaiting(const nsAString& aNumber)
+{
+  return NS_OK;
+}
+
+} // anonymous namespace
+
+/**
+ *  BluetoothRilListener
+ */
+BluetoothRilListener::BluetoothRilListener()
+{
+  mIccListener = new IccListener();
+  mMobileConnectionListener = new MobileConnectionListener();
+  mTelephonyListener = new TelephonyListener();
+}
+
+bool
+BluetoothRilListener::StartListening()
+{
+  NS_ENSURE_TRUE(StartIccListening(), false);
+  NS_ENSURE_TRUE(StartMobileConnectionListening(), false);
+  NS_ENSURE_TRUE(StartTelephonyListening(), false);
+
+  return true;
+}
+
+bool
+BluetoothRilListener::StopListening()
+{
+  NS_ENSURE_TRUE(StopIccListening(), false);
+  NS_ENSURE_TRUE(StopMobileConnectionListening(), false);
+  NS_ENSURE_TRUE(StopTelephonyListening(), false);
+
+  return true;
+}
+
+void
+BluetoothRilListener::EnumerateCalls()
+{
+  nsCOMPtr<nsITelephonyProvider> provider =
+    do_GetService(TELEPHONY_PROVIDER_CONTRACTID);
+  NS_ENSURE_TRUE_VOID(provider);
+
+  provider->EnumerateCalls(mTelephonyListener);
+}
+
+// private
+bool
+BluetoothRilListener::StartIccListening()
+{
+  nsCOMPtr<nsIIccProvider> provider =
+    do_GetService(NS_RILCONTENTHELPER_CONTRACTID);
+  NS_ENSURE_TRUE(provider, false);
+
+  nsresult rv = provider->RegisterIccMsg(mIccListener);
+  return NS_SUCCEEDED(rv);
+}
+
+bool
+BluetoothRilListener::StopIccListening()
+{
+  nsCOMPtr<nsIIccProvider> provider =
+    do_GetService(NS_RILCONTENTHELPER_CONTRACTID);
+  NS_ENSURE_TRUE(provider, false);
+
+  nsresult rv = provider->UnregisterIccMsg(mIccListener);
+  return NS_SUCCEEDED(rv);
+}
+
+bool
+BluetoothRilListener::StartMobileConnectionListening()
+{
+  nsCOMPtr<nsIMobileConnectionProvider> provider =
+    do_GetService(NS_RILCONTENTHELPER_CONTRACTID);
+  NS_ENSURE_TRUE(provider, false);
+
+  nsresult rv = provider->
+                  RegisterMobileConnectionMsg(mMobileConnectionListener);
+  return NS_SUCCEEDED(rv);
+}
+
+bool
+BluetoothRilListener::StopMobileConnectionListening()
+{
+  nsCOMPtr<nsIMobileConnectionProvider> provider =
+    do_GetService(NS_RILCONTENTHELPER_CONTRACTID);
+  NS_ENSURE_TRUE(provider, false);
+
+  nsresult rv = provider->
+                  UnregisterMobileConnectionMsg(mMobileConnectionListener);
+  return NS_SUCCEEDED(rv);
+}
+
+bool
+BluetoothRilListener::StartTelephonyListening()
+{
+  nsCOMPtr<nsITelephonyProvider> provider =
+    do_GetService(TELEPHONY_PROVIDER_CONTRACTID);
+  NS_ENSURE_TRUE(provider, false);
+
+  nsresult rv = provider->RegisterListener(mTelephonyListener);
+  return NS_SUCCEEDED(rv);
+}
+
+bool
+BluetoothRilListener::StopTelephonyListening()
+{
+  nsCOMPtr<nsITelephonyProvider> provider =
+    do_GetService(TELEPHONY_PROVIDER_CONTRACTID);
+  NS_ENSURE_TRUE(provider, false);
+
+  nsresult rv = provider->UnregisterListener(mTelephonyListener);
+  return NS_SUCCEEDED(rv);
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/dom/bluetooth/BluetoothRilListener.h
@@ -0,0 +1,47 @@
+/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
+/* vim: set ts=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/. */
+
+#ifndef mozilla_dom_bluetooth_bluetoothrillistener_h__
+#define mozilla_dom_bluetooth_bluetoothrillistener_h__
+
+#include "BluetoothCommon.h"
+
+#include "nsCOMPtr.h"
+
+class nsIIccListener;
+class nsIMobileConnectionListener;
+class nsITelephonyListener;
+
+BEGIN_BLUETOOTH_NAMESPACE
+
+class BluetoothRilListener
+{
+public:
+  BluetoothRilListener();
+
+  bool StartListening();
+  bool StopListening();
+
+  void EnumerateCalls();
+
+private:
+  bool StartIccListening();
+  bool StopIccListening();
+
+  bool StartMobileConnectionListening();
+  bool StopMobileConnectionListening();
+
+  bool StartTelephonyListening();
+  bool StopTelephonyListening();
+
+  nsCOMPtr<nsIIccListener> mIccListener;
+  nsCOMPtr<nsIMobileConnectionListener> mMobileConnectionListener;
+  nsCOMPtr<nsITelephonyListener> mTelephonyListener;
+};
+
+END_BLUETOOTH_NAMESPACE
+
+#endif
deleted file mode 100644
--- a/dom/bluetooth/BluetoothTelephonyListener.cpp
+++ /dev/null
@@ -1,143 +0,0 @@
-/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
-/* vim: set ts=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/. */
-
-#include "BluetoothTelephonyListener.h"
-
-#include "BluetoothHfpManager.h"
-#include "nsRadioInterfaceLayer.h"
-#include "nsServiceManagerUtils.h"
-#include "nsString.h"
-
-USING_BLUETOOTH_NAMESPACE
-
-namespace {
-
-class TelephonyListener : public nsITelephonyListener
-{
-public:
-  NS_DECL_ISUPPORTS
-  NS_DECL_NSITELEPHONYLISTENER
-
-  TelephonyListener() { }
-};
-
-NS_IMPL_ISUPPORTS1(TelephonyListener, nsITelephonyListener)
-
-NS_IMETHODIMP
-TelephonyListener::CallStateChanged(uint32_t aCallIndex,
-                                    uint16_t aCallState,
-                                    const nsAString& aNumber,
-                                    bool aIsActive,
-                                    bool aIsOutgoing,
-                                    bool aIsEmergency,
-                                    bool aIsConference)
-{
-  BluetoothHfpManager* hfp = BluetoothHfpManager::Get();
-  hfp->HandleCallStateChanged(aCallIndex, aCallState, EmptyString(), aNumber,
-                              aIsOutgoing, true);
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-TelephonyListener::ConferenceCallStateChanged(uint16_t aCallState)
-{
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-TelephonyListener::EnumerateCallStateComplete()
-{
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-TelephonyListener::EnumerateCallState(uint32_t aCallIndex,
-                                      uint16_t aCallState,
-                                      const nsAString_internal& aNumber,
-                                      bool aIsActive,
-                                      bool aIsOutgoing,
-                                      bool aIsEmergency,
-                                      bool aIsConference)
-{
-  BluetoothHfpManager* hfp = BluetoothHfpManager::Get();
-  hfp->HandleCallStateChanged(aCallIndex, aCallState, EmptyString(), aNumber,
-                              aIsOutgoing, false);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-TelephonyListener::SupplementaryServiceNotification(int32_t aCallIndex,
-                                                    uint16_t aNotification)
-{
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-TelephonyListener::NotifyError(int32_t aCallIndex,
-                               const nsAString& aError)
-{
-  BluetoothHfpManager* hfp = BluetoothHfpManager::Get();
-
-  if (aCallIndex > 0) {
-    // In order to not miss any related call state transition.
-    // It's possible that 3G network signal lost for unknown reason.
-    // If a call is released abnormally, NotifyError() will be called,
-    // instead of CallStateChanged(). We need to reset the call array state
-    // via setting CALL_STATE_DISCONNECTED
-    hfp->HandleCallStateChanged(aCallIndex,
-                                nsITelephonyProvider::CALL_STATE_DISCONNECTED,
-                                aError, EmptyString(), false, true);
-    NS_WARNING("Reset the call state due to call transition ends abnormally");
-  }
-
-  NS_WARNING(NS_ConvertUTF16toUTF8(aError).get());
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-TelephonyListener::NotifyCdmaCallWaiting(const nsAString& aNumber)
-{
-  return NS_OK;
-}
-
-} // anonymous namespace
-
-BluetoothTelephonyListener::BluetoothTelephonyListener()
-{
-  mTelephonyListener = new TelephonyListener();
-}
-
-bool
-BluetoothTelephonyListener::StartListening()
-{
-  nsCOMPtr<nsITelephonyProvider> provider =
-    do_GetService(TELEPHONY_PROVIDER_CONTRACTID);
-  NS_ENSURE_TRUE(provider, false);
-
-  nsresult rv = provider->RegisterListener(mTelephonyListener);
-  NS_ENSURE_SUCCESS(rv, false);
-
-  return true;
-}
-
-bool
-BluetoothTelephonyListener::StopListening()
-{
-  nsCOMPtr<nsITelephonyProvider> provider =
-    do_GetService(TELEPHONY_PROVIDER_CONTRACTID);
-  NS_ENSURE_TRUE(provider, false);
-
-  nsresult rv = provider->UnregisterListener(mTelephonyListener);
-
-  return NS_FAILED(rv) ? false : true;
-}
-
-nsITelephonyListener*
-BluetoothTelephonyListener::GetListener()
-{
-  return mTelephonyListener;
-}
deleted file mode 100644
--- a/dom/bluetooth/BluetoothTelephonyListener.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
-/* vim: set ts=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/. */
-
-#ifndef mozilla_dom_bluetooth_bluetoothtelephonylistener_h__
-#define mozilla_dom_bluetooth_bluetoothtelephonylistener_h__
-
-#include "BluetoothCommon.h"
-
-#include "nsCOMPtr.h"
-#include "nsITelephonyProvider.h"
-
-BEGIN_BLUETOOTH_NAMESPACE
-
-class BluetoothTelephonyListener
-{
-public:
-  BluetoothTelephonyListener();
-
-  bool StartListening();
-  bool StopListening();
-
-  nsITelephonyListener* GetListener();
-
-private:
-  nsCOMPtr<nsITelephonyListener> mTelephonyListener;
-};
-
-END_BLUETOOTH_NAMESPACE
-
-#endif
--- a/dom/bluetooth/linux/BluetoothDBusService.cpp
+++ b/dom/bluetooth/linux/BluetoothDBusService.cpp
@@ -3074,16 +3074,26 @@ BluetoothDBusService::SendMetaData(const
 
   const char* title = tempTitle.get();
   const char* album = tempAlbum.get();
   const char* artist = tempArtist.get();
   const char* mediaNumber = tempMediaNumber.get();
   const char* totalMediaCount = tempTotalMediaCount.get();
   const char* duration = tempDuration.get();
 
+  nsAutoString prevTitle, prevAlbum;
+  a2dp->GetTitle(prevTitle);
+  a2dp->GetAlbum(prevAlbum);
+
+  if (aMediaNumber != a2dp->GetMediaNumber() ||
+      !aTitle.Equals(prevTitle) ||
+      !aAlbum.Equals(prevAlbum)) {
+    UpdateNotification(ControlEventId::EVENT_TRACK_CHANGED, aMediaNumber);
+  }
+
   nsRefPtr<BluetoothReplyRunnable> runnable(aRunnable);
 
   bool ret = dbus_func_args_async(mConnection,
                                   -1,
                                   GetVoidCallback,
                                   (void*)runnable.get(),
                                   NS_ConvertUTF16toUTF8(objectPath).get(),
                                   DBUS_CTL_IFACE,
@@ -3094,26 +3104,16 @@ BluetoothDBusService::SendMetaData(const
                                   DBUS_TYPE_STRING, &mediaNumber,
                                   DBUS_TYPE_STRING, &totalMediaCount,
                                   DBUS_TYPE_STRING, &duration,
                                   DBUS_TYPE_INVALID);
   NS_ENSURE_TRUE_VOID(ret);
 
   runnable.forget();
 
-  nsAutoString prevTitle, prevAlbum;
-  a2dp->GetTitle(prevTitle);
-  a2dp->GetAlbum(prevAlbum);
-
-  if (aMediaNumber != a2dp->GetMediaNumber() ||
-      !aTitle.Equals(prevTitle) ||
-      !aAlbum.Equals(prevAlbum)) {
-    UpdateNotification(ControlEventId::EVENT_TRACK_CHANGED, aMediaNumber);
-  }
-
   a2dp->UpdateMetaData(aTitle, aArtist, aAlbum,
                        aMediaNumber, aTotalMediaCount, aDuration);
 }
 
 static ControlPlayStatus
 PlayStatusStringToControlPlayStatus(const nsAString& aPlayStatus)
 {
   ControlPlayStatus playStatus = ControlPlayStatus::PLAYSTATUS_UNKNOWN;
@@ -3172,53 +3172,46 @@ BluetoothDBusService::SendPlayStatus(int
                            NS_LITERAL_STRING(ERR_A2DP_IS_DISCONNECTED));
     return;
   } else if (!a2dp->IsAvrcpConnected()) {
     DispatchBluetoothReply(aRunnable, BluetoothValue(),
                            NS_LITERAL_STRING(ERR_AVRCP_IS_DISCONNECTED));
     return;
   }
 
+  uint32_t tempPlayStatus = playStatus;
+  if (playStatus != a2dp->GetPlayStatus()) {
+    UpdateNotification(ControlEventId::EVENT_PLAYBACK_STATUS_CHANGED,
+                       tempPlayStatus);
+  } else if (aPosition != a2dp->GetPosition()) {
+    UpdateNotification(ControlEventId::EVENT_PLAYBACK_POS_CHANGED, aPosition);
+  }
+
   nsAutoString address;
   a2dp->GetAddress(address);
   nsString objectPath =
     GetObjectPathFromAddress(sAdapterPath, address);
 
   nsRefPtr<BluetoothReplyRunnable> runnable(aRunnable);
 
-  uint32_t tempPlayStatus = playStatus;
   bool ret = dbus_func_args_async(mConnection,
                                   -1,
                                   GetVoidCallback,
                                   (void*)runnable.get(),
                                   NS_ConvertUTF16toUTF8(objectPath).get(),
                                   DBUS_CTL_IFACE,
                                   "UpdatePlayStatus",
                                   DBUS_TYPE_UINT32, &aDuration,
                                   DBUS_TYPE_UINT32, &aPosition,
                                   DBUS_TYPE_UINT32, &tempPlayStatus,
                                   DBUS_TYPE_INVALID);
   NS_ENSURE_TRUE_VOID(ret);
 
   runnable.forget();
 
-  ControlEventId eventId = ControlEventId::EVENT_UNKNOWN;
-  uint64_t data;
-  if (aPosition != a2dp->GetPosition()) {
-    eventId = ControlEventId::EVENT_PLAYBACK_POS_CHANGED;
-    data = aPosition;
-  } else if (playStatus != a2dp->GetPlayStatus()) {
-    eventId = ControlEventId::EVENT_PLAYBACK_STATUS_CHANGED;
-    data = tempPlayStatus;
-  }
-
-  if (eventId != ControlEventId::EVENT_UNKNOWN) {
-    UpdateNotification(eventId, data);
-  }
-
   a2dp->UpdatePlayStatus(aDuration, aPosition, playStatus);
 }
 
 static void
 ControlCallback(DBusMessage* aMsg, void* aParam)
 {
   NS_ENSURE_TRUE_VOID(aMsg);
 
--- a/dom/bluetooth/moz.build
+++ b/dom/bluetooth/moz.build
@@ -44,17 +44,17 @@ if CONFIG['MOZ_B2G_BT']:
         'ObexBase.cpp',
         'BluetoothUuid.cpp',
         'BluetoothSocket.cpp',
         'BluetoothProfileController.cpp'
     ]
 
     if CONFIG['MOZ_B2G_RIL']:
         CPP_SOURCES += [
-            'BluetoothTelephonyListener.cpp',
+            'BluetoothRilListener.cpp',
         ]
 
     if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
         CPP_SOURCES += [
             'BluetoothDBusService.cpp',
             'BluetoothGonkService.cpp',
         ]
     else:
--- a/dom/promise/Promise.cpp
+++ b/dom/promise/Promise.cpp
@@ -2,16 +2,17 @@
 /* vim: set ts=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/. */
 
 #include "mozilla/dom/Promise.h"
 
 #include "jsfriendapi.h"
+#include "mozilla/dom/OwningNonNull.h"
 #include "mozilla/dom/PromiseBinding.h"
 #include "mozilla/dom/PromiseResolver.h"
 #include "mozilla/Preferences.h"
 #include "PromiseCallback.h"
 #include "nsContentUtils.h"
 #include "nsPIDOMWindow.h"
 #include "WorkerPrivate.h"
 #include "nsJSPrincipals.h"
--- a/dom/src/notification/Notification.cpp
+++ b/dom/src/notification/Notification.cpp
@@ -1,14 +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/. */
 
 #include "PCOMContentPermissionRequestChild.h"
 #include "mozilla/dom/Notification.h"
+#include "mozilla/dom/OwningNonNull.h"
 #include "mozilla/Preferences.h"
 #include "TabChild.h"
 #include "nsContentUtils.h"
 #include "nsDOMEvent.h"
 #include "nsIAlertsService.h"
 #include "nsIContentPermissionPrompt.h"
 #include "nsIDocument.h"
 #include "nsIPermissionManager.h"
--- a/ipc/chromium/moz.build
+++ b/ipc/chromium/moz.build
@@ -70,17 +70,16 @@ CPP_SOURCES += [
     'path_service.cc',
     'pickle.cc',
     'rand_util.cc',
     'ref_counted.cc',
     'revocable_store.cc',
     'scoped_temp_dir.cc',
     'simple_thread.cc',
     'stats_table.cc',
-    'string_escape.cc',
     'string_piece.cc',
     'string_util.cc',
     'system_monitor.cc',
     'task_queue.cc',
     'thread.cc',
     'thread_collision_warner.cc',
     'time.cc',
     'timer.cc',
deleted file mode 100644
--- a/ipc/chromium/src/base/foundation_utils_mac.h
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (c) 2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef BASE_FOUNDATION_UTILS_MAC_H_
-#define BASE_FOUNDATION_UTILS_MAC_H_
-
-#include <CoreFoundation/CoreFoundation.h>
-#import <Foundation/Foundation.h>
-
-// CFTypeRefToNSObjectAutorelease transfers ownership of a Core Foundation
-// object (one derived from CFTypeRef) to the Foundation memory management
-// system.  In a traditional managed-memory environment, cf_object is
-// autoreleased and returned as an NSObject.  In a garbage-collected
-// environment, cf_object is marked as eligible for garbage collection.
-//
-// This function should only be used to convert a concrete CFTypeRef type to
-// its equivalent "toll-free bridged" NSObject subclass, for example,
-// converting a CFStringRef to NSString.
-//
-// By calling this function, callers relinquish any ownership claim to
-// cf_object.  In a managed-memory environment, the object's ownership will be
-// managed by the innermost NSAutoreleasePool, so after this function returns,
-// callers should not assume that cf_object is valid any longer than the
-// returned NSObject.
-static inline id CFTypeRefToNSObjectAutorelease(CFTypeRef cf_object) {
-  // When GC is on, NSMakeCollectable marks cf_object for GC and autorelease
-  // is a no-op.
-  //
-  // In the traditional GC-less environment, NSMakeCollectable is a no-op,
-  // and cf_object is autoreleased, balancing out the caller's ownership claim.
-  //
-  // NSMakeCollectable returns nil when used on a NULL object.
-  return [NSMakeCollectable(cf_object) autorelease];
-}
-
-#endif  // BASE_FOUNDATION_UTILS_MAC_H_
--- a/ipc/chromium/src/base/mac_util.h
+++ b/ipc/chromium/src/base/mac_util.h
@@ -1,39 +1,15 @@
 // Copyright (c) 2008 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
 #ifndef BASE_MAC_UTIL_H_
 #define BASE_MAC_UTIL_H_
 
-struct FSRef;
-class FilePath;
-
-#ifdef __OBJC__
-@class NSBundle;
-#else
-class NSBundle;
-#endif
-
-#include <string>
-
 namespace mac_util {
 
-std::string PathFromFSRef(const FSRef& ref);
-bool FSRefFromPath(const std::string& path, FSRef* ref);
-
 // Returns true if the application is running from a bundle
 bool AmIBundled();
 
-// Returns the main bundle or the override, used for code that needs
-// to fetch resources from bundles, but work within a unittest where we
-// aren't a bundle.
-NSBundle* MainAppBundle();
-
-// Set the bundle that MainAppBundle will return, overriding the default value
-// (Restore the default by calling SetOverrideAppBundle(nil)).
-void SetOverrideAppBundle(NSBundle* bundle);
-void SetOverrideAppBundlePath(const FilePath& file_path);
-
 }  // namespace mac_util
 
 #endif  // BASE_MAC_UTIL_H_
--- a/ipc/chromium/src/base/mac_util.mm
+++ b/ipc/chromium/src/base/mac_util.mm
@@ -9,29 +9,16 @@
 
 #include "base/file_path.h"
 #include "base/logging.h"
 #include "base/scoped_cftyperef.h"
 #include "base/sys_string_conversions.h"
 
 namespace mac_util {
 
-std::string PathFromFSRef(const FSRef& ref) {
-  scoped_cftyperef<CFURLRef> url(
-      CFURLCreateFromFSRef(kCFAllocatorDefault, &ref));
-  NSString *path_string = [(NSURL *)url.get() path];
-  return [path_string fileSystemRepresentation];
-}
-
-bool FSRefFromPath(const std::string& path, FSRef* ref) {
-  OSStatus status = FSPathMakeRef((const UInt8*)path.c_str(),
-                                  ref, nil);
-  return status == noErr;
-}
-
 // Adapted from http://developer.apple.com/carbon/tipsandtricks.html#AmIBundled
 bool AmIBundled() {
   ProcessSerialNumber psn = {0, kCurrentProcess};
 
   FSRef fsref;
   if (GetProcessBundleLocation(&psn, &fsref) != noErr)
     return false;
 
@@ -39,31 +26,9 @@ bool AmIBundled() {
   if (FSGetCatalogInfo(&fsref, kFSCatInfoNodeFlags, &info,
                        NULL, NULL, NULL) != noErr) {
     return false;
   }
 
   return info.nodeFlags & kFSNodeIsDirectoryMask;
 }
 
-// No threading worries since NSBundle isn't thread safe.
-static NSBundle* g_override_app_bundle = nil;
-
-NSBundle* MainAppBundle() {
-  if (g_override_app_bundle)
-    return g_override_app_bundle;
-  return [NSBundle mainBundle];
-}
-
-void SetOverrideAppBundle(NSBundle* bundle) {
-  [g_override_app_bundle release];
-  g_override_app_bundle = [bundle retain];
-}
-
-void SetOverrideAppBundlePath(const FilePath& file_path) {
-  NSString* path = base::SysUTF8ToNSString(file_path.value());
-  NSBundle* bundle = [NSBundle bundleWithPath:path];
-  DCHECK(bundle) << "failed to load the bundle: " << file_path.value();
-
-  SetOverrideAppBundle(bundle);
-}
-
 }  // namespace mac_util
--- a/ipc/chromium/src/base/process.h
+++ b/ipc/chromium/src/base/process.h
@@ -60,30 +60,16 @@ class Process {
 
   // Set a prcess as backgrounded.  If value is true, the priority
   // of the process will be lowered.  If value is false, the priority
   // of the process will be made "normal" - equivalent to default
   // process priority.
   // Returns true if the priority was changed, false otherwise.
   bool SetProcessBackgrounded(bool value);
 
-  // Reduces the working set of memory used by the process.
-  // The algorithm used by this function is intentionally vague.  Repeated calls
-  // to this function consider the process' previous required Working Set sizes
-  // to determine a reasonable reduction.  This helps give memory back to the OS
-  // in increments without over releasing memory.
-  // When the WorkingSet is reduced, it is permanent, until the caller calls
-  // UnReduceWorkingSet.
-  // Returns true if successful, false otherwise.
-  bool ReduceWorkingSet();
-
-  // Undoes the effects of prior calls to ReduceWorkingSet().
-  // Returns true if successful, false otherwise.
-  bool UnReduceWorkingSet();
-
   // Releases as much of the working set back to the OS as possible.
   // Returns true if successful, false otherwise.
   bool EmptyWorkingSet();
 
  private:
   ProcessHandle process_;
   size_t last_working_set_size_;
 };
--- a/ipc/chromium/src/base/process_posix.cc
+++ b/ipc/chromium/src/base/process_posix.cc
@@ -31,26 +31,16 @@ bool Process::IsProcessBackgrounded() co
 bool Process::SetProcessBackgrounded(bool value) {
   // http://code.google.com/p/chromium/issues/detail?id=8083
   // Just say we did it to keep renderer happy at the moment.  Need to finish
   // cleaning this up w/in higher layers since windows is probably the only
   // one that can raise priorities w/o privileges.
   return true;
 }
 
-bool Process::ReduceWorkingSet() {
-  // http://code.google.com/p/chromium/issues/detail?id=8083
-  return false;
-}
-
-bool Process::UnReduceWorkingSet() {
-  // http://code.google.com/p/chromium/issues/detail?id=8083
-  return false;
-}
-
 bool Process::EmptyWorkingSet() {
   // http://code.google.com/p/chromium/issues/detail?id=8083
   return false;
 }
 
 ProcessId Process::pid() const {
   if (process_ == 0)
     return 0;
--- a/ipc/chromium/src/base/process_util.h
+++ b/ipc/chromium/src/base/process_util.h
@@ -185,97 +185,40 @@ bool LaunchApp(const std::vector<std::st
 // returns if privileges were successfully adjusted.
 void SetCurrentProcessPrivileges(ChildPrivileges privs);
 
 // Executes the application specified by cl. This function delegates to one
 // of the above two platform-specific functions.
 bool LaunchApp(const CommandLine& cl,
                bool wait, bool start_hidden, ProcessHandle* process_handle);
 
-#if defined(OS_WIN)
-// Executes the application specified by |cmd_line| and copies the contents
-// printed to the standard output to |output|, which should be non NULL.
-// Blocks until the started process terminates.
-// Returns true if the application was run successfully, false otherwise.
-bool GetAppOutput(const std::wstring& cmd_line, std::string* output);
-#elif defined(OS_POSIX)
-// Executes the application specified by |cl| and wait for it to exit. Stores
-// the output (stdout) in |output|. Redirects stderr to /dev/null. Returns true
-// on success (application launched and exited cleanly, with exit code
-// indicating success). |output| is modified only when the function finished
-// successfully.
-bool GetAppOutput(const CommandLine& cl, std::string* output);
-#endif
-
 // Used to filter processes by process ID.
 class ProcessFilter {
  public:
   // Returns true to indicate set-inclusion and false otherwise.  This method
   // should not have side-effects and should be idempotent.
   virtual bool Includes(ProcessId pid, ProcessId parent_pid) const = 0;
   virtual ~ProcessFilter() { }
 };
 
-// Returns the number of processes on the machine that are running from the
-// given executable name.  If filter is non-null, then only processes selected
-// by the filter will be counted.
-int GetProcessCount(const std::wstring& executable_name,
-                    const ProcessFilter* filter);
-
-// Attempts to kill all the processes on the current machine that were launched
-// from the given executable name, ending them with the given exit code.  If
-// filter is non-null, then only processes selected by the filter are killed.
-// Returns false if all processes were able to be killed off, false if at least
-// one couldn't be killed.
-bool KillProcesses(const std::wstring& executable_name, int exit_code,
-                   const ProcessFilter* filter);
-
 // Attempts to kill the process identified by the given process
 // entry structure, giving it the specified exit code. If |wait| is true, wait
 // for the process to be actually terminated before returning.
 // Returns true if this is successful, false otherwise.
 bool KillProcess(ProcessHandle process, int exit_code, bool wait);
-#if defined(OS_WIN)
-bool KillProcessById(ProcessId process_id, int exit_code, bool wait);
-#endif
 
 // Get the termination status (exit code) of the process and return true if the
 // status indicates the process crashed. |child_exited| is set to true iff the
 // child process has terminated. (|child_exited| may be NULL.)
 //
 // On Windows, it is an error to call this if the process hasn't terminated
 // yet. On POSIX, |child_exited| is set correctly since we detect terminate in
 // a different manner on POSIX.
 bool DidProcessCrash(bool* child_exited, ProcessHandle handle);
 
-// Waits for process to exit. In POSIX systems, if the process hasn't been
-// signaled then puts the exit code in |exit_code|; otherwise it's considered
-// a failure. On Windows |exit_code| is always filled. Returns true on success,
-// and closes |handle| in any case.
-bool WaitForExitCode(ProcessHandle handle, int* exit_code);
-
-// Wait for all the processes based on the named executable to exit.  If filter
-// is non-null, then only processes selected by the filter are waited on.
-// Returns after all processes have exited or wait_milliseconds have expired.
-// Returns true if all the processes exited, false otherwise.
-bool WaitForProcessesToExit(const std::wstring& executable_name,
-                            int wait_milliseconds,
-                            const ProcessFilter* filter);
-
-// Waits a certain amount of time (can be 0) for all the processes with a given
-// executable name to exit, then kills off any of them that are still around.
-// If filter is non-null, then only processes selected by the filter are waited
-// on.  Killed processes are ended with the given exit code.  Returns false if
-// any processes needed to be killed, true if they all exited cleanly within
-// the wait_milliseconds delay.
-bool CleanupProcesses(const std::wstring& executable_name,
-                      int wait_milliseconds,
-                      int exit_code,
-                      const ProcessFilter* filter);
-
 // This class provides a way to iterate through the list of processes
 // on the current machine that were started from the given executable
 // name.  To use, create an instance and then call NextProcessEntry()
 // until it returns false.
 class NamedProcessIterator {
  public:
   NamedProcessIterator(const std::wstring& executable_name,
                        const ProcessFilter* filter);
@@ -319,81 +262,28 @@ class NamedProcessIterator {
 #if !defined(OS_BSD) || defined(__GLIBC__)
   ProcessEntry entry_;
   const ProcessFilter* filter_;
 #endif
 
   DISALLOW_EVIL_CONSTRUCTORS(NamedProcessIterator);
 };
 
-// Working Set (resident) memory usage broken down by
-// priv (private): These pages (kbytes) cannot be shared with any other process.
-// shareable:      These pages (kbytes) can be shared with other processes under
-//                 the right circumstances.
-// shared :        These pages (kbytes) are currently shared with at least one
-//                 other process.
-struct WorkingSetKBytes {
-  size_t priv;
-  size_t shareable;
-  size_t shared;
-};
-
-// Committed (resident + paged) memory usage broken down by
-// private: These pages cannot be shared with any other process.
-// mapped:  These pages are mapped into the view of a section (backed by
-//          pagefile.sys)
-// image:   These pages are mapped into the view of an image section (backed by
-//          file system)
-struct CommittedKBytes {
-  size_t priv;
-  size_t mapped;
-  size_t image;
-};
-
-// Free memory (Megabytes marked as free) in the 2G process address space.
-// total : total amount in megabytes marked as free. Maximum value is 2048.
-// largest : size of the largest contiguous amount of memory found. It is
-//   always smaller or equal to FreeMBytes::total.
-// largest_ptr: starting address of the largest memory block.
-struct FreeMBytes {
-  size_t total;
-  size_t largest;
-  void* largest_ptr;
-};
-
 // Provides performance metrics for a specified process (CPU usage, memory and
 // IO counters). To use it, invoke CreateProcessMetrics() to get an instance
 // for a specific process, then access the information with the different get
 // methods.
 class ProcessMetrics {
  public:
   // Creates a ProcessMetrics for the specified process.
   // The caller owns the returned object.
   static ProcessMetrics* CreateProcessMetrics(ProcessHandle process);
 
   ~ProcessMetrics();
 
-  // Returns the current space allocated for the pagefile, in bytes (these pages
-  // may or may not be in memory).
-  size_t GetPagefileUsage() const;
-  // Returns the peak space allocated for the pagefile, in bytes.
-  size_t GetPeakPagefileUsage() const;
-  // Returns the current working set size, in bytes.
-  size_t GetWorkingSetSize() const;
-  // Returns private usage, in bytes. Private bytes is the amount
-  // of memory currently allocated to a process that cannot be shared.
-  // Note: returns 0 on unsupported OSes: prior to XP SP2.
-  size_t GetPrivateBytes() const;
-  // Fills a CommittedKBytes with both resident and paged
-  // memory usage as per definition of CommittedBytes.
-  void GetCommittedKBytes(CommittedKBytes* usage) const;
-  // Fills a WorkingSetKBytes containing resident private and shared memory
-  // usage in bytes, as per definition of WorkingSetBytes.
-  bool GetWorkingSetKBytes(WorkingSetKBytes* ws_usage) const;
-
   // Returns the CPU usage in percent since the last time this method was
   // called. The first time this method is called it returns 0 and will return
   // the actual CPU info on subsequent calls.
   // Note that on multi-processor machines, the CPU usage value is for all
   // CPUs. So if you have 2 CPUs and your process is using all the cycles
   // of 1 CPU and not the other CPU, this method returns 50.
   int GetCPUUsage();
 
--- a/ipc/chromium/src/base/process_util_posix.cc
+++ b/ipc/chromium/src/base/process_util_posix.cc
@@ -275,33 +275,16 @@ bool DidProcessCrash(bool* child_exited,
   }
 
   if (WIFEXITED(status))
     return WEXITSTATUS(status) != 0;
 
   return false;
 }
 
-bool WaitForExitCode(ProcessHandle handle, int* exit_code) {
-  int status;
-  if (HANDLE_EINTR(waitpid(handle, &status, 0)) == -1) {
-    NOTREACHED();
-    return false;
-  }
-
-  if (WIFEXITED(status)) {
-    *exit_code = WEXITSTATUS(status);
-    return true;
-  }
-
-  // If it didn't exit cleanly, it must have been signaled.
-  DCHECK(WIFSIGNALED(status));
-  return false;
-}
-
 namespace {
 
 int64_t TimeValToMicroseconds(const struct timeval& tv) {
   return tv.tv_sec * kMicrosecondsPerSecond + tv.tv_usec;
 }
 
 }
 
@@ -339,147 +322,9 @@ int ProcessMetrics::GetCPUUsage() {
                              time_delta);
 
   last_system_time_ = system_time;
   last_time_ = time;
 
   return cpu;
 }
 
-bool GetAppOutput(const CommandLine& cl, std::string* output) {
-  int pipe_fd[2];
-  pid_t pid;
-
-  // Illegal to allocate memory after fork and before execvp
-  InjectiveMultimap fd_shuffle1, fd_shuffle2;
-  fd_shuffle1.reserve(3);
-  fd_shuffle2.reserve(3);
-  const std::vector<std::string>& argv = cl.argv();
-  scoped_array<char*> argv_cstr(new char*[argv.size() + 1]);
-
-  if (pipe(pipe_fd) < 0)
-    return false;
-
-  switch (pid = fork()) {
-    case -1:  // error
-      close(pipe_fd[0]);
-      close(pipe_fd[1]);
-      return false;
-    case 0:  // child
-      {
-        // Obscure fork() rule: in the child, if you don't end up doing exec*(),
-        // you call _exit() instead of exit(). This is because _exit() does not
-        // call any previously-registered (in the parent) exit handlers, which
-        // might do things like block waiting for threads that don't even exist
-        // in the child.
-        int dev_null = open("/dev/null", O_WRONLY);
-        if (dev_null < 0)
-          _exit(127);
-
-        fd_shuffle1.push_back(InjectionArc(pipe_fd[1], STDOUT_FILENO, true));
-        fd_shuffle1.push_back(InjectionArc(dev_null, STDERR_FILENO, true));
-        fd_shuffle1.push_back(InjectionArc(dev_null, STDIN_FILENO, true));
-        // Adding another element here? Remeber to increase the argument to
-        // reserve(), above.
-
-        std::copy(fd_shuffle1.begin(), fd_shuffle1.end(),
-                  std::back_inserter(fd_shuffle2));
-
-        // fd_shuffle1 is mutated by this call because it cannot malloc.
-        if (!ShuffleFileDescriptors(&fd_shuffle1))
-          _exit(127);
-
-        CloseSuperfluousFds(fd_shuffle2);
-
-        for (size_t i = 0; i < argv.size(); i++)
-          argv_cstr[i] = const_cast<char*>(argv[i].c_str());
-        argv_cstr[argv.size()] = NULL;
-        execvp(argv_cstr[0], argv_cstr.get());
-        _exit(127);
-      }
-    default:  // parent
-      {
-        // Close our writing end of pipe now. Otherwise later read would not
-        // be able to detect end of child's output (in theory we could still
-        // write to the pipe).
-        close(pipe_fd[1]);
-
-        int exit_code = EXIT_FAILURE;
-        bool success = WaitForExitCode(pid, &exit_code);
-        if (!success || exit_code != EXIT_SUCCESS) {
-          close(pipe_fd[0]);
-          return false;
-        }
-
-        char buffer[256];
-        std::string buf_output;
-
-        while (true) {
-          ssize_t bytes_read =
-              HANDLE_EINTR(read(pipe_fd[0], buffer, sizeof(buffer)));
-          if (bytes_read <= 0)
-            break;
-          buf_output.append(buffer, bytes_read);
-        }
-        output->swap(buf_output);
-        close(pipe_fd[0]);
-        return true;
-      }
-  }
-}
-
-int GetProcessCount(const std::wstring& executable_name,
-                    const ProcessFilter* filter) {
-  int count = 0;
-
-  NamedProcessIterator iter(executable_name, filter);
-  while (iter.NextProcessEntry())
-    ++count;
-  return count;
-}
-
-bool KillProcesses(const std::wstring& executable_name, int exit_code,
-                   const ProcessFilter* filter) {
-  bool result = true;
-  const ProcessEntry* entry;
-
-  NamedProcessIterator iter(executable_name, filter);
-  while ((entry = iter.NextProcessEntry()) != NULL)
-    result = KillProcess((*entry).pid, exit_code, true) && result;
-
-  return result;
-}
-
-bool WaitForProcessesToExit(const std::wstring& executable_name,
-                            int wait_milliseconds,
-                            const ProcessFilter* filter) {
-  bool result = false;
-
-  // TODO(port): This is inefficient, but works if there are multiple procs.
-  // TODO(port): use waitpid to avoid leaving zombies around
-
-  base::Time end_time = base::Time::Now() +
-      base::TimeDelta::FromMilliseconds(wait_milliseconds);
-  do {
-    NamedProcessIterator iter(executable_name, filter);
-    if (!iter.NextProcessEntry()) {
-      result = true;
-      break;
-    }
-    PlatformThread::Sleep(100);
-  } while ((base::Time::Now() - end_time) > base::TimeDelta());
-
-  return result;
-}
-
-bool CleanupProcesses(const std::wstring& executable_name,
-                      int wait_milliseconds,
-                      int exit_code,
-                      const ProcessFilter* filter) {
-  bool exited_cleanly =
-      WaitForProcessesToExit(executable_name, wait_milliseconds,
-                           filter);
-  if (!exited_cleanly)
-    KillProcesses(executable_name, exit_code, filter);
-  return exited_cleanly;
-}
-
 }  // namespace base
--- a/ipc/chromium/src/base/process_util_win.cc
+++ b/ipc/chromium/src/base/process_util_win.cc
@@ -350,107 +350,16 @@ bool LaunchApp(const std::wstring& cmdli
 }
 
 bool LaunchApp(const CommandLine& cl,
                bool wait, bool start_hidden, ProcessHandle* process_handle) {
   return LaunchApp(cl.command_line_string(), wait,
                    start_hidden, process_handle);
 }
 
-// Attempts to kill the process identified by the given process
-// entry structure, giving it the specified exit code.
-// Returns true if this is successful, false otherwise.
-bool KillProcessById(ProcessId process_id, int exit_code, bool wait) {
-  HANDLE process = OpenProcess(PROCESS_TERMINATE | SYNCHRONIZE,
-                               FALSE,  // Don't inherit handle
-                               process_id);
-  if (!process)
-    return false;
-
-  bool ret = KillProcess(process, exit_code, wait);
-  CloseHandle(process);
-  return ret;
-}
-
-bool GetAppOutput(const std::wstring& cmd_line, std::string* output) {
-  if (!output) {
-    NOTREACHED();
-    return false;
-  }
-
-  HANDLE out_read = NULL;
-  HANDLE out_write = NULL;
-
-  SECURITY_ATTRIBUTES sa_attr;
-  // Set the bInheritHandle flag so pipe handles are inherited.
-  sa_attr.nLength = sizeof(SECURITY_ATTRIBUTES);
-  sa_attr.bInheritHandle = TRUE;
-  sa_attr.lpSecurityDescriptor = NULL;
-
-  // Create the pipe for the child process's STDOUT.
-  if (!CreatePipe(&out_read, &out_write, &sa_attr, 0)) {
-    NOTREACHED() << "Failed to create pipe";
-    return false;
-  }
-
-  // Ensure we don't leak the handles.
-  ScopedHandle scoped_out_read(out_read);
-  ScopedHandle scoped_out_write(out_write);
-
-  // Ensure the read handle to the pipe for STDOUT is not inherited.
-  if (!SetHandleInformation(out_read, HANDLE_FLAG_INHERIT, 0)) {
-    NOTREACHED() << "Failed to disabled pipe inheritance";
-    return false;
-  }
-
-  // Now create the child process
-  PROCESS_INFORMATION proc_info = { 0 };
-  STARTUPINFO start_info = { 0 };
-
-  start_info.cb = sizeof(STARTUPINFO);
-  start_info.hStdOutput = out_write;
-  // Keep the normal stdin and stderr.
-  start_info.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
-  start_info.hStdError = GetStdHandle(STD_ERROR_HANDLE);
-  start_info.dwFlags |= STARTF_USESTDHANDLES;
-
-  // Create the child process.
-  if (!CreateProcess(NULL, const_cast<wchar_t*>(cmd_line.c_str()), NULL, NULL,
-                     TRUE,  // Handles are inherited.
-                     0, NULL, NULL, &start_info, &proc_info)) {
-    NOTREACHED() << "Failed to start process";
-    return false;
-  }
-
-  // We don't need the thread handle, close it now.
-  CloseHandle(proc_info.hThread);
-
-  // Close our writing end of pipe now. Otherwise later read would not be able
-  // to detect end of child's output.
-  scoped_out_write.Close();
-
-  // Read output from the child process's pipe for STDOUT
-  const int kBufferSize = 1024;
-  char buffer[kBufferSize];
-
-  for (;;) {
-    DWORD bytes_read = 0;
-    BOOL success = ReadFile(out_read, buffer, kBufferSize, &bytes_read, NULL);
-    if (!success || bytes_read == 0)
-      break;
-    output->append(buffer, bytes_read);
-  }
-
-  // Let's wait for the process to finish.
-  WaitForSingleObject(proc_info.hProcess, INFINITE);
-  CloseHandle(proc_info.hProcess);
-
-  return true;
-}
-
 bool KillProcess(ProcessHandle process, int exit_code, bool wait) {
   bool result = (TerminateProcess(process, exit_code) != FALSE);
   if (result && wait) {
     // The process may not end immediately due to pending I/O
     if (WAIT_OBJECT_0 != WaitForSingleObject(process, 60 * 1000))
       DLOG(ERROR) << "Error waiting for process exit: " << GetLastError();
   } else if (!result) {
     DLOG(ERROR) << "Unable to terminate process: " << GetLastError();
@@ -484,29 +393,16 @@ bool DidProcessCrash(bool* child_exited,
       exitcode == 0xC000013A ||     // Control-C/end session.
       exitcode == 0x40010004) {     // Debugger terminated process/end session.
     return false;
   }
 
   return true;
 }
 
-bool WaitForExitCode(ProcessHandle handle, int* exit_code) {
-  ScopedHandle closer(handle);  // Ensure that we always close the handle.
-  if (::WaitForSingleObject(handle, INFINITE) != WAIT_OBJECT_0) {
-    NOTREACHED();
-    return false;
-  }
-  DWORD temp_code;  // Don't clobber out-parameters in case of failure.
-  if (!::GetExitCodeProcess(handle, &temp_code))
-    return false;
-  *exit_code = temp_code;
-  return true;
-}
-
 void SetCurrentProcessPrivileges(ChildPrivileges privs) {
 
 }
 
 NamedProcessIterator::NamedProcessIterator(const std::wstring& executable_name,
                                            const ProcessFilter* filter)
     : started_iteration_(false),
       executable_name_(executable_name),
@@ -549,75 +445,16 @@ bool NamedProcessIterator::IncludeEntry(
                                                  entry_.th32ParentProcessID));
 }
 
 void NamedProcessIterator::InitProcessEntry(ProcessEntry* entry) {
   memset(entry, 0, sizeof(*entry));
   entry->dwSize = sizeof(*entry);
 }
 
-int GetProcessCount(const std::wstring& executable_name,
-                    const ProcessFilter* filter) {
-  int count = 0;
-
-  NamedProcessIterator iter(executable_name, filter);
-  while (iter.NextProcessEntry())
-    ++count;
-  return count;
-}
-
-bool KillProcesses(const std::wstring& executable_name, int exit_code,
-                   const ProcessFilter* filter) {
-  bool result = true;
-  const ProcessEntry* entry;
-
-  NamedProcessIterator iter(executable_name, filter);
-  while (entry = iter.NextProcessEntry()) {
-    if (!KillProcessById((*entry).th32ProcessID, exit_code, true))
-      result = false;
-  }
-
-  return result;
-}
-
-bool WaitForProcessesToExit(const std::wstring& executable_name,
-                            int wait_milliseconds,
-                            const ProcessFilter* filter) {
-  const ProcessEntry* entry;
-  bool result = true;
-  DWORD start_time = GetTickCount();
-
-  NamedProcessIterator iter(executable_name, filter);
-  while (entry = iter.NextProcessEntry()) {
-    DWORD remaining_wait =
-      std::max(0, wait_milliseconds -
-          static_cast<int>(GetTickCount() - start_time));
-    HANDLE process = OpenProcess(SYNCHRONIZE,
-                                 FALSE,
-                                 entry->th32ProcessID);
-    DWORD wait_result = WaitForSingleObject(process, remaining_wait);
-    CloseHandle(process);
-    result = result && (wait_result == WAIT_OBJECT_0);
-  }
-
-  return result;
-}
-
-bool CleanupProcesses(const std::wstring& executable_name,
-                      int wait_milliseconds,
-                      int exit_code,
-                      const ProcessFilter* filter) {
-  bool exited_cleanly = WaitForProcessesToExit(executable_name,
-                                               wait_milliseconds,
-                                               filter);
-  if (!exited_cleanly)
-    KillProcesses(executable_name, exit_code, filter);
-  return exited_cleanly;
-}
-
 ///////////////////////////////////////////////////////////////////////////////
 // ProcesMetrics
 
 ProcessMetrics::ProcessMetrics(ProcessHandle process) : process_(process),
                                                         last_time_(0),
                                                         last_system_time_(0) {
   SYSTEM_INFO system_info;
   GetSystemInfo(&system_info);
@@ -626,161 +463,16 @@ ProcessMetrics::ProcessMetrics(ProcessHa
 
 // static
 ProcessMetrics* ProcessMetrics::CreateProcessMetrics(ProcessHandle process) {
   return new ProcessMetrics(process);
 }
 
 ProcessMetrics::~ProcessMetrics() { }
 
-size_t ProcessMetrics::GetPagefileUsage() const {
-  PROCESS_MEMORY_COUNTERS pmc;
-  if (GetProcessMemoryInfo(process_, &pmc, sizeof(pmc))) {
-    return pmc.PagefileUsage;
-  }
-  return 0;
-}
-
-// Returns the peak space allocated for the pagefile, in bytes.
-size_t ProcessMetrics::GetPeakPagefileUsage() const {
-  PROCESS_MEMORY_COUNTERS pmc;
-  if (GetProcessMemoryInfo(process_, &pmc, sizeof(pmc))) {
-    return pmc.PeakPagefileUsage;
-  }
-  return 0;
-}
-
-// Returns the current working set size, in bytes.
-size_t ProcessMetrics::GetWorkingSetSize() const {
-  PROCESS_MEMORY_COUNTERS pmc;
-  if (GetProcessMemoryInfo(process_, &pmc, sizeof(pmc))) {
-    return pmc.WorkingSetSize;
-  }
-  return 0;
-}
-
-size_t ProcessMetrics::GetPrivateBytes() const {
-  // PROCESS_MEMORY_COUNTERS_EX is not supported until XP SP2.
-  // GetProcessMemoryInfo() will simply fail on prior OS. So the requested
-  // information is simply not available. Hence, we will return 0 on unsupported
-  // OSes. Unlike most Win32 API, we don't need to initialize the "cb" member.
-  PROCESS_MEMORY_COUNTERS_EX pmcx;
-  if (GetProcessMemoryInfo(process_,
-                          reinterpret_cast<PROCESS_MEMORY_COUNTERS*>(&pmcx),
-                          sizeof(pmcx))) {
-      return pmcx.PrivateUsage;
-  }
-  return 0;
-}
-
-void ProcessMetrics::GetCommittedKBytes(CommittedKBytes* usage) const {
-  MEMORY_BASIC_INFORMATION mbi = {0};
-  size_t committed_private = 0;
-  size_t committed_mapped = 0;
-  size_t committed_image = 0;
-  void* base_address = NULL;
-  while (VirtualQueryEx(process_, base_address, &mbi, sizeof(mbi)) ==
-      sizeof(mbi)) {
-    if (mbi.State == MEM_COMMIT) {
-      if (mbi.Type == MEM_PRIVATE) {
-        committed_private += mbi.RegionSize;
-      } else if (mbi.Type == MEM_MAPPED) {
-        committed_mapped += mbi.RegionSize;
-      } else if (mbi.Type == MEM_IMAGE) {
-        committed_image += mbi.RegionSize;
-      } else {
-        NOTREACHED();
-      }
-    }
-    void* new_base = (static_cast<BYTE*>(mbi.BaseAddress)) + mbi.RegionSize;
-    // Avoid infinite loop by weird MEMORY_BASIC_INFORMATION.
-    // If we query 64bit processes in a 32bit process, VirtualQueryEx()
-    // returns such data.
-    if (new_base <= base_address) {
-      usage->image = 0;
-      usage->mapped = 0;
-      usage->priv = 0;
-      return;
-    }
-    base_address = new_base;
-  }
-  usage->image = committed_image / 1024;
-  usage->mapped = committed_mapped / 1024;
-  usage->priv = committed_private / 1024;
-}
-
-bool ProcessMetrics::GetWorkingSetKBytes(WorkingSetKBytes* ws_usage) const {
-  size_t ws_private = 0;
-  size_t ws_shareable = 0;
-  size_t ws_shared = 0;
-
-  DCHECK(ws_usage);
-  memset(ws_usage, 0, sizeof(*ws_usage));
-
-  DWORD number_of_entries = 4096;  // Just a guess.
-  PSAPI_WORKING_SET_INFORMATION* buffer = NULL;
-  int retries = 5;
-  for (;;) {
-    DWORD buffer_size = sizeof(PSAPI_WORKING_SET_INFORMATION) +
-                        (number_of_entries * sizeof(PSAPI_WORKING_SET_BLOCK));
-
-    // if we can't expand the buffer, don't leak the previous
-    // contents or pass a NULL pointer to QueryWorkingSet
-    PSAPI_WORKING_SET_INFORMATION* new_buffer =
-        reinterpret_cast<PSAPI_WORKING_SET_INFORMATION*>(
-            realloc(buffer, buffer_size));
-    if (!new_buffer) {
-      free(buffer);
-      return false;
-    }
-    buffer = new_buffer;
-
-    // Call the function once to get number of items
-    if (QueryWorkingSet(process_, buffer, buffer_size))
-      break;  // Success
-
-    if (GetLastError() != ERROR_BAD_LENGTH) {
-      free(buffer);
-      return false;
-    }
-
-    number_of_entries = static_cast<DWORD>(buffer->NumberOfEntries);
-
-    // Maybe some entries are being added right now. Increase the buffer to
-    // take that into account.
-    number_of_entries = static_cast<DWORD>(number_of_entries * 1.25);
-
-    if (--retries == 0) {
-      free(buffer);  // If we're looping, eventually fail.
-      return false;
-    }
-  }
-
-  // On windows 2000 the function returns 1 even when the buffer is too small.
-  // The number of entries that we are going to parse is the minimum between the
-  // size we allocated and the real number of entries.
-  number_of_entries =
-      std::min(number_of_entries, static_cast<DWORD>(buffer->NumberOfEntries));
-  for (unsigned int i = 0; i < number_of_entries; i++) {
-    if (buffer->WorkingSetInfo[i].Shared) {
-      ws_shareable++;
-      if (buffer->WorkingSetInfo[i].ShareCount > 1)
-        ws_shared++;
-    } else {
-      ws_private++;
-    }
-  }
-
-  ws_usage->priv = ws_private * PAGESIZE_KB;
-  ws_usage->shareable = ws_shareable * PAGESIZE_KB;
-  ws_usage->shared = ws_shared * PAGESIZE_KB;
-  free(buffer);
-  return true;
-}
-
 static uint64_t FileTimeToUTC(const FILETIME& ftime) {
   LARGE_INTEGER li;
   li.LowPart = ftime.dwLowDateTime;
   li.HighPart = ftime.dwHighDateTime;
   return li.QuadPart;
 }
 
 int ProcessMetrics::GetCPUUsage() {
--- a/ipc/chromium/src/base/process_win.cc
+++ b/ipc/chromium/src/base/process_win.cc
@@ -31,79 +31,16 @@ bool Process::IsProcessBackgrounded() co
 }
 
 bool Process::SetProcessBackgrounded(bool value) {
   DCHECK(process_);
   DWORD priority = value ? BELOW_NORMAL_PRIORITY_CLASS : NORMAL_PRIORITY_CLASS;
   return (SetPriorityClass(process_, priority) != 0);
 }
 
-// According to MSDN, these are the default values which XP
-// uses to govern working set soft limits.
-// http://msdn.microsoft.com/en-us/library/ms686234.aspx
-static const int kWinDefaultMinSet = 50 * 4096;
-static const int kWinDefaultMaxSet = 345 * 4096;
-static const int kDampingFactor = 2;
-
-bool Process::ReduceWorkingSet() {
-  if (!process_)
-    return false;
-  // The idea here is that when we the process' working set has gone
-  // down, we want to release those pages to the OS quickly.  However,
-  // when it is not going down, we want to be careful not to release
-  // too much back to the OS, as it could cause additional paging.
-
-  // We use a damping function to lessen the working set over time.
-  // As the process grows/shrinks, this algorithm will lag with
-  // working set reduction.
-  //
-  // The intended algorithm is:
-  //   TargetWorkingSetSize = (LastWorkingSet/2 + CurrentWorkingSet) /2
-
-  scoped_ptr<ProcessMetrics> metrics(
-      ProcessMetrics::CreateProcessMetrics(process_));
-  WorkingSetKBytes working_set;
-  if (!metrics->GetWorkingSetKBytes(&working_set))
-    return false;
-
-
-  // We want to compute the amount of working set that the process
-  // needs to keep in memory.  Since other processes contain the
-  // pages which are shared, we don't need to reserve them in our
-  // process, the system already has them tagged.  Keep in mind, we
-  // don't get to control *which* pages get released, but if we
-  // assume reasonable distribution of pages, this should generally
-  // be the right value.
-  size_t current_working_set_size  = working_set.priv +
-                                     working_set.shareable;
-
-  size_t max_size = current_working_set_size;
-  if (last_working_set_size_)
-    max_size = (max_size + last_working_set_size_) / 2;  // Average.
-  max_size *= 1024;  // Convert to KBytes.
-  last_working_set_size_ = current_working_set_size / kDampingFactor;
-
-  BOOL rv = SetProcessWorkingSetSize(process_, kWinDefaultMinSet, max_size);
-  return rv == TRUE;
-}
-
-bool Process::UnReduceWorkingSet() {
-  if (!process_)
-    return false;
-
-  if (!last_working_set_size_)
-    return true;  // There was nothing to undo.
-
-  // We've had a reduced working set.  Make sure we have lots of
-  // headroom now that we're active again.
-  size_t limit = last_working_set_size_ * kDampingFactor * 2 * 1024;
-  BOOL rv = SetProcessWorkingSetSize(process_, kWinDefaultMinSet, limit);
-  return rv == TRUE;
-}
-
 bool Process::EmptyWorkingSet() {
   if (!process_)
     return false;
 
   BOOL rv = SetProcessWorkingSetSize(process_, -1, -1);
   return rv == TRUE;
 }
 
deleted file mode 100644
--- a/ipc/chromium/src/base/string_escape.cc
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/string_escape.h"
-
-#include <string>
-
-#include "base/string_util.h"
-
-namespace string_escape {
-
-// Try to escape |c| as a "SingleEscapeCharacter" (\n, etc).  If successful,
-// returns true and appends the escape sequence to |dst|.
-template<typename CHAR>
-static bool JavascriptSingleEscapeChar(const CHAR c, std::string* dst) {
-  // WARNING: if you add a new case here, you need to update the reader as well.
-  switch (c) {
-    case '\b':
-      dst->append("\\b");
-      break;
-    case '\f':
-      dst->append("\\f");
-      break;
-    case '\n':
-      dst->append("\\n");
-      break;
-    case '\r':
-      dst->append("\\r");
-      break;
-    case '\t':
-      dst->append("\\t");
-      break;
-    case '\v':
-      dst->append("\\v");
-      break;
-    case '\\':
-      dst->append("\\\\");
-      break;
-    case '"':
-      dst->append("\\\"");
-      break;
-    default:
-      return false;
-  }
-  return true;
-}
-
-void JavascriptDoubleQuote(const string16& str,
-                           bool put_in_quotes,
-                           std::string* dst) {
-  if (put_in_quotes)
-    dst->push_back('"');
-
-  for (string16::const_iterator it = str.begin(); it != str.end(); ++it) {
-    char16 c = *it;
-    if (!JavascriptSingleEscapeChar(c, dst)) {
-      if (c > 255) {
-        // Non-ascii values need to be unicode dst->
-        // TODO(tc): Some unicode values are handled specially. See
-        // spidermonkey code.
-        StringAppendF(dst, "\\u%04X", c);
-      } else if (c < 32 || c > 126) {
-        // Spidermonkey hex escapes these values.
-        StringAppendF(dst, "\\x%02X", c);
-      } else {
-        dst->push_back(static_cast<char>(c));
-      }
-    }
-  }
-
-  if (put_in_quotes)
-    dst->push_back('"');
-}
-
-void JavascriptDoubleQuote(const std::string& str,
-                           bool put_in_quotes,
-                           std::string* dst) {
-  if (put_in_quotes)
-    dst->push_back('"');
-
-  for (std::string::const_iterator it = str.begin(); it != str.end(); ++it) {
-    unsigned char c = *it;
-    if (!JavascriptSingleEscapeChar(c, dst)) {
-      // Hex encode if the character is non-printable 7bit ascii
-      if (c < 32 || c == 127) {
-        StringAppendF(dst, "\\x%02X", c);
-      } else {
-        dst->push_back(static_cast<char>(c));
-      }
-    }
-  }
-
-  if (put_in_quotes)
-    dst->push_back('"');
-}
-
-}  // namespace string_escape
deleted file mode 100644
--- a/ipc/chromium/src/base/string_escape.h
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-// This file defines utility functions for escaping strings.
-
-#ifndef BASE_STRING_ESCAPE_H__
-#define BASE_STRING_ESCAPE_H__
-
-#include "base/string16.h"
-
-namespace string_escape {
-
-// Escape |str| appropriately for a javascript string litereal, _appending_ the
-// result to |dst|. This will create standard escape sequences (\b, \n),
-// hex escape sequences (\x00), and unicode escape sequences (\uXXXX).
-// If |put_in_quotes| is true, the result will be surrounded in double quotes.
-// The outputted literal, when interpreted by the browser, should result in a
-// javascript string that is identical and the same length as the input |str|.
-void JavascriptDoubleQuote(const string16& str,
-                           bool put_in_quotes,
-                           std::string* dst);
-
-// Similar to the wide version, but for narrow strings.  It will not use
-// \uXXXX unicode escape sequences.  It will pass non-7bit characters directly
-// into the string unencoded, allowing the browser to interpret the encoding.
-// The outputted literal, when interpreted by the browser, could result in a
-// javascript string of a different length than the input |str|.
-void JavascriptDoubleQuote(const std::string& str,
-                           bool put_in_quotes,
-                           std::string* dst);
-
-}  // namespace string_escape
-
-#endif  // BASE_STRING_ESCAPE_H__
--- a/ipc/chromium/src/base/string_util.h
+++ b/ipc/chromium/src/base/string_util.h
@@ -213,54 +213,23 @@ std::wstring StringPrintf(const wchar_t*
 const std::string& SStringPrintf(std::string* dst, const char* format, ...);
 const std::wstring& SStringPrintf(std::wstring* dst,
                                   const wchar_t* format, ...);
 
 // Append result to a supplied string
 void StringAppendF(std::string* dst, const char* format, ...);
 void StringAppendF(std::wstring* dst, const wchar_t* format, ...);
 
-// This is mpcomplete's pattern for saving a string copy when dealing with
-// a function that writes results into a wchar_t[] and wanting the result to
-// end up in a std::wstring.  It ensures that the std::wstring's internal
-// buffer has enough room to store the characters to be written into it, and
-// sets its .length() attribute to the right value.
-//
-// The reserve() call allocates the memory required to hold the string
-// plus a terminating null.  This is done because resize() isn't
-// guaranteed to reserve space for the null.  The resize() call is
-// simply the only way to change the string's 'length' member.
-//
-// XXX-performance: the call to wide.resize() takes linear time, since it fills
-// the string's buffer with nulls.  I call it to change the length of the
-// string (needed because writing directly to the buffer doesn't do this).
-// Perhaps there's a constant-time way to change the string's length.
-template <class string_type>
-inline typename string_type::value_type* WriteInto(string_type* str,
-                                                   size_t length_with_null) {
-  str->reserve(length_with_null);
-  str->resize(length_with_null - 1);
-  return &((*str)[0]);
-}
-
 //-----------------------------------------------------------------------------
 
 // Splits |str| into a vector of strings delimited by |s|. Append the results
 // into |r| as they appear. If several instances of |s| are contiguous, or if
 // |str| begins with or ends with |s|, then an empty string is inserted.
 //
 // Every substring is trimmed of any leading or trailing white space.
 void SplitString(const std::wstring& str,
                  wchar_t s,
                  std::vector<std::wstring>* r);
 void SplitString(const std::string& str,
                  char s,
                  std::vector<std::string>* r);
 
-// Returns true if the string passed in matches the pattern. The pattern
-// string can contain wildcards like * and ?
-// TODO(iyengar) This function may not work correctly for CJK strings as
-// it does individual character matches.
-// The backslash character (\) is an escape character for * and ?
-bool MatchPattern(const std::wstring& string, const std::wstring& pattern);
-bool MatchPattern(const std::string& string, const std::string& pattern);
-
 #endif  // BASE_STRING_UTIL_H_
--- a/ipc/chromium/src/base/sys_string_conversions.h
+++ b/ipc/chromium/src/base/sys_string_conversions.h
@@ -8,25 +8,16 @@
 // Provides system-dependent string type conversions for cases where it's
 // necessary to not use ICU. Generally, you should not need this in Chrome,
 // but it is used in some shared code. Dependencies should be minimal.
 
 #include <string>
 #include "base/basictypes.h"
 #include "base/string16.h"
 
-#if defined(OS_MACOSX)
-#include <CoreFoundation/CoreFoundation.h>
-#ifdef __OBJC__
-@class NSString;
-#else
-class NSString;
-#endif
-#endif  // OS_MACOSX
-
 class StringPiece;
 
 namespace base {
 
 // Converts between wide and UTF-8 representations of a string. On error, the
 // result is system-dependent.
 std::string SysWideToUTF8(const std::wstring& wide);
 std::wstring SysUTF8ToWide(const StringPiece& utf8);
@@ -44,40 +35,11 @@ std::wstring SysNativeMBToWide(const Str
 // Converts between 8-bit and wide strings, using the given code page. The
 // code page identifier is one accepted by the Windows function
 // MultiByteToWideChar().
 std::wstring SysMultiByteToWide(const StringPiece& mb, uint32_t code_page);
 std::string SysWideToMultiByte(const std::wstring& wide, uint32_t code_page);
 
 #endif  // defined(OS_WIN)
 
-// Mac-specific ----------------------------------------------------------------
-
-#if defined(OS_MACOSX)
-
-// Converts between STL strings and CFStringRefs/NSStrings.
-
-// Creates a string, and returns it with a refcount of 1. You are responsible
-// for releasing it. Returns NULL on failure.
-CFStringRef SysUTF8ToCFStringRef(const std::string& utf8);
-CFStringRef SysUTF16ToCFStringRef(const string16& utf16);
-CFStringRef SysWideToCFStringRef(const std::wstring& wide);
-
-// Same, but returns an autoreleased NSString.
-NSString* SysUTF8ToNSString(const std::string& utf8);
-NSString* SysUTF16ToNSString(const string16& utf16);
-NSString* SysWideToNSString(const std::wstring& wide);
-
-// Converts a CFStringRef to an STL string. Returns an empty string on failure.
-std::string SysCFStringRefToUTF8(CFStringRef ref);
-string16 SysCFStringRefToUTF16(CFStringRef ref);
-std::wstring SysCFStringRefToWide(CFStringRef ref);
-
-// Same, but accepts NSString input.
-std::string SysNSStringToUTF8(NSString* ref);
-string16 SysNSStringToUTF16(NSString* ref);
-std::wstring SysNSStringToWide(NSString* ref);
-
-#endif  // defined(OS_MACOSX)
-
 }  // namespace base
 
 #endif  // BASE_SYS_STRING_CONVERSIONS_H_
--- a/ipc/chromium/src/base/sys_string_conversions_mac.mm
+++ b/ipc/chromium/src/base/sys_string_conversions_mac.mm
@@ -3,17 +3,16 @@
 // found in the LICENSE file.
 
 #include "base/sys_string_conversions.h"
 
 #import <Foundation/Foundation.h>
 
 #include <vector>
 
-#include "base/foundation_utils_mac.h"
 #include "base/scoped_cftyperef.h"
 #include "base/string_piece.h"
 
 namespace base {
 
 namespace {
 
 // Convert the supplied CFString into the specified encoding, and return it as
@@ -139,60 +138,9 @@ std::wstring SysUTF8ToWide(const StringP
 std::string SysWideToNativeMB(const std::wstring& wide) {
   return SysWideToUTF8(wide);
 }
 
 std::wstring SysNativeMBToWide(const StringPiece& native_mb) {
   return SysUTF8ToWide(native_mb);
 }
 
-CFStringRef SysUTF8ToCFStringRef(const std::string& utf8) {
-  return STLStringToCFStringWithEncodingsT(utf8, kNarrowStringEncoding);
-}
-
-CFStringRef SysUTF16ToCFStringRef(const string16& utf16) {
-  return STLStringToCFStringWithEncodingsT(utf16, kMediumStringEncoding);
-}
-
-CFStringRef SysWideToCFStringRef(const std::wstring& wide) {
-  return STLStringToCFStringWithEncodingsT(wide, kWideStringEncoding);
-}
-
-NSString* SysUTF8ToNSString(const std::string& utf8) {
-  return CFTypeRefToNSObjectAutorelease(SysUTF8ToCFStringRef(utf8));
-}
-
-NSString* SysUTF16ToNSString(const string16& utf16) {
-  return CFTypeRefToNSObjectAutorelease(SysUTF16ToCFStringRef(utf16));
-}
-
-NSString* SysWideToNSString(const std::wstring& wide) {
-  return CFTypeRefToNSObjectAutorelease(SysWideToCFStringRef(wide));
-}
-
-std::string SysCFStringRefToUTF8(CFStringRef ref) {
-  return CFStringToSTLStringWithEncodingT<std::string>(ref,
-                                                       kNarrowStringEncoding);
-}
-
-string16 SysCFStringRefToUTF16(CFStringRef ref) {
-  return CFStringToSTLStringWithEncodingT<string16>(ref,
-                                                    kMediumStringEncoding);
-}
-
-std::wstring SysCFStringRefToWide(CFStringRef ref) {
-  return CFStringToSTLStringWithEncodingT<std::wstring>(ref,
-                                                        kWideStringEncoding);
-}
-
-std::string SysNSStringToUTF8(NSString* nsstring) {
-  return SysCFStringRefToUTF8(reinterpret_cast<CFStringRef>(nsstring));
-}
-
-string16 SysNSStringToUTF16(NSString* nsstring) {
-  return SysCFStringRefToUTF16(reinterpret_cast<CFStringRef>(nsstring));
-}
-
-std::wstring SysNSStringToWide(NSString* nsstring) {
-  return SysCFStringRefToWide(reinterpret_cast<CFStringRef>(nsstring));
-}
-
 }  // namespace base
--- a/ipc/chromium/src/base/win_util.cc
+++ b/ipc/chromium/src/base/win_util.cc
@@ -12,35 +12,16 @@
 #include "base/scoped_handle.h"
 #include "base/scoped_ptr.h"
 #include "base/singleton.h"
 #include "base/string_util.h"
 #include "base/tracked.h"
 
 namespace win_util {
 
-#define SIZEOF_STRUCT_WITH_SPECIFIED_LAST_MEMBER(struct_name, member) \
-    offsetof(struct_name, member) + \
-    (sizeof static_cast<struct_name*>(NULL)->member)
-#define NONCLIENTMETRICS_SIZE_PRE_VISTA \
-    SIZEOF_STRUCT_WITH_SPECIFIED_LAST_MEMBER(NONCLIENTMETRICS, lfMessageFont)
-
-void GetNonClientMetrics(NONCLIENTMETRICS* metrics) {
-  DCHECK(metrics);
-
-  static const UINT SIZEOF_NONCLIENTMETRICS =
-      (GetWinVersion() >= WINVERSION_VISTA) ?
-      sizeof(NONCLIENTMETRICS) : NONCLIENTMETRICS_SIZE_PRE_VISTA;
-  metrics->cbSize = SIZEOF_NONCLIENTMETRICS;
-  const bool success = !!SystemParametersInfo(SPI_GETNONCLIENTMETRICS,
-                                              SIZEOF_NONCLIENTMETRICS, metrics,
-                                              0);
-  DCHECK(success);
-}
-
 WinVersion GetWinVersion() {
   static bool checked_version = false;
   static WinVersion win_version = WINVERSION_PRE_2000;
   if (!checked_version) {
     OSVERSIONINFOEX version_info;
     version_info.dwOSVersionInfoSize = sizeof version_info;
     GetVersionEx(reinterpret_cast<OSVERSIONINFO*>(&version_info));
     if (version_info.dwMajorVersion == 5) {
@@ -70,295 +51,28 @@ WinVersion GetWinVersion() {
     } else if (version_info.dwMajorVersion > 6) {
       win_version = WINVERSION_WIN7;
     }
     checked_version = true;
   }
   return win_version;
 }
 
-void GetServicePackLevel(int* major, int* minor) {
-  DCHECK(major && minor);
-  static bool checked_version = false;
-  static int service_pack_major = -1;
-  static int service_pack_minor = -1;
-  if (!checked_version) {
-    OSVERSIONINFOEX version_info = {0};
-    version_info.dwOSVersionInfoSize = sizeof(version_info);
-    GetVersionEx(reinterpret_cast<OSVERSIONINFOW*>(&version_info));
-    service_pack_major = version_info.wServicePackMajor;
-    service_pack_minor = version_info.wServicePackMinor;
-    checked_version = true;
-  }
-
-  *major = service_pack_major;
-  *minor = service_pack_minor;
-}
-
-bool AddAccessToKernelObject(HANDLE handle, WELL_KNOWN_SID_TYPE known_sid,
-                             ACCESS_MASK access) {
-  PSECURITY_DESCRIPTOR descriptor = NULL;
-  PACL old_dacl = NULL;
-  PACL new_dacl = NULL;
-
-  if (ERROR_SUCCESS != GetSecurityInfo(handle, SE_KERNEL_OBJECT,
-            DACL_SECURITY_INFORMATION, NULL, NULL, &old_dacl, NULL,
-            &descriptor))
-    return false;
-
-  BYTE sid[SECURITY_MAX_SID_SIZE] = {0};
-  DWORD size_sid = SECURITY_MAX_SID_SIZE;
-
-  if (known_sid == WinSelfSid) {
-    // We hijack WinSelfSid when we want to add the current user instead of
-    // a known sid.
-    HANDLE token = NULL;
-    if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &token)) {
-      LocalFree(descriptor);
-      return false;
-    }
-
-    DWORD size = sizeof(TOKEN_USER) + size_sid;
-    TOKEN_USER* token_user = reinterpret_cast<TOKEN_USER*>(new BYTE[size]);
-    scoped_ptr<TOKEN_USER> token_user_ptr(token_user);
-    BOOL ret = GetTokenInformation(token, TokenUser, token_user, size, &size);
-
-    CloseHandle(token);
-
-    if (!ret) {
-      LocalFree(descriptor);
-      return false;
-    }
-    memcpy(sid, token_user->User.Sid, size_sid);
-  } else {
-    if (!CreateWellKnownSid(known_sid , NULL, sid, &size_sid)) {
-      LocalFree(descriptor);
-      return false;
-    }
-  }
-
-  EXPLICIT_ACCESS new_access = {0};
-  new_access.grfAccessMode = GRANT_ACCESS;
-  new_access.grfAccessPermissions = access;
-  new_access.grfInheritance = NO_INHERITANCE;
-
-  new_access.Trustee.pMultipleTrustee = NULL;
-  new_access.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
-  new_access.Trustee.TrusteeForm = TRUSTEE_IS_SID;
-  new_access.Trustee.ptstrName = reinterpret_cast<LPWSTR>(&sid);
-
-  if (ERROR_SUCCESS != SetEntriesInAcl(1, &new_access, old_dacl, &new_dacl)) {
-    LocalFree(descriptor);
-    return false;
-  }
-
-  DWORD result = SetSecurityInfo(handle, SE_KERNEL_OBJECT,
-                                 DACL_SECURITY_INFORMATION, NULL, NULL,
-                                 new_dacl, NULL);
-
-  LocalFree(new_dacl);
-  LocalFree(descriptor);
-
-  if (ERROR_SUCCESS != result)
-    return false;
-
-  return true;
-}
-
-bool GetUserSidString(std::wstring* user_sid) {
-  // Get the current token.
-  HANDLE token = NULL;
-  if (!::OpenProcessToken(::GetCurrentProcess(), TOKEN_QUERY, &token))
-    return false;
-  ScopedHandle token_scoped(token);
-
-  DWORD size = sizeof(TOKEN_USER) + SECURITY_MAX_SID_SIZE;
-  scoped_ptr<TOKEN_USER> user(reinterpret_cast<TOKEN_USER*>(new BYTE[size]));
-
-  if (!::GetTokenInformation(token, TokenUser, user.get(), size, &size))
-    return false;
-
-  if (!user->User.Sid)
-    return false;
-
-  // Convert the data to a string.
-  wchar_t* sid_string;
-  if (!::ConvertSidToStringSid(user->User.Sid, &sid_string))
-    return false;
-
-  *user_sid = sid_string;
-
-  ::LocalFree(sid_string);
-
-  return true;
-}
-
-bool GetLogonSessionOnlyDACL(SECURITY_DESCRIPTOR** security_descriptor) {
-  // Get the current token.
-  HANDLE token = NULL;
-  if (!OpenProcessToken(::GetCurrentProcess(), TOKEN_QUERY, &token))
-    return false;
-  ScopedHandle token_scoped(token);
-
-  // Get the size of the TokenGroups structure.
-  DWORD size = 0;
-  BOOL result = GetTokenInformation(token, TokenGroups, NULL,  0, &size);
-  if (result != FALSE && GetLastError() != ERROR_INSUFFICIENT_BUFFER)
-    return false;
-
-  // Get the data.
-  scoped_ptr<TOKEN_GROUPS> token_groups;
-  token_groups.reset(reinterpret_cast<TOKEN_GROUPS*>(new char[size]));
-
-  if (!GetTokenInformation(token, TokenGroups, token_groups.get(), size, &size))
-    return false;
-
-  // Look for the logon sid.
-  SID* logon_sid = NULL;
-  for (unsigned int i = 0; i < token_groups->GroupCount ; ++i) {
-    if ((token_groups->Groups[i].Attributes & SE_GROUP_LOGON_ID) != 0) {
-        logon_sid = static_cast<SID*>(token_groups->Groups[i].Sid);
-        break;
-    }
-  }
-
-  if (!logon_sid)
-    return false;
-
-  // Convert the data to a string.
-  wchar_t* sid_string;
-  if (!ConvertSidToStringSid(logon_sid, &sid_string))
-    return false;
-
-  static const wchar_t dacl_format[] = L"D:(A;OICI;GA;;;%ls)";
-  wchar_t dacl[SECURITY_MAX_SID_SIZE + arraysize(dacl_format) + 1] = {0};
-  wsprintf(dacl, dacl_format, sid_string);
-
-  LocalFree(sid_string);
-
-  // Convert the string to a security descriptor
-  if (!ConvertStringSecurityDescriptorToSecurityDescriptor(
-      dacl,
-      SDDL_REVISION_1,
-      reinterpret_cast<PSECURITY_DESCRIPTOR*>(security_descriptor),
-      NULL)) {
-    return false;
-  }
-
-  return true;
-}
-
-#pragma warning(push)
-#pragma warning(disable:4312 4244)
-WNDPROC SetWindowProc(HWND hwnd, WNDPROC proc) {
-  // The reason we don't return the SetwindowLongPtr() value is that it returns
-  // the orignal window procedure and not the current one. I don't know if it is
-  // a bug or an intended feature.
-  WNDPROC oldwindow_proc =
-      reinterpret_cast<WNDPROC>(GetWindowLongPtr(hwnd, GWLP_WNDPROC));
-  SetWindowLongPtr(hwnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(proc));
-  return oldwindow_proc;
-}
-
-void* SetWindowUserData(HWND hwnd, void* user_data) {
-  return
-      reinterpret_cast<void*>(SetWindowLongPtr(hwnd, GWLP_USERDATA,
-          reinterpret_cast<LONG_PTR>(user_data)));
-}
-
-void* GetWindowUserData(HWND hwnd) {
-  return reinterpret_cast<void*>(GetWindowLongPtr(hwnd, GWLP_USERDATA));
-}
-
-// Maps to the WNDPROC for a window that was active before the subclass was
-// installed.
-static const wchar_t* const kHandlerKey = L"__ORIGINAL_MESSAGE_HANDLER__";
-
-bool IsSubclassed(HWND window, WNDPROC subclass_proc) {
-  WNDPROC original_handler =
-      reinterpret_cast<WNDPROC>(GetWindowLongPtr(window, GWLP_WNDPROC));
-  return original_handler == subclass_proc;
-}
-
-bool Subclass(HWND window, WNDPROC subclass_proc) {
-  WNDPROC original_handler =
-      reinterpret_cast<WNDPROC>(GetWindowLongPtr(window, GWLP_WNDPROC));
-  if (original_handler != subclass_proc) {
-    win_util::SetWindowProc(window, subclass_proc);
-    SetProp(window, kHandlerKey, (void*)original_handler);
-    return true;
-  }
-  return false;
-}
-
-bool Unsubclass(HWND window, WNDPROC subclass_proc) {
-  WNDPROC current_handler =
-      reinterpret_cast<WNDPROC>(GetWindowLongPtr(window, GWLP_WNDPROC));
-  if (current_handler == subclass_proc) {
-    HANDLE original_handler = GetProp(window, kHandlerKey);
-    if (original_handler) {
-      RemoveProp(window, kHandlerKey);
-      win_util::SetWindowProc(window,
-                              reinterpret_cast<WNDPROC>(original_handler));
-      return true;
-    }
-  }
-  return false;
-}
-
-WNDPROC GetSuperclassWNDPROC(HWND window) {
-  return reinterpret_cast<WNDPROC>(GetProp(window, kHandlerKey));
-}
-
-#pragma warning(pop)
-
 bool IsShiftPressed() {
   return (::GetKeyState(VK_SHIFT) & 0x80) == 0x80;
 }
 
 bool IsCtrlPressed() {
   return (::GetKeyState(VK_CONTROL) & 0x80) == 0x80;
 }
 
 bool IsAltPressed() {
   return (::GetKeyState(VK_MENU) & 0x80) == 0x80;
 }
 
-std::wstring GetClassName(HWND window) {
-  // GetClassNameW will return a truncated result (properly null terminated) if
-  // the given buffer is not large enough.  So, it is not possible to determine
-  // that we got the entire class name if the result is exactly equal to the
-  // size of the buffer minus one.
-  DWORD buffer_size = MAX_PATH;
-  while (true) {
-    std::wstring output;
-    DWORD size_ret =
-        GetClassNameW(window, WriteInto(&output, buffer_size), buffer_size);
-    if (size_ret == 0)
-      break;
-    if (size_ret < (buffer_size - 1)) {
-      output.resize(size_ret);
-      return output;
-    }
-    buffer_size *= 2;
-  }
-  return std::wstring();  // error
-}
-
-bool UserAccountControlIsEnabled() {
-  RegKey key(HKEY_LOCAL_MACHINE,
-      L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System");
-  DWORD uac_enabled;
-  if (!key.ReadValueDW(L"EnableLUA", &uac_enabled))
-    return true;
-  // Users can set the EnableLUA value to something arbitrary, like 2, which
-  // Vista will treat as UAC enabled, so we make sure it is not set to 0.
-  return (uac_enabled != 0);
-}
-
 std::wstring FormatMessage(unsigned messageid) {
   wchar_t* string_buffer = NULL;
   unsigned string_length = ::FormatMessage(
       FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
       FORMAT_MESSAGE_IGNORE_INSERTS, NULL, messageid, 0,
       reinterpret_cast<wchar_t *>(&string_buffer), 0, NULL);
 
   std::wstring formatted_string;
@@ -371,76 +85,16 @@ std::wstring FormatMessage(unsigned mess
   }
   return formatted_string;
 }
 
 std::wstring FormatLastWin32Error() {
   return FormatMessage(GetLastError());
 }
 
-typedef std::map<HWND, tracked_objects::Location> HWNDInfoMap;
-struct HWNDBirthMapTrait : public DefaultSingletonTraits<HWNDInfoMap> {
-};
-struct HWNDDeathMapTrait : public DefaultSingletonTraits<HWNDInfoMap> {
-};
-
-void NotifyHWNDCreation(const tracked_objects::Location& from_here, HWND hwnd) {
-  HWNDInfoMap* birth_map = Singleton<HWNDInfoMap, HWNDBirthMapTrait>::get();
-  HWNDInfoMap::iterator birth_iter = birth_map->find(hwnd);
-  if (birth_iter != birth_map->end()) {
-    birth_map->erase(birth_iter);
-
-    // We have already seen this HWND, was it destroyed?
-    HWNDInfoMap* death_map = Singleton<HWNDInfoMap, HWNDDeathMapTrait>::get();
-    HWNDInfoMap::iterator death_iter = death_map->find(hwnd);
-    if (death_iter == death_map->end()) {
-      // We did not get a destruction notification.  The code is probably not
-      // calling NotifyHWNDDestruction for that HWND.
-      NOTREACHED() << "Creation of HWND reported for already tracked HWND. The "
-                      "HWND destruction is probably not tracked properly. "
-                      "Fix it!";
-    } else {
-      death_map->erase(death_iter);
-    }
-  }
-  birth_map->insert(std::pair<HWND, tracked_objects::Location>(hwnd,
-                                                              from_here));
-}
-
-void NotifyHWNDDestruction(const tracked_objects::Location& from_here,
-                           HWND hwnd) {
-  HWNDInfoMap* death_map = Singleton<HWNDInfoMap, HWNDDeathMapTrait>::get();
-  HWNDInfoMap::iterator death_iter = death_map->find(hwnd);
-
-  HWNDInfoMap* birth_map = Singleton<HWNDInfoMap, HWNDBirthMapTrait>::get();
-  HWNDInfoMap::iterator birth_iter = birth_map->find(hwnd);
-
-  if (death_iter != death_map->end()) {
-    std::string allocation, first_delete, second_delete;
-    if (birth_iter != birth_map->end())
-      birth_iter->second.Write(true, true, &allocation);
-    death_iter->second.Write(true, true, &first_delete);
-    from_here.Write(true, true, &second_delete);
-    LOG(FATAL) << "Double delete of an HWND. Please file a bug with info on "
-        "how you got that assertion and the following information:\n"
-        "Double delete of HWND 0x" << hwnd << "\n" <<
-        "Allocated at " << allocation << "\n" <<
-        "Deleted first at " << first_delete << "\n" <<
-        "Deleted again at " << second_delete;
-    death_map->erase(death_iter);
-  }
-
-  if (birth_iter == birth_map->end()) {
-    NOTREACHED() << "Destruction of HWND reported for unknown HWND. The HWND "
-                    "construction is probably not tracked properly. Fix it!";
-  }
-  death_map->insert(std::pair<HWND, tracked_objects::Location>(hwnd,
-                                                               from_here));
-}
-
 }  // namespace win_util
 
 #ifdef _MSC_VER
 //
 // If the ASSERT below fails, please install Visual Studio 2005 Service Pack 1.
 //
 extern char VisualStudio2005ServicePack1Detection[10];
 COMPILE_ASSERT(sizeof(&VisualStudio2005ServicePack1Detection) == sizeof(void*),
--- a/ipc/chromium/src/base/win_util.h
+++ b/ipc/chromium/src/base/win_util.h
@@ -22,101 +22,30 @@ enum WinVersion {
   WINVERSION_2000 = 1,
   WINVERSION_XP = 2,
   WINVERSION_SERVER_2003 = 3,
   WINVERSION_VISTA = 4,
   WINVERSION_2008 = 5,
   WINVERSION_WIN7 = 6
 };
 
-void GetNonClientMetrics(NONCLIENTMETRICS* metrics);
-
 // Returns the running version of Windows.
 WinVersion GetWinVersion();
 
-// Returns the major and minor version of the service pack installed.
-void GetServicePackLevel(int* major, int* minor);
-
-// Adds an ACE in the DACL of the object referenced by handle. The ACE is
-// granting |access| to the user |known_sid|.
-// If |known_sid| is WinSelfSid, the sid of the current user will be added to
-// the DACL.
-bool AddAccessToKernelObject(HANDLE handle, WELL_KNOWN_SID_TYPE known_sid,
-                             ACCESS_MASK access);
-
-// Returns the string representing the current user sid.
-bool GetUserSidString(std::wstring* user_sid);
-
-// Creates a security descriptor with a DACL that has one ace giving full
-// access to the current logon session.
-// The security descriptor returned must be freed using LocalFree.
-// The function returns true if it succeeds, false otherwise.
-bool GetLogonSessionOnlyDACL(SECURITY_DESCRIPTOR** security_descriptor);
-
-// Useful for subclassing a HWND.  Returns the previous window procedure.
-WNDPROC SetWindowProc(HWND hwnd, WNDPROC wndproc);
-
-// Returns true if the existing window procedure is the same as |subclass_proc|.
-bool IsSubclassed(HWND window, WNDPROC subclass_proc);
-
-// Subclasses a window, replacing its existing window procedure with the
-// specified one. Returns true if the current window procedure was replaced,
-// false if the window has already been subclassed with the specified
-// subclass procedure.
-bool Subclass(HWND window, WNDPROC subclass_proc);
-
-// Unsubclasses a window subclassed using Subclass. Returns true if
-// the window was subclassed with the specified |subclass_proc| and the window
-// was successfully unsubclassed, false if the window's window procedure is not
-// |subclass_proc|.
-bool Unsubclass(HWND window, WNDPROC subclass_proc);
-
-// Retrieves the original WNDPROC of a window subclassed using
-// SubclassWindow.
-WNDPROC GetSuperclassWNDPROC(HWND window);
-
-// Pointer-friendly wrappers around Get/SetWindowLong(..., GWLP_USERDATA, ...)
-// Returns the previously set value.
-void* SetWindowUserData(HWND hwnd, void* user_data);
-void* GetWindowUserData(HWND hwnd);
-
 // Returns true if the shift key is currently pressed.
 bool IsShiftPressed();
 
 // Returns true if the ctrl key is currently pressed.
 bool IsCtrlPressed();
 
 // Returns true if the alt key is currently pressed.
 bool IsAltPressed();
 
-// A version of the GetClassNameW API that returns the class name in an
-// std::wstring.  An empty result indicates a failure to get the class name.
-std::wstring GetClassName(HWND window);
-
-// Returns false if user account control (UAC) has been disabled with the
-// EnableLUA registry flag. Returns true if user account control is enabled.
-// NOTE: The EnableLUA registry flag, which is ignored on Windows XP
-// machines, might still exist and be set to 0 (UAC disabled), in which case
-// this function will return false. You should therefore check this flag only
-// if the OS is Vista.
-bool UserAccountControlIsEnabled();
-
 // Use the Win32 API FormatMessage() function to generate a string, using
 // Windows's default Message Compiled resources; ignoring the inserts.
 std::wstring FormatMessage(unsigned messageid);
 
 // Uses the last Win32 error to generate a human readable message string.
 std::wstring FormatLastWin32Error();
 
-// These 2 methods are used to track HWND creation/destruction to investigate
-// a mysterious crasher http://crbugs.com/4714 (crasher in on NCDestroy) that
-// might be caused by a multiple delete of an HWND.
-void NotifyHWNDCreation(const tracked_objects::Location& from_here, HWND hwnd);
-void NotifyHWNDDestruction(const tracked_objects::Location& from_here,
-                           HWND hwnd);
-
-#define TRACK_HWND_CREATION(hwnd) win_util::NotifyHWNDCreation(FROM_HERE, hwnd)
-#define TRACK_HWND_DESTRUCTION(hwnd) \
-    win_util::NotifyHWNDDestruction(FROM_HERE, hwnd)
-
 }  // namespace win_util
 
 #endif  // BASE_WIN_UTIL_H__
--- a/ipc/chromium/src/chrome/common/child_process_info.h
+++ b/ipc/chromium/src/chrome/common/child_process_info.h
@@ -33,17 +33,16 @@ class ChildProcessInfo {
   virtual int GetProcessId() const {
     if (pid_ != -1)
       return pid_;
 
     pid_ = process_.pid();
     return pid_;
   }
   void SetProcessBackgrounded() const { process_.SetProcessBackgrounded(true); }
-  void ReduceWorkingSet() const { process_.ReduceWorkingSet(); }
 
   // Returns an English name of the process type, should only be used for non
   // user-visible strings, or debugging pages like about:memory.
   static std::wstring GetTypeNameInEnglish(ProcessType type);
 
   // Returns a localized title for the child process.  For example, a plugin
   // process would be "Plug-in: Flash" when name is "Flash".
   std::wstring GetLocalizedTitle() const;
--- a/js/src/frontend/Parser.cpp
+++ b/js/src/frontend/Parser.cpp
@@ -6512,16 +6512,24 @@ Parser<ParseHandler>::arrayInitializer()
         }
 
         MUST_MATCH_TOKEN(TOK_RB, JSMSG_BRACKET_AFTER_LIST);
     }
     handler.setEndPosition(literal, pos().end);
     return literal;
 }
 
+static JSAtom*
+DoubleToAtom(ExclusiveContext *cx, double value)
+{
+    // This is safe because doubles can not be moved.
+    Value tmp = DoubleValue(value);
+    return ToAtom<CanGC>(cx, HandleValue::fromMarkedLocation(&tmp));
+}
+
 template <typename ParseHandler>
 typename ParseHandler::Node
 Parser<ParseHandler>::objectLiteral()
 {
     JS_ASSERT(tokenStream.isCurrentTokenType(TOK_LC));
 
     /*
      * A map from property names we've seen thus far to a mask of property
@@ -6535,28 +6543,26 @@ Parser<ParseHandler>::objectLiteral()
         VALUE   = 0x4 | GET | SET
     };
 
     Node literal = handler.newObjectLiteral(pos().begin);
     if (!literal)
         return null();
 
     RootedAtom atom(context);
-    Value tmp;
     for (;;) {
         TokenKind ltok = tokenStream.getToken(TokenStream::KeywordIsName);
         if (ltok == TOK_RC)
             break;
 
         JSOp op = JSOP_INITPROP;
         Node propname;
         switch (ltok) {
           case TOK_NUMBER:
-            tmp = DoubleValue(tokenStream.currentToken().number());
-            atom = ToAtom<CanGC>(context, HandleValue::fromMarkedLocation(&tmp));
+            atom = DoubleToAtom(context, tokenStream.currentToken().number());
             if (!atom)
                 return null();
             propname = newNumber(tokenStream.currentToken());
             break;
 
           case TOK_NAME: {
             atom = tokenStream.currentName();
             if (atom == context->names().get) {
@@ -6581,29 +6587,26 @@ Parser<ParseHandler>::objectLiteral()
             } else if (tt == TOK_STRING) {
                 atom = tokenStream.currentToken().atom();
 
                 uint32_t index;
                 if (atom->isIndex(&index)) {
                     propname = handler.newNumber(index, NoDecimal, pos());
                     if (!propname)
                         return null();
-                    tmp = DoubleValue(index);
-                    atom = ToAtom<CanGC>(context, HandleValue::fromMarkedLocation(&tmp));
+                    atom = DoubleToAtom(context, index);
                     if (!atom)
                         return null();
                 } else {
                     propname = stringLiteral();
                     if (!propname)
                         return null();
                 }
             } else if (tt == TOK_NUMBER) {
-                double number = tokenStream.currentToken().number();
-                tmp = DoubleValue(number);
-                atom = ToAtom<CanGC>(context, HandleValue::fromMarkedLocation(&tmp));
+                atom = DoubleToAtom(context, tokenStream.currentToken().number());
                 if (!atom)
                     return null();
                 propname = newNumber(tokenStream.currentToken());
                 if (!propname)
                     return null();
             } else {
                 // Not an accessor property after all.
                 tokenStream.ungetToken();
--- a/mobile/android/base/Makefile.in
+++ b/mobile/android/base/Makefile.in
@@ -1381,25 +1381,26 @@ res/drawable-hdpi/icon.png: $(ICON_PATH_
 res/drawable-xhdpi/icon.png: $(ICON_PATH_XHDPI)
 	$(NSINSTALL) -D res/drawable-xhdpi
 	cp $(ICON_PATH_XHDPI) $@
 
 res/drawable-xxhdpi/icon.png: $(ICON_PATH_XXHDPI)
 	$(NSINSTALL) -D res/drawable-xxhdpi
 	cp $(ICON_PATH_XXHDPI) $@
 
-$(RES_DIRS): $(subst res/,$(srcdir)/resources/,$(RESOURCES))
-	$(RM) -r $@
-	$(NSINSTALL) -D $@
+$(call mkdir_deps,$(RES_DIRS)): $(subst res/,$(srcdir)/resources/,$(RESOURCES)) Makefile
+	$(RM) -r $(@D)
+	$(NSINSTALL) -D $(@D)
+	$(TOUCH) $@
 
-$(RESOURCES): $(RES_DIRS) $(subst res/,$(srcdir)/resources/,$(RESOURCES))
+$(RESOURCES): $(call mkdir_deps,$(RES_DIRS)) $(subst res/,$(srcdir)/resources/,$(RESOURCES))
 	@echo "creating $@"
 	$(NSINSTALL) $(subst res/,$(srcdir)/resources/,$@) $(dir $@)
 
-res/values/strings.xml: $(RES_DIRS)
+res/values/strings.xml: $(call mkdir_deps,$(RES_DIRS))
 	$(MAKE) -C locales
 
 # With multilocale builds, there will be multiple strings.xml files. We need to
 # rebuild gecko.ap_ if any of them change.
 MULTILOCALE_STRINGS_XML_FILES := $(wildcard res/values-*/strings.xml)
 all_resources = \
   res/drawable-mdpi/icon.png \
   res/drawable-hdpi/icon.png \
--- a/mobile/android/base/home/BrowserSearch.java
+++ b/mobile/android/base/home/BrowserSearch.java
@@ -224,32 +224,43 @@ public class BrowserSearch extends HomeF
 
     @Override
     public void onViewCreated(View view, Bundle savedInstanceState) {
         super.onViewCreated(view, savedInstanceState);
 
         mList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
             @Override
             public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
-                // Account for the search engines
+                // Perform the user-entered search if the user clicks on a search engine row.
+                // This row will be disabled if suggestions (in addition to the user-entered term) are showing.
+                if (view instanceof SearchEngineRow) {
+                    ((SearchEngineRow) view).performUserEnteredSearch();
+                    return;
+                }
+
+                // Account for the search engine rows.
                 position -= getSuggestEngineCount();
                 final Cursor c = mAdapter.getCursor(position);
                 final String url = c.getString(c.getColumnIndexOrThrow(URLColumns.URL));
 
                 // This item is a TwoLinePageRow, so we allow switch-to-tab.
                 mUrlOpenListener.onUrlOpen(url, EnumSet.of(OnUrlOpenListener.Flags.ALLOW_SWITCH_TO_TAB));
             }
         });
 
         mList.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
             @Override
             public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
-                // Account for the search engines
+                // Don't do anything when the user long-clicks on a search engine row.
+                if (view instanceof SearchEngineRow) {
+                    return true;
+                }
+
+                // Account for the search engine rows.
                 position -= getSuggestEngineCount();
-
                 return mList.onItemLongClick(parent, view, position, id);
             }
         });
 
         final ListSelectionListener listener = new ListSelectionListener();
         mList.setOnItemSelectedListener(listener);
         mList.setOnFocusChangeListener(listener);
 
--- a/mobile/android/base/home/SearchEngineRow.java
+++ b/mobile/android/base/home/SearchEngineRow.java
@@ -106,41 +106,16 @@ class SearchEngineRow extends AnimatedHe
         mSuggestionView = (FlowLayout) findViewById(R.id.suggestion_layout);
         mIconView = (FaviconView) findViewById(R.id.suggestion_icon);
 
         // User-entered search term is first suggestion
         mUserEnteredView = (LinearLayout) findViewById(R.id.suggestion_user_entered);
         mUserEnteredView.setOnClickListener(mClickListener);
 
         mUserEnteredTextView = (TextView) findViewById(R.id.suggestion_text);
-
-        // Handle clicks on this row that don't happen on individual suggestion views.
-        setOnClickListener(new OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                // Don't do anything if we are showing suggestions.
-                if (mSearchEngine.suggestions.size() > 0) {
-                    return;
-                }
-
-                // Otherwise, perform a search for the user entered term.
-                String searchTerm = getSuggestionTextFromView(mUserEnteredView);
-                if (mSearchListener != null) {
-                    mSearchListener.onSearch(mSearchEngine.name, searchTerm);
-                }
-            }
-        });
-
-        // Intercept long clicks to avoid trying to show a context menu.
-        setOnLongClickListener(new OnLongClickListener() {
-            @Override
-            public boolean onLongClick(View v) {
-                return true;
-            }
-        });
     }
 
     private void setDescriptionOnSuggestion(View v, String suggestion) {
         v.setContentDescription(getResources().getString(R.string.suggestion_for_engine,
                                                          mSearchEngine.name, suggestion));
     }
 
     private String getSuggestionTextFromView(View v) {
@@ -149,16 +124,26 @@ class SearchEngineRow extends AnimatedHe
     }
 
     private void setSuggestionOnView(View v, String suggestion) {
         final TextView suggestionText = (TextView) v.findViewById(R.id.suggestion_text);
         suggestionText.setText(suggestion);
         setDescriptionOnSuggestion(suggestionText, suggestion);
     }
 
+    /**
+     * Perform a search for the user-entered term.
+     */
+    public void performUserEnteredSearch() {
+        String searchTerm = getSuggestionTextFromView(mUserEnteredView);
+        if (mSearchListener != null) {
+            mSearchListener.onSearch(mSearchEngine.name, searchTerm);
+        }
+    }
+
     public void setSearchTerm(String searchTerm) {
         mUserEnteredTextView.setText(searchTerm);
 
         // mSearchEngine is not set in the first call to this method; the content description
         // is instead initially set in updateFromSearchEngine.
         if (mSearchEngine != null) {
             setDescriptionOnSuggestion(mUserEnteredTextView, searchTerm);
         }
--- a/mobile/android/base/locales/Makefile.in
+++ b/mobile/android/base/locales/Makefile.in
@@ -56,16 +56,17 @@ strings-xml-preqs =\
   $(STRINGSPATH) \
   $(SYNCSTRINGSPATH) \
   $(BOOKMARKSPATH) \
   $(if $(IS_LANGUAGE_REPACK),FORCE) \
   $(NULL)
 
 $(dir-strings-xml)/strings.xml: $(strings-xml-preqs)
 	$(NSINSTALL) -D $(dir-strings-xml)
+	$(TOUCH) $(call mkdir_deps,$(dir-strings-xml))
 	$(PYTHON) $(topsrcdir)/config/Preprocessor.py \
       $(DEFINES) \
 	  -DBRANDPATH="$(BRANDPATH)" \
 	  -DSTRINGSPATH="$(STRINGSPATH)" \
 	  -DSYNCSTRINGSPATH="$(SYNCSTRINGSPATH)" \
 	  -DBOOKMARKSPATH="$(BOOKMARKSPATH)" \
 	  -DMOZ_APP_DISPLAYNAME="@MOZ_APP_DISPLAYNAME@" \
       $< \
--- a/mobile/android/chrome/content/SelectionHandler.js
+++ b/mobile/android/chrome/content/SelectionHandler.js
@@ -505,17 +505,19 @@ var SelectionHandler = {
   },
 
   _clearSelection: function sh_clearSelection() {
     let selection = this._getSelection();
     if (selection) {
       // Remove our listener before we clear the selection
       selection.QueryInterface(Ci.nsISelectionPrivate).removeSelectionListener(this);
       // Clear selection without clearing the anchorNode or focusNode
-      selection.collapseToStart();
+      if (selection.rangeCount != 0) {
+        selection.collapseToStart();
+      }
     }
   },
 
   _deactivate: function sh_deactivate() {
     this._activeType = this.TYPE_NONE;
 
     sendMessageToJava({ type: "TextSelection:HideHandles" });
 
--- a/modules/libpref/src/init/all.js
+++ b/modules/libpref/src/init/all.js
@@ -142,23 +142,16 @@ pref("browser.display.focus_ring_on_anyt
 // focus ring border style.
 // 0 = solid border, 1 = dotted border
 pref("browser.display.focus_ring_style", 1);
 
 pref("browser.helperApps.alwaysAsk.force",  false);
 pref("browser.helperApps.neverAsk.saveToDisk", "");
 pref("browser.helperApps.neverAsk.openFile", "");
 
-#ifdef XP_WIN
-// By default, security zone information is stored in the Alternate Data Stream
-// of downloaded executable files on Windows.  This preference allows disabling
-// this feature, and thus the associated system-level execution prompts.
-pref("browser.download.saveZoneInformation", true);
-#endif
-
 // xxxbsmedberg: where should prefs for the toolkit go?
 pref("browser.chrome.toolbar_tips",         true);
 // 0 = Pictures Only, 1 = Text Only, 2 = Pictures and Text
 pref("browser.chrome.toolbar_style",        2);
 // max image size for which it is placed in the tab icon for tabbrowser.
 // if 0, no images are used for tab icons for image documents.
 pref("browser.chrome.image_icons.max_size", 1024);
 
--- a/toolkit/components/jsdownloads/src/DownloadCore.jsm
+++ b/toolkit/components/jsdownloads/src/DownloadCore.jsm
@@ -62,19 +62,16 @@ XPCOMUtils.defineLazyModuleGetter(this, 
                                   "resource://gre/modules/NetUtil.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "OS",
                                   "resource://gre/modules/osfile.jsm")
 XPCOMUtils.defineLazyModuleGetter(this, "Promise",
                                   "resource://gre/modules/commonjs/sdk/core/promise.js");
 XPCOMUtils.defineLazyModuleGetter(this, "Task",
                                   "resource://gre/modules/Task.jsm");
 
-XPCOMUtils.defineLazyServiceGetter(this, "gDownloadHistory",
-           "@mozilla.org/browser/download-history;1",
-           Ci.nsIDownloadHistory);
 XPCOMUtils.defineLazyServiceGetter(this, "gExternalHelperAppService",
            "@mozilla.org/uriloader/external-helper-app-service;1",
            Ci.nsIExternalHelperAppService);
 
 const BackgroundFileSaverStreamListener = Components.Constructor(
       "@mozilla.org/network/background-file-saver;1?mode=streamlistener",
       "nsIBackgroundFileSaver");
 
@@ -1204,40 +1201,16 @@ DownloadSaver.prototype = {
    * @rejects JavaScript exception.
    */
   removePartialData: function DS_removePartialData()
   {
     return Promise.resolve();
   },
 
   /**
-   * This can be called by the saver implementation when the download is already
-   * started, to add it to the browsing history.  This method has no effect if
-   * the download is private.
-   */
-  addToHistory: function ()
-  {
-    if (this.download.source.isPrivate) {
-      return;
-    }
-
-    let sourceUri = NetUtil.newURI(this.download.source.url);
-    let referrer = this.download.source.referrer;
-    let referrerUri = referrer ? NetUtil.newURI(referrer) : null;
-    let targetUri = NetUtil.newURI(new FileUtils.File(
-                                       this.download.target.path));
-
-    // The start time is always available when we reach this point.
-    let startPRTime = this.download.startTime.getTime() * 1000;
-
-    gDownloadHistory.addDownload(sourceUri, referrerUri, startPRTime,
-                                 targetUri);
-  },
-
-  /**
    * Returns a static representation of the current object state.
    *
    * @return A JavaScript object that can be serialized to JSON.
    */
   toSerializable: function ()
   {
     throw new Error("Not implemented.");
   },
@@ -1289,21 +1262,16 @@ DownloadCopySaver.prototype = {
   /**
    * Indicates whether the "cancel" method has been called.  This is used to
    * prevent the request from starting in case the operation is canceled before
    * the BackgroundFileSaver instance has been created.
    */
   _canceled: false,
 
   /**
-   * True if the associated download has already been added to browsing history.
-   */
-  alreadyAddedToHistory: false,
-
-  /**
    * String corresponding to the entityID property of the nsIResumableChannel
    * used to execute the download, or null if the channel was not resumable or
    * the saver was instructed not to keep partially downloaded data.
    */
   entityID: null,
 
   /**
    * Implements "DownloadSaver.execute".
@@ -1315,26 +1283,16 @@ DownloadCopySaver.prototype = {
     this._canceled = false;
 
     let download = this.download;
     let targetPath = download.target.path;
     let partFilePath = download.target.partFilePath;
     let keepPartialData = download.tryToKeepPartialData;
 
     return Task.spawn(function task_DCS_execute() {
-      // Add the download to history the first time it is started in this
-      // session.  If the download is restarted in a different session, a new
-      // history visit will be added.  We do this just to avoid the complexity
-      // of serializing this state between sessions, since adding a new visit
-      // does not have any noticeable side effect.
-      if (!this.alreadyAddedToHistory) {
-        this.addToHistory();
-        this.alreadyAddedToHistory = true;
-      }
-
       // To reduce the chance that other downloads reuse the same final target
       // file name, we should create a placeholder as soon as possible, before
       // starting the network request.  The placeholder is also required in case
       // we are using a ".part" file instead of the final target while the
       // download is in progress.
       try {
         // If the file already exists, don't delete its contents yet.
         let file = yield OS.File.open(targetPath, { write: true });
@@ -1670,43 +1628,28 @@ DownloadLegacySaver.prototype = {
    */
   progressWasNotified: false,
 
   /**
    * Called by the nsITransfer implementation when the request has started.
    *
    * @param aRequest
    *        nsIRequest associated to the status update.
-   * @param aAlreadyAddedToHistory
-   *        Indicates that the nsIExternalHelperAppService component already
-   *        added the download to the browsing history, unless it was started
-   *        from a private browsing window.  When this parameter is false, the
-   *        download is added to the browsing history here.  Private downloads
-   *        are never added to history even if this parameter is false.
    */
-  onTransferStarted: function (aRequest, aAlreadyAddedToHistory)
+  onTransferStarted: function (aRequest)
   {
     // Store the entity ID to use for resuming if required.
     if (this.download.tryToKeepPartialData &&
         aRequest instanceof Ci.nsIResumableChannel) {
       try {
         // If reading the ID succeeds, the source is resumable.
         this.entityID = aRequest.entityID;
       } catch (ex if ex instanceof Components.Exception &&
                      ex.result == Cr.NS_ERROR_NOT_RESUMABLE) { }
     }
-
-    // For legacy downloads, we must update the referrer at this time.
-    if (aRequest instanceof Ci.nsIHttpChannel && aRequest.referrer) {
-      this.download.source.referrer = aRequest.referrer.spec;
-    }
-
-    if (!aAlreadyAddedToHistory) {
-      this.addToHistory();
-    }
   },
 
   /**
    * Called by the nsITransfer implementation when the request has finished.
    *
    * @param aRequest
    *        nsIRequest associated to the status update.
    * @param aStatus
@@ -1754,17 +1697,16 @@ DownloadLegacySaver.prototype = {
   {
     // Check if this is not the first execution of the download.  The Download
     // object guarantees that this function is not re-entered during execution.
     if (this.firstExecutionFinished) {
       if (!this.copySaver) {
         this.copySaver = new DownloadCopySaver();
         this.copySaver.download = this.download;
         this.copySaver.entityID = this.entityID;
-        this.copySaver.alreadyAddedToHistory = true;
       }
       return this.copySaver.execute.apply(this.copySaver, arguments);
     }
 
     this.setProgressBytesFn = aSetProgressBytesFn;
 
     return Task.spawn(function task_DLS_execute() {
       try {
--- a/toolkit/components/jsdownloads/src/DownloadIntegration.jsm
+++ b/toolkit/components/jsdownloads/src/DownloadIntegration.jsm
@@ -61,24 +61,16 @@ XPCOMUtils.defineLazyServiceGetter(this,
 XPCOMUtils.defineLazyGetter(this, "gParentalControlsService", function() {
   if ("@mozilla.org/parental-controls-service;1" in Cc) {
     return Cc["@mozilla.org/parental-controls-service;1"]
       .createInstance(Ci.nsIParentalControlsService);
   }
   return null;
 });
 
-/**
- * ArrayBufferView representing the bytes to be written to the "Zone.Identifier"
- * Alternate Data Stream to mark a file as coming from the Internet zone.
- */
-XPCOMUtils.defineLazyGetter(this, "gInternetZoneIdentifier", function() {
-  return new TextEncoder().encode("[ZoneTransfer]\r\nZoneId=3\r\n");
-});
-
 const Timer = Components.Constructor("@mozilla.org/timer;1", "nsITimer",
                                      "initWithCallback");
 
 /**
  * Indicates the delay between a change to the downloads data and the related
  * save operation.  This value is the result of a delicate trade-off, assuming
  * the host application uses the browser history instead of the download store
  * to save completed downloads.
@@ -392,56 +384,25 @@ this.DownloadIntegration = {
    * aParam aDownload
    *        The Download object.
    *
    * @return {Promise}
    * @resolves When all the operations completed successfully.
    * @rejects JavaScript exception if any of the operations failed.
    */
   downloadDone: function(aDownload) {
-    return Task.spawn(function () {
-#ifdef XP_WIN
-      // On Windows, we mark any executable file saved to the NTFS file system
-      // as coming from the Internet security zone.  We do this by writing to
-      // the "Zone.Identifier" Alternate Data Stream directly, because the Save
-      // method of the IAttachmentExecute interface would trigger operations
-      // that may cause the application to hang, or other performance issues.
-      // The stream created in this way is forward-compatible with all the
-      // current and future versions of Windows.
-      if (Services.prefs.getBoolPref("browser.download.saveZoneInformation")) {
-        let file = new FileUtils.File(aDownload.target.path);
-        if (file.isExecutable()) {
-          try {
-            let streamPath = aDownload.target.path + ":Zone.Identifier";
-            let stream = yield OS.File.open(streamPath, { create: true });
-            try {
-              yield stream.write(gInternetZoneIdentifier);
-            } finally {
-              yield stream.close();
-            }
-          } catch (ex) {
-            // If writing to the stream fails, we ignore the error and continue.
-            // The Windows API error 123 (ERROR_INVALID_NAME) is expected to
-            // occur when working on a file system that does not support
-            // Alternate Data Streams, like FAT32, thus we don't report this
-            // specific error.
-            if (!(ex instanceof OS.File.Error) || ex.winLastError != 123) {
-              Cu.reportError(ex);
-            }
-          }
-        }
-      }
-#endif
-
+    try {
       gDownloadPlatform.downloadDone(NetUtil.newURI(aDownload.source.url),
                                      new FileUtils.File(aDownload.target.path),
-                                     aDownload.contentType,
-                                     aDownload.source.isPrivate);
+                                     aDownload.contentType, aDownload.source.isPrivate);
       this.downloadDoneCalled = true;
-    }.bind(this));
+      return Promise.resolve();
+    } catch(ex) {
+      return Promise.reject(ex);
+    }
   },
 
   /**
    * Determines whether it's a Windows Metro app.
    */
   _isImmersiveProcess: function() {
     // TODO: to be implemented
     return false;
@@ -466,36 +427,33 @@ this.DownloadIntegration = {
    *           launched.
    * @rejects  JavaScript exception if there was an error trying to launch
    *           the file.
    */
   launchDownload: function (aDownload) {
     let deferred = Task.spawn(function DI_launchDownload_task() {
       let file = new FileUtils.File(aDownload.target.path);
 
-#ifndef XP_WIN
-      // Ask for confirmation if the file is executable, except on Windows where
-      // the operating system will show the prompt based on the security zone.
-      // We do this here, instead of letting the caller handle the prompt
-      // separately in the user interface layer, for two reasons.  The first is
-      // because of its security nature, so that add-ons cannot forget to do
-      // this check.  The second is that the system-level security prompt would
-      // be displayed at launch time in any case.
+      // Ask for confirmation if the file is executable.  We do this here,
+      // instead of letting the caller handle the prompt separately in the user
+      // interface layer, for two reasons.  The first is because of its security
+      // nature, so that add-ons cannot forget to do this check.  The second is
+      // that the system-level security prompt, if enabled, would be displayed
+      // at launch time in any case.
       if (file.isExecutable() && !this.dontOpenFileAndFolder) {
         // We don't anchor the prompt to a specific window intentionally, not
         // only because this is the same behavior as the system-level prompt,
         // but also because the most recently active window is the right choice
         // in basically all cases.
         let shouldLaunch = yield DownloadUIHelper.getPrompter()
                                    .confirmLaunchExecutable(file.path);
         if (!shouldLaunch) {
           return;
         }
       }
-#endif
 
       // In case of a double extension, like ".tar.gz", we only
       // consider the last one, because the MIME service cannot
       // handle multiple extensions.
       let fileExtension = null, mimeInfo = null;
       let match = file.leafName.match(/\.([^.]+)$/);
       if (match) {
         fileExtension = match[1];
--- a/toolkit/components/jsdownloads/src/DownloadLegacy.js
+++ b/toolkit/components/jsdownloads/src/DownloadLegacy.js
@@ -86,31 +86,26 @@ DownloadLegacyTransfer.prototype = {
     if (!Components.isSuccessCode(aStatus)) {
       this._componentFailed = true;
     }
 
     if ((aStateFlags & Ci.nsIWebProgressListener.STATE_START) &&
         (aStateFlags & Ci.nsIWebProgressListener.STATE_IS_NETWORK)) {
       // The main request has just started.  Wait for the associated Download
       // object to be available before notifying.
-      this._deferDownload.promise.then(download => {
-        download.saver.onTransferStarted(
-                         aRequest,
-                         this._cancelable instanceof Ci.nsIHelperAppLauncher);
+      this._deferDownload.promise.then(function (aDownload) {
+        aDownload.saver.onTransferStarted(aRequest);
       }).then(null, Cu.reportError);
     } else if ((aStateFlags & Ci.nsIWebProgressListener.STATE_STOP) &&
         (aStateFlags & Ci.nsIWebProgressListener.STATE_IS_NETWORK)) {
       // The last file has been received, or the download failed.  Wait for the
       // associated Download object to be available before notifying.
-      this._deferDownload.promise.then(download => {
-        download.saver.onTransferFinished(aRequest, aStatus);
+      this._deferDownload.promise.then(function DLT_OSC_onDownload(aDownload) {
+        aDownload.saver.onTransferFinished(aRequest, aStatus);
       }).then(null, Cu.reportError);
-
-      // Release the reference to the component executing the download.
-      this._cancelable = null;
     }
   },
 
   onProgressChange: function DLT_onProgressChange(aWebProgress, aRequest,
                                                   aCurSelfProgress,
                                                   aMaxSelfProgress,
                                                   aCurTotalProgress,
                                                   aMaxTotalProgress)
@@ -164,18 +159,16 @@ DownloadLegacyTransfer.prototype = {
   },
 
   //////////////////////////////////////////////////////////////////////////////
   //// nsITransfer
 
   init: function DLT_init(aSource, aTarget, aDisplayName, aMIMEInfo, aStartTime,
                           aTempFile, aCancelable, aIsPrivate)
   {
-    this._cancelable = aCancelable;
-
     let launchWhenSucceeded = false, contentType = null, launcherPath = null;
 
     if (aMIMEInfo instanceof Ci.nsIMIMEInfo) {
       launchWhenSucceeded =
                 aMIMEInfo.preferredAction != Ci.nsIMIMEInfo.saveToDisk;
       contentType = aMIMEInfo.type;
 
       let appHandler = aMIMEInfo.preferredApplicationHandler;
@@ -236,22 +229,16 @@ DownloadLegacyTransfer.prototype = {
 
   /**
    * This deferred object contains a promise that is resolved with the Download
    * object associated with this nsITransfer instance, when it is available.
    */
   _deferDownload: null,
 
   /**
-   * Reference to the component that is executing the download.  This component
-   * allows cancellation through its nsICancelable interface.
-   */
-  _cancelable: null,
-
-  /**
    * Indicates that the component that executes the download has notified a
    * failure condition.  In this case, we should never use the component methods
    * that cancel the download.
    */
   _componentFailed: false,
 };
 
 ////////////////////////////////////////////////////////////////////////////////
--- a/toolkit/components/jsdownloads/test/unit/common_test_Download.js
+++ b/toolkit/components/jsdownloads/test/unit/common_test_Download.js
@@ -1671,65 +1671,8 @@ add_task(function test_platform_integrat
     });
 
     // Then, wait for the promise returned by "start" to be resolved.
     yield promiseDownloadStopped(download);
 
     yield promiseVerifyContents(download.target.path, TEST_DATA_SHORT);
   }
 });
-
-/**
- * Checks that downloads are added to browsing history when they start.
- */
-add_task(function test_history()
-{
-  mustInterruptResponses();
-
-  // We will wait for the visit to be notified during the download.
-  yield promiseClearHistory();
-  let promiseVisit = promiseWaitForVisit(httpUrl("interruptible.txt"));
-
-  // Start a download that is not allowed to finish yet.
-  let download = yield promiseStartDownload(httpUrl("interruptible.txt"));
-
-  // The history notifications should be received before the download completes.
-  let [time, transitionType] = yield promiseVisit;
-  do_check_eq(time, download.startTime.getTime() * 1000);
-  do_check_eq(transitionType, Ci.nsINavHistoryService.TRANSITION_DOWNLOAD);
-
-  // Restart and complete the download after clearing history.
-  yield promiseClearHistory();
-  download.cancel();
-  continueResponses();
-  yield download.start();
-
-  // The restart should not have added a new history visit.
-  do_check_false(yield promiseIsURIVisited(httpUrl("interruptible.txt")));
-});
-
-/**
- * Checks that downloads started by nsIHelperAppService are added to the
- * browsing history when they start.
- */
-add_task(function test_history_tryToKeepPartialData()
-{
-  // We will wait for the visit to be notified during the download.
-  yield promiseClearHistory();
-  let promiseVisit =
-      promiseWaitForVisit(httpUrl("interruptible_resumable.txt"));
-
-  // Start a download that is not allowed to finish yet.
-  let beforeStartTimeMs = Date.now();
-  let download = yield promiseStartDownload_tryToKeepPartialData();
-
-  // The history notifications should be received before the download completes.
-  let [time, transitionType] = yield promiseVisit;
-  do_check_eq(transitionType, Ci.nsINavHistoryService.TRANSITION_DOWNLOAD);
-
-  // The time set by nsIHelperAppService may be different than the start time in
-  // the download object, thus we only check that it is a meaningful time.
-  do_check_true(time >= beforeStartTimeMs * 1000);
-
-  // Complete the download before finishing the test.
-  continueResponses();
-  yield promiseDownloadStopped(download);
-});
--- a/toolkit/components/jsdownloads/test/unit/head.js
+++ b/toolkit/components/jsdownloads/test/unit/head.js
@@ -165,111 +165,16 @@ function promiseExecuteSoon()
 function promiseTimeout(aTime)
 {
   let deferred = Promise.defer();
   do_timeout(aTime, deferred.resolve);
   return deferred.promise;
 }
 
 /**
- * Allows waiting for an observer notification once.
- *
- * @param aTopic
- *        Notification topic to observe.
- *
- * @return {Promise}
- * @resolves The array [aSubject, aData] from the observed notification.
- * @rejects Never.
- */
-function promiseTopicObserved(aTopic)
-{
-  let deferred = Promise.defer();
-
-  Services.obs.addObserver(
-    function PTO_observe(aSubject, aTopic, aData) {
-      Services.obs.removeObserver(PTO_observe, aTopic);
-      deferred.resolve([aSubject, aData]);
-    }, aTopic, false);
-
-  return deferred.promise;
-}
-
-/**
- * Clears history asynchronously.
- *
- * @return {Promise}
- * @resolves When history has been cleared.
- * @rejects Never.
- */
-function promiseClearHistory()
-{
-  let promise = promiseTopicObserved(PlacesUtils.TOPIC_EXPIRATION_FINISHED);
-  do_execute_soon(function() PlacesUtils.bhistory.removeAllPages());
-  return promise;
-}
-
-/**
- * Waits for a new history visit to be notified for the specified URI.
- *
- * @param aUrl
- *        String containing the URI that will be visited.
- *
- * @return {Promise}
- * @resolves Array [aTime, aTransitionType] from nsINavHistoryObserver.onVisit.
- * @rejects Never.
- */
-function promiseWaitForVisit(aUrl)
-{
-  let deferred = Promise.defer();
-
-  let uri = NetUtil.newURI(aUrl);
-
-  PlacesUtils.history.addObserver({
-    QueryInterface: XPCOMUtils.generateQI([Ci.nsINavHistoryObserver]),
-    onBeginUpdateBatch: function () {},
-    onEndUpdateBatch: function () {},
-    onVisit: function (aURI, aVisitID, aTime, aSessionID, aReferringID,
-                       aTransitionType, aGUID, aHidden) {
-      if (aURI.equals(uri)) {
-        PlacesUtils.history.removeObserver(this);
-        deferred.resolve([aTime, aTransitionType]);
-      }
-    },
-    onTitleChanged: function () {},
-    onDeleteURI: function () {},
-    onClearHistory: function () {},
-    onPageChanged: function () {},
-    onDeleteVisits: function () {},
-  }, false);
-
-  return deferred.promise;
-}
-
-/**
- * Check browsing history to see whether the given URI has been visited.
- *
- * @param aUrl
- *        String containing the URI that will be visited.
- *
- * @return {Promise}
- * @resolves Boolean indicating whether the URI has been visited.
- * @rejects JavaScript exception.
- */
-function promiseIsURIVisited(aUrl) {
-  let deferred = Promise.defer();
-
-  PlacesUtils.asyncHistory.isURIVisited(NetUtil.newURI(aUrl),
-    function (aURI, aIsVisited) {
-      deferred.resolve(aIsVisited);
-    });
-
-  return deferred.promise;
-}
-
-/**
  * Creates a new Download object, setting a temporary file as the target.
  *
  * @param aSourceUrl
  *        String containing the URI for the download source, or null to use
  *        httpUrl("source.txt").
  *
  * @return {Promise}
  * @resolves The newly created Download object.
@@ -532,16 +437,50 @@ function promiseVerifyContents(aPath, aE
       }
       deferred.resolve();
     });
     yield deferred.promise;
   });
 }
 
 /**
+ * Adds entry for download.
+ *
+ * @param aSourceUrl
+ *        String containing the URI for the download source, or null to use
+ *        httpUrl("source.txt").
+ *
+ * @return {Promise}
+ * @rejects JavaScript exception.
+ */
+function promiseAddDownloadToHistory(aSourceUrl) {
+  let deferred = Promise.defer();
+  PlacesUtils.asyncHistory.updatePlaces(
+    {
+      uri: NetUtil.newURI(aSourceUrl || httpUrl("source.txt")),
+      visits: [{
+        transitionType: Ci.nsINavHistoryService.TRANSITION_DOWNLOAD,
+        visitDate:  Date.now()
+      }]
+    },
+    {
+      handleError: function handleError(aResultCode, aPlaceInfo) {
+        let ex = new Components.Exception("Unexpected error in adding visits.",
+                                          aResultCode);
+        deferred.reject(ex);
+      },
+      handleResult: function () {},
+      handleCompletion: function handleCompletion() {
+        deferred.resolve();
+      }
+    });
+  return deferred.promise;
+}
+
+/**
  * Starts a socket listener that closes each incoming connection.
  *
  * @returns nsIServerSocket that listens for connections.  Call its "close"
  *          method to stop listening and free the server port.
  */
 function startFakeServer()
 {
   let serverSocket = new ServerSocket(-1, true, -1);
--- a/toolkit/components/jsdownloads/test/unit/test_DownloadList.js
+++ b/toolkit/components/jsdownloads/test/unit/test_DownloadList.js
@@ -5,72 +5,16 @@
 
 /**
  * Tests the DownloadList object.
  */
 
 "use strict";
 
 ////////////////////////////////////////////////////////////////////////////////
-//// Globals
-
-/**
- * Returns a PRTime in the past usable to add expirable visits.
- *
- * @note Expiration ignores any visit added in the last 7 days, but it's
- *       better be safe against DST issues, by going back one day more.
- */
-function getExpirablePRTime()
-{
-  let dateObj = new Date();
-  // Normalize to midnight
-  dateObj.setHours(0);
-  dateObj.setMinutes(0);
-  dateObj.setSeconds(0);
-  dateObj.setMilliseconds(0);
-  dateObj = new Date(dateObj.getTime() - 8 * 86400000);
-  return dateObj.getTime() * 1000;
-}
-
-/**
- * Adds an expirable history visit for a download.
- *
- * @param aSourceUrl
- *        String containing the URI for the download source, or null to use
- *        httpUrl("source.txt").
- *
- * @return {Promise}
- * @rejects JavaScript exception.
- */
-function promiseExpirableDownloadVisit(aSourceUrl)
-{
-  let deferred = Promise.defer();
-  PlacesUtils.asyncHistory.updatePlaces(
-    {
-      uri: NetUtil.newURI(aSourceUrl || httpUrl("source.txt")),
-      visits: [{
-        transitionType: Ci.nsINavHistoryService.TRANSITION_DOWNLOAD,
-        visitDate: getExpirablePRTime(),
-      }]
-    },
-    {
-      handleError: function handleError(aResultCode, aPlaceInfo) {
-        let ex = new Components.Exception("Unexpected error in adding visits.",
-                                          aResultCode);
-        deferred.reject(ex);
-      },
-      handleResult: function () {},
-      handleCompletion: function handleCompletion() {
-        deferred.resolve();
-      }
-    });
-  return deferred.promise;
-}
-
-////////////////////////////////////////////////////////////////////////////////
 //// Tests
 
 /**
  * Checks the testing mechanism used to build different download lists.
  */
 add_task(function test_construction()
 {
   let downloadListOne = yield promiseNewDownloadList();
@@ -256,72 +200,71 @@ add_task(function test_notifications_thi
   do_check_true(receivedOnDownloadRemoved);
 });
 
 /**
  * Checks that download is removed on history expiration.
  */
 add_task(function test_history_expiration()
 {
-  mustInterruptResponses();
-
   function cleanup() {
     Services.prefs.clearUserPref("places.history.expiration.max_pages");
   }
   do_register_cleanup(cleanup);
 
   // Set max pages to 0 to make the download expire.
   Services.prefs.setIntPref("places.history.expiration.max_pages", 0);
 
+  // Add expirable visit for downloads.
+  yield promiseAddDownloadToHistory();
+  yield promiseAddDownloadToHistory(httpUrl("interruptible.txt"));
+
   let list = yield promiseNewDownloadList();
   let downloadOne = yield promiseNewDownload();
   let downloadTwo = yield promiseNewDownload(httpUrl("interruptible.txt"));
+  list.add(downloadOne);
+  list.add(downloadTwo);
 
   let deferred = Promise.defer();
   let removeNotifications = 0;
   let downloadView = {
     onDownloadRemoved: function (aDownload) {
       if (++removeNotifications == 2) {
         deferred.resolve();
       }
     },
   };
   list.addView(downloadView);
 
-  // Work with one finished download and one canceled download.
+  // Start download one.
   yield downloadOne.start();
+
+  // Start download two and then cancel it.
   downloadTwo.start();
   yield downloadTwo.cancel();
 
-  // We must replace the visits added while executing the downloads with visits
-  // that are older than 7 days, otherwise they will not be expired.
-  yield promiseClearHistory();
-  yield promiseExpirableDownloadVisit();
-  yield promiseExpirableDownloadVisit(httpUrl("interruptible.txt"));
-
-  // After clearing history, we can add the downloads to be removed to the list.
-  list.add(downloadOne);
-  list.add(downloadTwo);
-
   // Force a history expiration.
   let expire = Cc["@mozilla.org/places/expiration;1"]
                  .getService(Ci.nsIObserver);
   expire.observe(null, "places-debug-start-expiration", -1);
 
-  // Wait for both downloads to be removed.
   yield deferred.promise;
 
   cleanup();
 });
 
 /**
  * Checks all downloads are removed after clearing history.
  */
 add_task(function test_history_clear()
 {
+  // Add expirable visit for downloads.
+  yield promiseAddDownloadToHistory();
+  yield promiseAddDownloadToHistory();
+
   let list = yield promiseNewDownloadList();
   let downloadOne = yield promiseNewDownload();
   let downloadTwo = yield promiseNewDownload();
   list.add(downloadOne);
   list.add(downloadTwo);
 
   let deferred = Promise.defer();
   let removeNotifications = 0;
@@ -332,19 +275,18 @@ add_task(function test_history_clear()
       }
     },
   };
   list.addView(downloadView);
 
   yield downloadOne.start();
   yield downloadTwo.start();
 
-  yield promiseClearHistory();
+  PlacesUtils.history.removeAllPages();
 
-  // Wait for the removal notifications that may still be pending.
   yield deferred.promise;
 });
 
 /**
  * Tests the removeFinished method to ensure that it only removes
  * finished downloads.
  */
 add_task(function test_removeFinished()
--- a/toolkit/components/social/FrameWorker.jsm
+++ b/toolkit/components/social/FrameWorker.jsm
@@ -122,22 +122,26 @@ WorkerHandle.prototype = {
   // browser element.
   terminate: function terminate() {
     let url = this._worker.options.url;
     if (!(url in workerCache)) {
       // terminating an already terminated worker - ignore it
       return;
     }
     delete workerCache[url];
+    // close all the ports we have handed out.
+    for (let [portid, port] of this._worker.ports) {
+      port.close();
+    }
+    this._worker.ports.clear();
+    this._worker.ports = null;
     this._worker.browserPromise.then(browser => {
       browser.parentNode.removeChild(browser);
     });
     // wipe things out just incase other reference have snuck out somehow...
-    this._worker.ports.clear();
-    this._worker.ports = null;
     this._worker.browserPromise = null;
     this._worker = null;
   }
 };
 
 // The port that lives in the parent chrome process.  The other end of this
 // port is the "client" port in the content process, which itself is just a
 // shim which shuttles messages to/from the worker itself.
--- a/toolkit/components/thumbnails/BackgroundPageThumbs.jsm
+++ b/toolkit/components/thumbnails/BackgroundPageThumbs.jsm
@@ -1,20 +1,32 @@
 /* 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/. */
 
+/**
+ * WARNING: BackgroundPageThumbs.jsm is currently excluded from release builds.
+ * If you use it, you must also exclude your caller when RELEASE_BUILD is
+ * defined, as described here:
+ * https://wiki.mozilla.org/Platform/Channel-specific_build_defines
+ */
+
 const EXPORTED_SYMBOLS = [
   "BackgroundPageThumbs",
 ];
 
 const DEFAULT_CAPTURE_TIMEOUT = 30000; // ms
 const DESTROY_BROWSER_TIMEOUT = 60000; // ms
 const FRAME_SCRIPT_URL = "chrome://global/content/backgroundPageThumbsContent.js";
 
+// If a request for a thumbnail comes in and we find one that is "stale"
+// (or don't find one at all) we automatically queue a request to generate a
+// new one.
+const MAX_THUMBNAIL_AGE_SECS = 172800; // 2 days == 60*60*24*2 == 172800 secs.
+
 const TELEMETRY_HISTOGRAM_ID_PREFIX = "FX_THUMBNAILS_BG_";
 
 // possible FX_THUMBNAILS_BG_CAPTURE_DONE_REASON telemetry values
 const TEL_CAPTURE_DONE_OK = 0;
 const TEL_CAPTURE_DONE_TIMEOUT = 1;
 // 2 and 3 were used when we had special handling for private-browsing.
 
 const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
@@ -27,16 +39,21 @@ Cu.import("resource://gre/modules/Servic
 
 const BackgroundPageThumbs = {
 
   /**
    * Asynchronously captures a thumbnail of the given URL.
    *
    * The page is loaded anonymously, and plug-ins are disabled.
    *
+   * WARNING: BackgroundPageThumbs.jsm is currently excluded from release
+   * builds.  If you use it, you must also exclude your caller when
+   * RELEASE_BUILD is defined, as described here:
+   * https://wiki.mozilla.org/Platform/Channel-specific_build_defines
+   *
    * @param url      The URL to capture.
    * @param options  An optional object that configures the capture.  Its
    *                 properties are the following, and all are optional:
    * @opt onDone     A function that will be asynchronously called when the
    *                 capture is complete or times out.  It's called as
    *                   onDone(url),
    *                 where `url` is the captured URL.
    * @opt timeout    The capture will time out after this many milliseconds have
@@ -65,16 +82,47 @@ const BackgroundPageThumbs = {
     }
     let cap = new Capture(url, this._onCaptureOrTimeout.bind(this), options);
     this._captureQueue.push(cap);
     this._capturesByURL.set(url, cap);
     this._processCaptureQueue();
   },
 
   /**
+   * Checks if an existing thumbnail for the specified URL is either missing
+   * or stale, and if so, queues a background request to capture it.  That
+   * capture process will send a notification via the observer service on
+   * capture, so consumers should watch for such observations if they want to
+   * be notified of an updated thumbnail.
+   *
+   * WARNING: BackgroundPageThumbs.jsm is currently excluded from release
+   * builds.  If you use it, you must also exclude your caller when
+   * RELEASE_BUILD is defined, as described here:
+   * https://wiki.mozilla.org/Platform/Channel-specific_build_defines
+   *
+   * @param url      The URL to capture.
+   * @param options  An optional object that configures the capture.  See
+   *                 capture() for description.
+   */
+  captureIfStale: function PageThumbs_captureIfStale(url, options={}) {
+    PageThumbsStorage.isFileRecentForURL(url, MAX_THUMBNAIL_AGE_SECS).then(
+      result => {
+        if (result.ok) {
+          if (options.onDone)
+            options.onDone(url);
+          return;
+        }
+        this.capture(url, options);
+      }, err => {
+        if (options.onDone)
+          options.onDone(url);
+      });
+  },
+
+  /**
    * Ensures that initialization of the thumbnail browser's parent window has
    * begun.
    *
    * @return  True if the parent window is completely initialized and can be
    *          used, and false if initialization has started but not completed.
    */
   _ensureParentWindowReady: function () {
     if (this._parentWin)
--- a/toolkit/components/thumbnails/PageThumbs.jsm
+++ b/toolkit/components/thumbnails/PageThumbs.jsm
@@ -12,21 +12,16 @@ const Ci = Components.interfaces;
 
 const HTML_NAMESPACE = "http://www.w3.org/1999/xhtml";
 const PREF_STORAGE_VERSION = "browser.pagethumbnails.storage_version";
 const LATEST_STORAGE_VERSION = 3;
 
 const EXPIRATION_MIN_CHUNK_SIZE = 50;
 const EXPIRATION_INTERVAL_SECS = 3600;
 
-// If a request for a thumbnail comes in and we find one that is "stale"
-// (or don't find one at all) we automatically queue a request to generate a
-// new one.
-const MAX_THUMBNAIL_AGE_SECS = 172800; // 2 days == 60*60*24*2 == 172800 secs.
-
 /**
  * Name of the directory in the profile that contains the thumbnails.
  */
 const THUMBNAIL_DIRECTORY = "thumbnails";
 
 /**
  * The default background color for page thumbnails.
  */
@@ -193,42 +188,16 @@ this.PageThumbs = {
     * @param aUrl The web page's url.
     * @return The path of the thumbnail file.
     */
    getThumbnailPath: function PageThumbs_getThumbnailPath(aUrl) {
      return PageThumbsStorage.getFilePathForURL(aUrl);
    },
 
   /**
-   * Checks if an existing thumbnail for the specified URL is either missing
-   * or stale, and if so, queues a background request to capture it.  That
-   * capture process will send a notification via the observer service on
-   * capture, so consumers should watch for such observations if they want to
-   * be notified of an updated thumbnail.
-   *
-   * @return {Promise} that's resolved on completion.
-   */
-  captureIfStale: function PageThumbs_captureIfStale(aUrl) {
-    let deferredResult = Promise.defer();
-    let filePath = PageThumbsStorage.getFilePathForURL(aUrl);
-    PageThumbsWorker.post(
-      "isFileRecent",
-      [filePath, MAX_THUMBNAIL_AGE_SECS]
-    ).then(result => {
-      if (!result.ok) {
-        // Sadly there is currently a circular dependency between this module
-        // and BackgroundPageThumbs, so do the import locally.
-        let BPT = Cu.import("resource://gre/modules/BackgroundPageThumbs.jsm", {}).BackgroundPageThumbs;
-        BPT.capture(aUrl, {onDone: deferredResult.resolve});
-      }
-    });
-    return deferredResult.promise;
-  },
-
-  /**
    * Captures a thumbnail for the given window.
    * @param aWindow The DOM window to capture a thumbnail from.
    * @param aCallback The function to be called when the thumbnail has been
    *                  captured. The first argument will be the data stream
    *                  containing the image data.
    */
   capture: function PageThumbs_capture(aWindow, aCallback) {
     if (!this._prefEnabled()) {
@@ -621,16 +590,21 @@ this.PageThumbsStorage = {
    * false.
    *
    * @return {Promise}
    */
   touchIfExists: function Storage_touchIfExists(aURL) {
     return PageThumbsWorker.post("touchIfExists", [this.getFilePathForURL(aURL)]);
   },
 
+  isFileRecentForURL: function Storage_isFileRecentForURL(aURL, aMaxSecs) {
+    return PageThumbsWorker.post("isFileRecent",
+                                 [this.getFilePathForURL(aURL), aMaxSecs]);
+  },
+
   _calculateMD5Hash: function Storage_calculateMD5Hash(aValue) {
     let hash = gCryptoHash;
     let value = gUnicodeConverter.convertToByteArray(aValue);
 
     hash.init(hash.MD5);
     hash.update(value, value.length);
     return this._convertToHexString(hash.finish(false));
   },
--- a/toolkit/components/thumbnails/jar.mn
+++ b/toolkit/components/thumbnails/jar.mn
@@ -1,6 +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/.
 
 toolkit.jar:
+#ifndef RELEASE_BUILD
 + content/global/backgroundPageThumbsContent.js (content/backgroundPageThumbsContent.js)
+#endif
--- a/toolkit/components/thumbnails/moz.build
+++ b/toolkit/components/thumbnails/moz.build
@@ -7,13 +7,14 @@
 TEST_DIRS += ['test']
 
 EXTRA_COMPONENTS += [
     'BrowserPageThumbs.manifest',
     'PageThumbsProtocol.js',
 ]
 
 EXTRA_JS_MODULES += [
-    'BackgroundPageThumbs.jsm',
     'PageThumbs.jsm',
     'PageThumbsWorker.js',
 ]
 
+if not CONFIG['RELEASE_BUILD']:
+    EXTRA_JS_MODULES += ['BackgroundPageThumbs.jsm']
--- a/toolkit/components/thumbnails/test/Makefile.in
+++ b/toolkit/components/thumbnails/test/Makefile.in
@@ -1,24 +1,29 @@
 # 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/.
 
 MOCHITEST_BROWSER_FILES := \
-	browser_thumbnails_background.js \
 	browser_thumbnails_capture.js \
 	browser_thumbnails_expiration.js \
 	browser_thumbnails_privacy.js \
 	browser_thumbnails_redirect.js \
 	browser_thumbnails_storage.js \
 	browser_thumbnails_storage_migrate3.js \
 	browser_thumbnails_bug726727.js \
 	browser_thumbnails_bug727765.js \
 	browser_thumbnails_bug818225.js \
-	browser_thumbnails_update.js \
 	head.js \
 	background_red.html \
 	background_red_scroll.html \
 	background_red_redirect.sjs \
 	privacy_cache_control.sjs \
+	$(NULL)
+
+ifndef RELEASE_BUILD
+MOCHITEST_BROWSER_FILES += \
+	browser_thumbnails_background.js \
+	browser_thumbnails_update.js \
 	thumbnails_background.sjs \
 	thumbnails_update.sjs \
 	$(NULL)
+endif
--- a/toolkit/components/thumbnails/test/browser_thumbnails_update.js
+++ b/toolkit/components/thumbnails/test/browser_thumbnails_update.js
@@ -1,15 +1,22 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 /**
- * These tests check the auto-update facility of the thumbnail service.
+ * These tests check the auto-update facility of the background thumbnail
+ * service.
  */
 
+const imports = {};
+Cu.import("resource://gre/modules/BackgroundPageThumbs.jsm", imports);
+registerCleanupFunction(function () {
+  imports.BackgroundPageThumbs._destroy();
+});
+
 function runTests() {
   // A "trampoline" - a generator that iterates over sub-iterators
   let tests = [
     simpleCaptureTest,
     errorResponseUpdateTest,
     goodResponseUpdateTest,
     foregroundErrorResponseUpdateTest,
     foregroundGoodResponseUpdateTest
@@ -63,22 +70,22 @@ function simpleCaptureTest() {
   // Capture the screenshot.
   PageThumbs.captureAndStore(browser, function () {
     // done with the tab.
     gBrowser.removeTab(gBrowser.selectedTab);
     // We've got a capture so should have seen the observer.
     is(numNotifications, 1, "got notification of item being created.");
     // The capture is now "fresh" - so requesting the URL should not cause
     // a new capture.
-    PageThumbs.captureIfStale(URL);
+    imports.BackgroundPageThumbs.captureIfStale(URL);
     is(numNotifications, 1, "still only 1 notification of item being created.");
 
     ensureThumbnailStale(URL);
     // Ask for it to be updated.
-    PageThumbs.captureIfStale(URL);
+    imports.BackgroundPageThumbs.captureIfStale(URL);
     // But it's async, so wait - our observer above will call next() when
     // the notification comes.
   });
   yield undefined // wait for callbacks to call 'next'...
 }
 
 /* Check functionality of a background capture when there is an error response
    from the server.
@@ -94,23 +101,23 @@ function errorResponseUpdateTest() {
   // The b/g service should (a) not save the thumbnail and (b) update the file
   // to have an mtime of "now" - so we (a) check the thumbnail remains green
   // and (b) check the mtime of the file is >= now.
   ensureThumbnailStale(URL);
   // now() returns a higher-precision value than the modified time of a file.
   // As we set the thumbnail very stale, allowing 1 second of "slop" here
   // works around this while still keeping the test valid.
   let now = Date.now() - 1000 ;
-  PageThumbs.captureIfStale(URL).then(() => {
+  imports.BackgroundPageThumbs.captureIfStale(URL, { onDone: () => {
     ok(getThumbnailModifiedTime(URL) >= now, "modified time should be >= now");
     retrieveImageDataForURL(URL, function ([r, g, b]) {
       is("" + [r,g,b], "" + [0, 255, 0], "thumbnail is still green");
       next();
     });
-  }).then(null, err => {ok(false, "Error in captureIfStale: " + err)});
+  }});
   yield undefined; // wait for callback to call 'next'...
 }
 
 /* Check functionality of a background capture when there is a non-error
    response from the server.  This test is somewhat redundant - although it is
    using a http:// URL instead of a data: url like most others.
  */
 function goodResponseUpdateTest() {
@@ -122,25 +129,25 @@ function goodResponseUpdateTest() {
   // update the thumbnail to be stale, then re-request it.  The server will
   // return a 200 response and a red thumbnail - so that new thumbnail should
   // end up captured.
   ensureThumbnailStale(URL);
   // now() returns a higher-precision value than the modified time of a file.
   // As we set the thumbnail very stale, allowing 1 second of "slop" here
   // works around this while still keeping the test valid.
   let now = Date.now() - 1000 ;
-  PageThumbs.captureIfStale(URL).then(() => {
+  imports.BackgroundPageThumbs.captureIfStale(URL, { onDone: () => {
     ok(getThumbnailModifiedTime(URL) >= now, "modified time should be >= now");
     // the captureIfStale request saw a 200 response with the red body, so we
     // expect to see the red version here.
     retrieveImageDataForURL(URL, function ([r, g, b]) {
       is("" + [r,g,b], "" + [255, 0, 0], "thumbnail is now red");
       next();
     });
-  }).then(null, err => {ok(false, "Error in captureIfStale: " + err)});
+  }});
   yield undefined; // wait for callback to call 'next'...
 }
 
 /* Check functionality of a foreground capture when there is an error response
    from the server.
  */
 function foregroundErrorResponseUpdateTest() {
   const URL = "http://mochi.test:8888/browser/toolkit/components/thumbnails/test/thumbnails_update.sjs?fail";
--- a/toolkit/devtools/server/actors/script.js
+++ b/toolkit/devtools/server/actors/script.js
@@ -711,16 +711,220 @@ ThreadActor.prototype = {
     } catch(e) {
       reportError(e, "Got an exception during TA__pauseAndRespond: ");
     }
 
     return undefined;
   },
 
   /**
+   * Handle resume requests that include a forceCompletion request.
+   *
+   * @param Object aRequest
+   *        The request packet received over the RDP.
+   * @returns A response packet.
+   */
+  _forceCompletion: function TA__forceCompletion(aRequest) {
+    // TODO: remove this when Debugger.Frame.prototype.pop is implemented in
+    // bug 736733.
+    return {
+      error: "notImplemented",
+      message: "forced completion is not yet implemented."
+    };
+  },
+
+  _makeOnEnterFrame: function TA__makeOnEnterFrame({ pauseAndRespond }) {
+    return aFrame => {
+      const generatedLocation = getFrameLocation(aFrame);
+      let { url } = this.synchronize(this.sources.getOriginalLocation(
+        generatedLocation));
+
+      return this.sources.isBlackBoxed(url)
+        ? undefined
+        : pauseAndRespond(aFrame);
+    };
+  },
+
+  _makeOnPop: function TA__makeOnPop({ thread, pauseAndRespond, createValueGrip }) {
+    return function (aCompletion) {
+      // onPop is called with 'this' set to the current frame.
+
+      const generatedLocation = getFrameLocation(this);
+      const { url } = thread.synchronize(thread.sources.getOriginalLocation(
+        generatedLocation));
+
+      if (thread.sources.isBlackBoxed(url)) {
+        return undefined;
+      }
+
+      // Note that we're popping this frame; we need to watch for
+      // subsequent step events on its caller.
+      this.reportedPop = true;
+
+      return pauseAndRespond(this, aPacket => {
+        aPacket.why.frameFinished = {};
+        if (!aCompletion) {
+          aPacket.why.frameFinished.terminated = true;
+        } else if (aCompletion.hasOwnProperty("return")) {
+          aPacket.why.frameFinished.return = createValueGrip(aCompletion.return);
+        } else if (aCompletion.hasOwnProperty("yield")) {
+          aPacket.why.frameFinished.return = createValueGrip(aCompletion.yield);
+        } else {
+          aPacket.why.frameFinished.throw = createValueGrip(aCompletion.throw);
+        }
+        return aPacket;
+      });
+    };
+  },
+
+  _makeOnStep: function TA__makeOnStep({ thread, pauseAndRespond, startFrame,
+                                         startLocation }) {
+    return function () {
+      // onStep is called with 'this' set to the current frame.
+
+      const generatedLocation = getFrameLocation(this);
+      const newLocation = thread.synchronize(thread.sources.getOriginalLocation(
+        generatedLocation));
+
+      // Cases when we should pause because we have executed enough to consider
+      // a "step" to have occured:
+      //
+      // 1.1. We change frames.
+      // 1.2. We change URLs (can happen without changing frames thanks to
+      //      source mapping).
+      // 1.3. We change lines.
+      //
+      // Cases when we should always continue execution, even if one of the
+      // above cases is true:
+      //
+      // 2.1. We are in a source mapped region, but inside a null mapping
+      //      (doesn't correlate to any region of original source)
+      // 2.2. The source we are in is black boxed.
+
+      // Cases 2.1 and 2.2
+      if (newLocation.url == null
+          || thread.sources.isBlackBoxed(newLocation.url)) {
+        return undefined;
+      }
+
+      // Cases 1.1, 1.2 and 1.3
+      if (this !== startFrame
+          || startLocation.url !== newLocation.url
+          || startLocation.line !== newLocation.line) {
+        return pauseAndRespond(this);
+      }
+
+      // Otherwise, let execution continue (we haven't executed enough code to
+      // consider this a "step" yet).
+      return undefined;
+    };
+  },
+
+  /**
+   * Define the JS hook functions for stepping.
+   */
+  _makeSteppingHooks: function TA__makeSteppingHooks(aStartLocation) {
+    // Bind these methods and state because some of the hooks are called
+    // with 'this' set to the current frame. Rather than repeating the
+    // binding in each _makeOnX method, just do it once here and pass it
+    // in to each function.
+    const steppingHookState = {
+      pauseAndRespond: (aFrame, onPacket=(k)=>k) => {
+        this._pauseAndRespond(aFrame, { type: "resumeLimit" }, onPacket);
+      },
+      createValueGrip: this.createValueGrip.bind(this),
+      thread: this,
+      startFrame: this.youngestFrame,
+      startLocation: aStartLocation
+    };
+
+    return {
+      onEnterFrame: this._makeOnEnterFrame(steppingHookState),
+      onPop: this._makeOnPop(steppingHookState),
+      onStep: this._makeOnStep(steppingHookState)
+    };
+  },
+
+  /**
+   * Handle attaching the various stepping hooks we need to attach when we
+   * receive a resume request with a resumeLimit property.
+   *
+   * @param Object aRequest
+   *        The request packet received over the RDP.
+   * @returns A promise that resolves to true once the hooks are attached, or is
+   *          rejected with an error packet.
+   */
+  _handleResumeLimit: function TA__handleResumeLimit(aRequest) {
+    let steppingType = aRequest.resumeLimit.type;
+    if (["step", "next", "finish"].indexOf(steppingType) == -1) {
+      return reject({ error: "badParameterType",
+                      message: "Unknown resumeLimit type" });
+    }
+
+    const generatedLocation = getFrameLocation(this.youngestFrame);
+    return this.sources.getOriginalLocation(generatedLocation)
+      .then(originalLocation => {
+        const { onEnterFrame, onPop, onStep } = this._makeSteppingHooks(originalLocation);
+
+        // Make sure there is still a frame on the stack if we are to continue
+        // stepping.
+        let stepFrame = this._getNextStepFrame(this.youngestFrame);
+        if (stepFrame) {
+          switch (steppingType) {
+            case "step":
+              this.dbg.onEnterFrame = onEnterFrame;
+              // Fall through.
+            case "next":
+              stepFrame.onStep = onStep;
+              stepFrame.onPop = onPop;
+              break;
+            case "finish":
+              stepFrame.onPop = onPop;
+          }
+        }
+
+        return true;
+      });
+  },
+
+  /**
+   * Clear the onStep and onPop hooks from the given frame and all of the frames
+   * below it.
+   *
+   * @param Debugger.Frame aFrame
+   *        The frame we want to clear the stepping hooks from.
+   */
+  _clearSteppingHooks: function TA__clearSteppingHooks(aFrame) {
+    while (aFrame) {
+      aFrame.onStep = undefined;
+      aFrame.onPop = undefined;
+      aFrame = aFrame.older;
+    }
+  },
+
+  /**
+   * Listen to the debuggee's DOM events if we received a request to do so.
+   *
+   * @param Object aRequest
+   *        The resume request packet received over the RDP.
+   */
+  _maybeListenToEvents: function TA__maybeListenToEvents(aRequest) {
+    // Break-on-DOMEvents is only supported in content debugging.
+    let events = aRequest.pauseOnDOMEvents;
+    if (this.global && events &&
+        (events == "*" ||
+        (Array.isArray(events) && events.length))) {
+      this._pauseOnDOMEvents = events;
+      let els = Cc["@mozilla.org/eventlistenerservice;1"]
+                .getService(Ci.nsIEventListenerService);
+      els.addListenerForAllEvents(this.global, this._allEventsListener, true);
+    }
+  },
+
+  /**
    * Handle a protocol request to resume execution of the debuggee.
    */
   onResume: function TA_onResume(aRequest) {
     if (this._state !== "paused") {
       return {
         error: "wrongState",
         message: "Can't resume when debuggee isn't paused. Current state is '"
           + this._state + "'"
@@ -735,175 +939,33 @@ ThreadActor.prototype = {
       return {
         error: "wrongOrder",
         message: "trying to resume in the wrong order.",
         lastPausedUrl: this._nestedEventLoops.lastPausedUrl
       };
     }
 
     if (aRequest && aRequest.forceCompletion) {
-      // TODO: remove this when Debugger.Frame.prototype.pop is implemented in
-      // bug 736733.
-      if (typeof this.frame.pop != "function") {
-        return { error: "notImplemented",
-                 message: "forced completion is not yet implemented." };
-      }
-
-      this.dbg.getNewestFrame().pop(aRequest.completionValue);
-      let packet = this._resumed();
-      this._popThreadPause();
-      return { type: "resumeLimit", frameFinished: aRequest.forceCompletion };
+      return this._forceCompletion(aRequest);
     }
 
     let resumeLimitHandled;
     if (aRequest && aRequest.resumeLimit) {
-      // Bind these methods because some of the hooks are called with 'this'
-      // set to the current frame.
-      let pauseAndRespond = (aFrame, onPacket=function (k) k) => {
-        this._pauseAndRespond(aFrame, { type: "resumeLimit" }, onPacket);
-      };
-      let createValueGrip = this.createValueGrip.bind(this);
-
-      let startFrame = this.youngestFrame;
-      const generatedLocation = getFrameLocation(this.youngestFrame);
-      resumeLimitHandled = this.sources.getOriginalLocation(generatedLocation)
-        .then((startLocation) => {
-          // Define the JS hook functions for stepping.
-
-          let onEnterFrame = aFrame => {
-            const generatedLocation = getFrameLocation(aFrame);
-            let { url } = this.synchronize(this.sources.getOriginalLocation(
-              generatedLocation));
-
-            return this.sources.isBlackBoxed(url)
-              ? undefined
-              : pauseAndRespond(aFrame);
-          };
-
-          let thread = this;
-
-          let onPop = function TA_onPop(aCompletion) {
-            // onPop is called with 'this' set to the current frame.
-
-            const generatedLocation = getFrameLocation(this);
-            let { url } = thread.synchronize(thread.sources.getOriginalLocation(
-              generatedLocation));
-
-            if (thread.sources.isBlackBoxed(url)) {
-              return undefined;
-            }
-
-            // Note that we're popping this frame; we need to watch for
-            // subsequent step events on its caller.
-            this.reportedPop = true;
-
-            return pauseAndRespond(this, aPacket => {
-              aPacket.why.frameFinished = {};
-              if (!aCompletion) {
-                aPacket.why.frameFinished.terminated = true;
-              } else if (aCompletion.hasOwnProperty("return")) {
-                aPacket.why.frameFinished.return = createValueGrip(aCompletion.return);
-              } else if (aCompletion.hasOwnProperty("yield")) {
-                aPacket.why.frameFinished.return = createValueGrip(aCompletion.yield);
-              } else {
-                aPacket.why.frameFinished.throw = createValueGrip(aCompletion.throw);
-              }
-              return aPacket;
-            });
-          };
-
-          let onStep = function TA_onStep() {
-            // onStep is called with 'this' set to the current frame.
-
-            const generatedLocation = getFrameLocation(this);
-            const newLocation = thread.synchronize(
-              thread.sources.getOriginalLocation(generatedLocation));
-
-            // Cases when we should pause because we have executed enough to
-            // consider a "step" to have occured:
-            //
-            // 1.1. We change frames.
-            // 1.2. We change URLs (can happen without changing frames thanks to
-            //      source mapping).
-            // 1.3. We change lines.
-            //
-            // Cases when we should always continue execution, even if one of the
-            // above cases is true:
-            //
-            // 2.1. We are in a source mapped region, but inside a null mapping
-            //      (doesn't correlate to any region of original source)
-            // 2.2. The source we are in is black boxed.
-
-            // Cases 2.1 and 2.2
-            if (newLocation.url == null
-                || thread.sources.isBlackBoxed(newLocation.url)) {
-              return undefined;
-            }
-
-            // Cases 1.1, 1.2 and 1.3
-            if (this !== startFrame
-                || startLocation.url !== newLocation.url
-                || startLocation.line !== newLocation.line) {
-              return pauseAndRespond(this);
-            }
-
-            // Otherwise, let execution continue (we haven't executed enough code to
-            // consider this a "step" yet).
-            return undefined;
-          };
-
-          let steppingType = aRequest.resumeLimit.type;
-          if (["step", "next", "finish"].indexOf(steppingType) == -1) {
-            throw { error: "badParameterType",
-                    message: "Unknown resumeLimit type" };
-          }
-          // Make sure there is still a frame on the stack if we are to continue
-          // stepping.
-          let stepFrame = this._getNextStepFrame(startFrame);
-          if (stepFrame) {
-            switch (steppingType) {
-              case "step":
-                this.dbg.onEnterFrame = onEnterFrame;
-                // Fall through.
-              case "next":
-                stepFrame.onStep = onStep;
-                stepFrame.onPop = onPop;
-                break;
-              case "finish":
-                stepFrame.onPop = onPop;
-            }
-          }
-          return true;
-        });
+      resumeLimitHandled = this._handleResumeLimit(aRequest)
     } else {
-      // Clear any previous stepping hooks on a plain resumption.
-      let frame = this.youngestFrame;
-      while (frame) {
-        frame.onStep = undefined;
-        frame.onPop = undefined;
-        frame = frame.older;
-      }
+      this._clearSteppingHooks(this.youngestFrame);
       resumeLimitHandled = resolve(true);
     }
 
     return resumeLimitHandled.then(() => {
       if (aRequest) {
         this._options.pauseOnExceptions = aRequest.pauseOnExceptions;
         this._options.ignoreCaughtExceptions = aRequest.ignoreCaughtExceptions;
         this.maybePauseOnExceptions();
-        // Break-on-DOMEvents is only supported in content debugging.
-        let events = aRequest.pauseOnDOMEvents;
-        if (this.global && events &&
-            (events == "*" ||
-             (Array.isArray(events) && events.length))) {
-          this._pauseOnDOMEvents = events;
-          let els = Cc["@mozilla.org/eventlistenerservice;1"]
-            .getService(Ci.nsIEventListenerService);
-          els.addListenerForAllEvents(this.global, this._allEventsListener, true);
-        }
+        this._maybeListenToEvents(aRequest);
       }
 
       let packet = this._resumed();
       this._popThreadPause();
       return packet;
     }, error => {
       return error instanceof Error
         ? { error: "unknownError",