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 id25260
push userryanvm@gmail.com
push dateWed, 11 Sep 2013 00:29:30 +0000
treeherdermozilla-central@f73bed2856a8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone26.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
merge 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",