merge mozilla-central to fx-team. r=merge a=merge
authorSebastian Hengst <archaeopteryx@coole-files.de>
Mon, 22 Aug 2016 17:33:19 +0200
changeset 336325 3b7148db9a79bb17fd85df31690c98ffb5c8a541
parent 336324 95e17b89b51955aabf9986ef9f2f973053630579 (current diff)
parent 336319 78b89cc4c3d3f09f73077d02cb6cae7bae0e07c3 (diff)
child 336326 81c452fd0a01dae174f8981907467791d06f6af7
push id10033
push userraliiev@mozilla.com
push dateMon, 19 Sep 2016 13:50:26 +0000
treeherdermozilla-aurora@5dddbefdf759 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge, merge
milestone51.0a1
merge mozilla-central to fx-team. r=merge a=merge
b2g/components/MobileIdentityUIGlue.js
b2g/components/PaymentGlue.js
b2g/components/PaymentProviderStrategy.js
dom/mobileid/MobileIdentity.js
dom/mobileid/MobileIdentity.manifest
dom/mobileid/interfaces/moz.build
dom/mobileid/interfaces/nsIMobileIdentityService.idl
dom/mobileid/moz.build
dom/mobileid/test/mochitest.ini
dom/mobileid/test/test_mobileid_basics.html
dom/mobileid/test/test_mobileid_no_permission.html
dom/payment/Payment.js
dom/payment/Payment.jsm
dom/payment/Payment.manifest
dom/payment/PaymentFlowInfo.js
dom/payment/PaymentProvider.js
dom/payment/PaymentProviderUtils.cpp
dom/payment/PaymentProviderUtils.h
dom/payment/interfaces/moz.build
dom/payment/interfaces/nsIPaymentContentHelperService.idl
dom/payment/interfaces/nsIPaymentFlowInfo.idl
dom/payment/interfaces/nsIPaymentProviderStrategy.idl
dom/payment/interfaces/nsIPaymentUIGlue.idl
dom/payment/moz.build
dom/payment/tests/mochitest/MockPaymentsUIChromeScript.js
dom/payment/tests/mochitest/file_mozpayproviderchecker.html
dom/payment/tests/mochitest/file_payproviderfailure.html
dom/payment/tests/mochitest/file_payprovidersuccess.html
dom/payment/tests/mochitest/mochitest.ini
dom/payment/tests/mochitest/test_mozpay_callbacks.html
dom/payment/tests/mochitest/test_mozpaymentprovider.html
dom/payment/tests/unit/header_helper.js
dom/payment/tests/unit/test_paymanager_get_payment_request.js
dom/payment/tests/unit/xpcshell.ini
dom/webidl/MozPaymentProvider.webidl
dom/workers/test/test_bug1241485.html
mobile/android/tests/browser/robocop/roboextender/base/paymentsUI.html
mobile/android/tests/browser/robocop/src/org/mozilla/gecko/tests/testMozPay.java
mobile/android/tests/browser/robocop/testMozPay.js
services/mobileid/MobileIdentityClient.jsm
services/mobileid/MobileIdentityCommon.jsm
services/mobileid/MobileIdentityCredentialsStore.jsm
services/mobileid/MobileIdentityManager.jsm
services/mobileid/MobileIdentitySmsMoMtVerificationFlow.jsm
services/mobileid/MobileIdentitySmsMtVerificationFlow.jsm
services/mobileid/MobileIdentitySmsVerificationFlow.jsm
services/mobileid/MobileIdentityUIGlueCommon.jsm
services/mobileid/MobileIdentityVerificationFlow.jsm
services/mobileid/interfaces/moz.build
services/mobileid/interfaces/nsIMobileIdentityUIGlue.idl
services/mobileid/moz.build
services/mobileid/tests/xpcshell/head.js
services/mobileid/tests/xpcshell/test_mobileid_client.js
services/mobileid/tests/xpcshell/test_mobileid_manager.js
services/mobileid/tests/xpcshell/test_mobileid_verification_flow.js
services/mobileid/tests/xpcshell/xpcshell.ini
--- a/b2g/app/b2g.js
+++ b/b2g/app/b2g.js
@@ -462,19 +462,16 @@ pref("dom.mozPermissionSettings.enabled"
 
 // controls if we want camera support
 pref("device.camera.enabled", true);
 pref("media.realtime_decoder.enabled", true);
 
 // TCPSocket
 pref("dom.mozTCPSocket.enabled", true);
 
-// WebPayment
-pref("dom.mozPay.enabled", true);
-
 // "Preview" landing of bug 710563, which is bogged down in analysis
 // of talos regression.  This is a needed change for higher-framerate
 // CSS animations, and incidentally works around an apparent bug in
 // our handling of requestAnimationFrame() listeners, which are
 // supposed to enable this REPEATING_PRECISE_CAN_SKIP behavior.  The
 // secondary bug isn't really worth investigating since it's obseleted
 // by bug 710563.
 pref("layout.frame_rate.precise", true);
@@ -1006,19 +1003,16 @@ pref("layout.accessiblecaret.use_long_ta
 
 // Hide carets and text selection dialog during scrolling.
 pref("layout.accessiblecaret.always_show_when_scrolling", false);
 
 // Enable sync and mozId with Firefox Accounts.
 pref("services.sync.fxaccounts.enabled", true);
 pref("identity.fxaccounts.enabled", true);
 
-// Mobile Identity API.
-pref("services.mobileid.server.uri", "https://msisdn.services.mozilla.com");
-
 pref("identity.fxaccounts.remote.oauth.uri", "https://oauth.accounts.firefox.com/v1");
 pref("identity.fxaccounts.remote.profile.uri", "https://profile.accounts.firefox.com/v1");
 
 // Disable Firefox Accounts device registration until bug 1238895 is fixed.
 pref("identity.fxaccounts.skipDeviceRegistration", true);
 
 // Enable mapped array buffer.
 pref("dom.mapped_arraybuffer.enabled", true);
--- a/b2g/chrome/content/shell.js
+++ b/b2g/chrome/content/shell.js
@@ -4,17 +4,16 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 window.performance.mark('gecko-shell-loadstart');
 
 Cu.import('resource://gre/modules/ContactService.jsm');
 Cu.import('resource://gre/modules/AlarmService.jsm');
 Cu.import('resource://gre/modules/NotificationDB.jsm');
-Cu.import('resource://gre/modules/Payment.jsm');
 Cu.import("resource://gre/modules/AppsUtils.jsm");
 Cu.import('resource://gre/modules/UserAgentOverrides.jsm');
 Cu.import('resource://gre/modules/Keyboard.jsm');
 Cu.import('resource://gre/modules/ErrorPage.jsm');
 Cu.import('resource://gre/modules/AlertsHelper.jsm');
 Cu.import('resource://gre/modules/SystemUpdateService.jsm');
 
 if (isGonk) {
@@ -23,17 +22,16 @@ if (isGonk) {
 }
 
 // Identity
 Cu.import('resource://gre/modules/SignInToWebsite.jsm');
 SignInToWebsiteController.init();
 
 Cu.import('resource://gre/modules/FxAccountsMgmtService.jsm');
 Cu.import('resource://gre/modules/DownloadsAPI.jsm');
-Cu.import('resource://gre/modules/MobileIdentityManager.jsm');
 Cu.import('resource://gre/modules/PresentationDeviceInfoManager.jsm');
 Cu.import('resource://gre/modules/AboutServiceWorkers.jsm');
 
 XPCOMUtils.defineLazyModuleGetter(this, "SystemAppProxy",
                                   "resource://gre/modules/SystemAppProxy.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "Screenshot",
                                   "resource://gre/modules/Screenshot.jsm");
--- a/b2g/components/B2GComponents.manifest
+++ b/b2g/components/B2GComponents.manifest
@@ -32,22 +32,16 @@ component {1a94c87a-5ece-4d11-91e1-d29c2
 contract @mozilla.org/b2g-process-global;1 {1a94c87a-5ece-4d11-91e1-d29c29f21b28}
 category app-startup ProcessGlobal service,@mozilla.org/b2g-process-global;1
 
 # OMAContentHandler.js
 component {a6b2ab13-9037-423a-9897-dde1081be323} OMAContentHandler.js
 contract @mozilla.org/uriloader/content-handler;1?type=application/vnd.oma.drm.message {a6b2ab13-9037-423a-9897-dde1081be323}
 contract @mozilla.org/uriloader/content-handler;1?type=application/vnd.oma.dd+xml {a6b2ab13-9037-423a-9897-dde1081be323}
 
-# Payments
-component {8b83eabc-7929-47f4-8b48-4dea8d887e4b} PaymentGlue.js
-contract @mozilla.org/payment/ui-glue;1 {8b83eabc-7929-47f4-8b48-4dea8d887e4b}
-component {4834b2e1-2c91-44ea-b020-e2581ed279a4} PaymentProviderStrategy.js
-contract @mozilla.org/payment/provider-strategy;1 {4834b2e1-2c91-44ea-b020-e2581ed279a4}
-
 # TelProtocolHandler.js
 component {782775dd-7351-45ea-aff1-0ffa872cfdd2} TelProtocolHandler.js
 contract @mozilla.org/network/protocol;1?name=tel {782775dd-7351-45ea-aff1-0ffa872cfdd2}
 
 # SmsProtocolHandler.js
 component {81ca20cb-0dad-4e32-8566-979c8998bd73} SmsProtocolHandler.js
 contract @mozilla.org/network/protocol;1?name=sms {81ca20cb-0dad-4e32-8566-979c8998bd73}
 
@@ -97,20 +91,16 @@ contract @mozilla.org/commandlinehandler
 category command-line-handler m-b2gcmds @mozilla.org/commandlinehandler/general-startup;1?type=b2gcmds
 #endif
 
 # BootstrapCommandLine.js
 component {fd663ec8-cf3f-4c2b-aacb-17a6915ccb44} BootstrapCommandLine.js
 contract @mozilla.org/commandlinehandler/general-startup;1?type=b2gbootstrap {fd663ec8-cf3f-4c2b-aacb-17a6915ccb44}
 category command-line-handler m-b2gbootstrap @mozilla.org/commandlinehandler/general-startup;1?type=b2gbootstrap
 
-# MobileIdentityUIGlue.js
-component {83dbe26a-81f3-4a75-9541-3d0b7ca496b5} MobileIdentityUIGlue.js
-contract @mozilla.org/services/mobileid-ui-glue;1 {83dbe26a-81f3-4a75-9541-3d0b7ca496b5}
-
 # B2GAppMigrator.js
 component {7211ece0-b458-4635-9afc-f8d7f376ee95} B2GAppMigrator.js
 contract @mozilla.org/app-migrator;1 {7211ece0-b458-4635-9afc-f8d7f376ee95}
 
 # B2GPresentationDevicePrompt.js
 component {4a300c26-e99b-4018-ab9b-c48cf9bc4de1} B2GPresentationDevicePrompt.js
 contract @mozilla.org/presentation-device/prompt;1 {4a300c26-e99b-4018-ab9b-c48cf9bc4de1}
 
deleted file mode 100644
--- a/b2g/components/MobileIdentityUIGlue.js
+++ /dev/null
@@ -1,162 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict"
-
-const { interfaces: Ci, utils: Cu, classes: Cc } = Components;
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/ContentRequestHelper.jsm");
-Cu.import("resource://gre/modules/MobileIdentityCommon.jsm");
-Cu.import("resource://gre/modules/MobileIdentityUIGlueCommon.jsm");
-Cu.import("resource://gre/modules/Promise.jsm");
-
-XPCOMUtils.defineLazyServiceGetter(this, "uuidgen",
-                                   "@mozilla.org/uuid-generator;1",
-                                   "nsIUUIDGenerator");
-
-XPCOMUtils.defineLazyModuleGetter(this, "SystemAppProxy",
-                                  "resource://gre/modules/SystemAppProxy.jsm");
-
-const CHROME_EVENT = "mozMobileIdChromeEvent";
-const CONTENT_EVENT = "mozMobileIdContentEvent";
-const UNSOLICITED_CONTENT_EVENT = "mozMobileIdUnsolContentEvent";
-
-function MobileIdentityUIGlue() {
-  SystemAppProxy.addEventListener(UNSOLICITED_CONTENT_EVENT, this);
-}
-
-MobileIdentityUIGlue.prototype = {
-
-  __proto__: ContentRequestHelper.prototype,
-
-  _sendChromeEvent: function(aEventName, aData) {
-    SystemAppProxy._sendCustomEvent(CHROME_EVENT, {
-      eventName: aEventName,
-      id: uuidgen.generateUUID().toString(),
-      data: aData
-    });
-  },
-
-  _oncancel: null,
-
-  get oncancel() {
-    return this._oncancel;
-  },
-
-  set oncancel(aCallback) {
-    this._oncancel = aCallback;
-  },
-
-  _onresendcode: null,
-
-  get onresendcode() {
-    return this._onresendcode;
-  },
-
-  set onresendcode(aCallback) {
-    this._onresendcode = aCallback;
-  },
-
-  startFlow: function(aManifestURL, aIccInfo) {
-    let phoneNumberInfo;
-    if (aIccInfo) {
-      phoneNumberInfo = [];
-      for (var i = 0; i < aIccInfo.length; i++) {
-        let iccInfo = aIccInfo[i];
-        phoneNumberInfo.push({
-          primary: iccInfo.primary,
-          msisdn: iccInfo.msisdn,
-          operator: iccInfo.operator,
-          external: iccInfo.external,
-          serviceId: iccInfo.serviceId,
-          mcc: iccInfo.mcc
-        });
-      }
-    }
-
-    return this.contentRequest(CONTENT_EVENT,
-                               CHROME_EVENT,
-                               "onpermissionrequest",
-                               { phoneNumberInfo: phoneNumberInfo || [],
-                                 manifestURL: aManifestURL })
-    .then(
-      (result) => {
-        if (!result || !result.phoneNumber && !result.serviceId) {
-          return Promise.reject(ERROR_INVALID_PROMPT_RESULT);
-        }
-
-        let promptResult = new MobileIdentityUIGluePromptResult(
-          result.phoneNumber || null,
-          result.prefix || null,
-          result.mcc || null,
-          result.serviceId || null
-        );
-        return promptResult;
-      }
-    );
-  },
-
-  verificationCodePrompt: function(aRetriesLeft, aTimeout, aTimeLeft) {
-    return this.contentRequest(CONTENT_EVENT,
-                               CHROME_EVENT,
-                               "onverificationcode",
-                               { retriesLeft: aRetriesLeft,
-                                 verificationTimeout: aTimeout,
-                                 verificationTimeoutLeft: aTimeLeft })
-    .then(
-      (result) => {
-        if (!result || !result.verificationCode) {
-          return Promise.reject(ERROR_INVALID_VERIFICATION_CODE);
-        }
-
-        return result.verificationCode;
-      }
-    );
-  },
-
-  error: function(aError) {
-    log.error("UI error " + aError);
-    this._sendChromeEvent("onerror", {
-      error: aError
-    });
-  },
-
-  verify: function() {
-    this._sendChromeEvent("verify");
-  },
-
-  verified: function(aVerifiedPhoneNumber) {
-    this._sendChromeEvent("onverified", {
-      verifiedPhoneNumber: aVerifiedPhoneNumber
-    });
-  },
-
-  handleEvent: function(aEvent) {
-    let msg = aEvent.detail;
-    if (!msg) {
-      log.warning("Got invalid event");
-      return;
-    }
-    log.debug("Got content event ${}", msg);
-
-    switch(msg.eventName) {
-      case 'cancel':
-        this.oncancel();
-        break;
-      case 'resendcode':
-        this.onresendcode();
-        break;
-      default:
-        log.warning("Invalid event name");
-        break;
-    }
-  },
-
-  classID: Components.ID("{83dbe26a-81f3-4a75-9541-3d0b7ca496b5}"),
-
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsIMobileIdentityUIGlue])
-};
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([MobileIdentityUIGlue]);
deleted file mode 100644
--- a/b2g/components/PaymentGlue.js
+++ /dev/null
@@ -1,202 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/Promise.jsm");
-
-// Type of MozChromEvents to handle payment dialogs.
-const kOpenPaymentConfirmationEvent = "open-payment-confirmation-dialog";
-const kOpenPaymentFlowEvent = "open-payment-flow-dialog";
-const kClosePaymentFlowEvent = "close-payment-flow-dialog";
-
-// Observer notification topic for payment flow cancelation.
-const kPaymentFlowCancelled = "payment-flow-cancelled";
-
-const PREF_DEBUG = "dom.payment.debug";
-
-XPCOMUtils.defineLazyServiceGetter(this, "uuidgen",
-                                   "@mozilla.org/uuid-generator;1",
-                                   "nsIUUIDGenerator");
-
-XPCOMUtils.defineLazyModuleGetter(this, "SystemAppProxy",
-                                  "resource://gre/modules/SystemAppProxy.jsm");
-
-function PaymentUI() {
-  try {
-    this._debug =
-      Services.prefs.getPrefType(PREF_DEBUG) == Ci.nsIPrefBranch.PREF_BOOL
-      && Services.prefs.getBoolPref(PREF_DEBUG);
-  } catch(e) {
-    this._debug = false;
-  }
-}
-
-PaymentUI.prototype = {
-
-  confirmPaymentRequest: function confirmPaymentRequest(aRequestId,
-                                                        aRequests,
-                                                        aSuccessCb,
-                                                        aErrorCb) {
-    let _error = function _error(errorMsg) {
-      if (aErrorCb) {
-        aErrorCb.onresult(aRequestId, errorMsg);
-      }
-    };
-
-    // The UI should listen for mozChromeEvent 'open-payment-confirmation-dialog'
-    // type in order to create and show the payment request confirmation frame
-    // embeded within a trusted dialog.
-    let id = kOpenPaymentConfirmationEvent + "-" + this.getRandomId();
-    let detail = {
-      type: kOpenPaymentConfirmationEvent,
-      id: id,
-      requestId: aRequestId,
-      paymentRequests: aRequests
-    };
-
-    // Once the user confirm the payment request and makes his choice, we get
-    // back to the DOM part to get the appropriate payment flow information
-    // based on the selected payment provider.
-    this._handleSelection = (function _handleSelection(evt) {
-      let msg = evt.detail;
-      if (msg.id != id) {
-        return;
-      }
-
-      if (msg.userSelection && aSuccessCb) {
-        aSuccessCb.onresult(aRequestId, msg.userSelection);
-      } else if (msg.errorMsg) {
-        _error(msg.errorMsg);
-      }
-
-      SystemAppProxy.removeEventListener("mozContentEvent", this._handleSelection);
-      this._handleSelection = null;
-    }).bind(this);
-    SystemAppProxy.addEventListener("mozContentEvent", this._handleSelection);
-
-    SystemAppProxy.dispatchEvent(detail);
-  },
-
-  showPaymentFlow: function showPaymentFlow(aRequestId,
-                                            aPaymentFlowInfo,
-                                            aErrorCb) {
-    let _error = (errorMsg) => {
-      if (aErrorCb) {
-        aErrorCb.onresult(aRequestId, errorMsg);
-      }
-    };
-
-    // We ask the UI to browse to the selected payment flow.
-    let id = kOpenPaymentFlowEvent + "-" + this.getRandomId();
-    let detail = {
-      type: kOpenPaymentFlowEvent,
-      id: id,
-      requestId: aRequestId
-    };
-
-    this._setPaymentRequest = (event) => {
-      let message = event.detail;
-      if (message.id != id) {
-        return;
-      }
-
-      let frame = message.frame;
-      let docshell = frame.contentWindow
-                          .QueryInterface(Ci.nsIInterfaceRequestor)
-                          .getInterface(Ci.nsIWebNavigation)
-                          .QueryInterface(Ci.nsIDocShell);
-      docshell.paymentRequestId = aRequestId;
-      frame.src = aPaymentFlowInfo.uri + aPaymentFlowInfo.jwt;
-      SystemAppProxy.removeEventListener("mozContentEvent",
-                                         this._setPaymentRequest);
-    };
-    SystemAppProxy.addEventListener("mozContentEvent",
-                                    this._setPaymentRequest);
-
-    // We listen for UI notifications about a closed payment flow. The UI
-    // should provide the reason of the closure within the 'errorMsg' parameter
-    this._notifyPayFlowClosed = (evt) => {
-      let msg = evt.detail;
-      if (msg.id != id) {
-        return;
-      }
-
-      if (msg.type != 'cancel') {
-        return;
-      }
-
-      if (msg.errorMsg) {
-        _error(msg.errorMsg);
-      }
-
-      SystemAppProxy.removeEventListener("mozContentEvent",
-                                         this._notifyPayFlowClosed);
-      this._notifyPayFlowClosed = null;
-
-      Services.obs.notifyObservers(null, kPaymentFlowCancelled, null);
-    };
-    SystemAppProxy.addEventListener("mozContentEvent",
-                                    this._notifyPayFlowClosed);
-
-    SystemAppProxy.dispatchEvent(detail);
-  },
-
-  closePaymentFlow: function(aRequestId) {
-    return new Promise((aResolve) => {
-      // After receiving the payment provider confirmation about the
-      // successful or failed payment flow, we notify the UI to close the
-      // payment flow dialog and return to the caller application.
-      let id = kClosePaymentFlowEvent + "-" + uuidgen.generateUUID().toString();
-
-      let detail = {
-        type: kClosePaymentFlowEvent,
-        id: id,
-        requestId: aRequestId
-      };
-
-      // In order to avoid race conditions, we wait for the UI to notify that
-      // it has successfully closed the payment flow and has recovered the
-      // caller app, before notifying the parent process to fire the success
-      // or error event over the DOMRequest.
-      SystemAppProxy.addEventListener("mozContentEvent",
-                                      (function closePaymentFlowReturn() {
-        SystemAppProxy.removeEventListener("mozContentEvent",
-                                    closePaymentFlowReturn);
-        this.cleanup();
-        aResolve();
-      }).bind(this));
-
-      SystemAppProxy.dispatchEvent(detail);
-    });
-  },
-
-  cleanup: function cleanup() {
-    if (this._handleSelection) {
-      SystemAppProxy.removeEventListener("mozContentEvent",
-                                         this._handleSelection);
-      this._handleSelection = null;
-    }
-
-    if (this._notifyPayFlowClosed) {
-      SystemAppProxy.removeEventListener("mozContentEvent",
-                                         this._notifyPayFlowClosed);
-      this._notifyPayFlowClosed = null;
-    }
-  },
-
-  getRandomId: function getRandomId() {
-    return uuidgen.generateUUID().toString();
-  },
-
-  classID: Components.ID("{8b83eabc-7929-47f4-8b48-4dea8d887e4b}"),
-
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsIPaymentUIGlue])
-}
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([PaymentUI]);
deleted file mode 100644
--- a/b2g/components/PaymentProviderStrategy.js
+++ /dev/null
@@ -1,178 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
-
-const PREF_DEBUG = "dom.payment.debug";
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-
-XPCOMUtils.defineLazyServiceGetter(this, "gIccService",
-                                   "@mozilla.org/icc/iccservice;1",
-                                   "nsIIccService");
-
-XPCOMUtils.defineLazyServiceGetter(this, "gRil",
-                                   "@mozilla.org/ril;1",
-                                   "nsIRadioInterfaceLayer");
-
-XPCOMUtils.defineLazyServiceGetter(this, "gSettingsService",
-                                   "@mozilla.org/settingsService;1",
-                                   "nsISettingsService");
-
-const kMozSettingsChangedObserverTopic = "mozsettings-changed";
-const kRilDefaultDataServiceId = "ril.data.defaultServiceId";
-const kRilDefaultPaymentServiceId = "ril.payment.defaultServiceId";
-
-var _debug;
-try {
-  _debug = Services.prefs.getPrefType(PREF_DEBUG) == Ci.nsIPrefBranch.PREF_BOOL
-           && Services.prefs.getBoolPref(PREF_DEBUG);
-} catch(e){
-  _debug = false;
-}
-
-function LOG(s) {
-  if (!_debug) {
-    return;
-  }
-  dump("== Payment Provider == " + s + "\n");
-}
-
-function LOGE(s) {
-  dump("== Payment Provider ERROR == " + s + "\n");
-}
-
-function PaymentSettings() {
-  Services.obs.addObserver(this, kMozSettingsChangedObserverTopic, false);
-
-  [kRilDefaultDataServiceId, kRilDefaultPaymentServiceId].forEach(setting => {
-    gSettingsService.createLock().get(setting, this);
-  });
-}
-
-PaymentSettings.prototype = {
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsISettingsServiceCallback,
-                                         Ci.nsIObserver]),
-
-  dataServiceId: 0,
-  _paymentServiceId: 0,
-
-  get paymentServiceId() {
-    return this._paymentServiceId;
-  },
-
-  set paymentServiceId(serviceId) {
-    // We allow the payment provider to set the service ID that will be used
-    // for the payment process.
-    // This service ID will be the one used by the silent SMS flow.
-    // If the payment is done with an external SIM, the service ID must be set
-    // to null.
-    if (serviceId != null && serviceId >= gRil.numRadioInterfaces) {
-      LOGE("Invalid service ID " + serviceId);
-      return;
-    }
-
-    gSettingsService.createLock().set(kRilDefaultPaymentServiceId,
-                                      serviceId, 0);
-    this._paymentServiceId = serviceId;
-  },
-
-  setServiceId: function(aName, aValue) {
-    switch (aName) {
-      case kRilDefaultDataServiceId:
-        this.dataServiceId = aValue;
-        if (_debug) {
-          LOG("dataServiceId " + this.dataServiceId);
-        }
-        break;
-      case kRilDefaultPaymentServiceId:
-        this._paymentServiceId = aValue;
-        if (_debug) {
-          LOG("paymentServiceId " + this._paymentServiceId);
-        }
-        break;
-    }
-  },
-
-  handle: function(aName, aValue) {
-    if (aName != kRilDefaultDataServiceId) {
-      return;
-    }
-
-    this.setServiceId(aName, aValue);
-  },
-
-  observe: function(aSubject, aTopic, aData) {
-    if (aTopic != kMozSettingsChangedObserverTopic) {
-      return;
-    }
-
-    try {
-      if ("wrappedJSObject" in aSubject) {
-        aSubject = aSubject.wrappedJSObject;
-      }
-      if (!aSubject.key ||
-          (aSubject.key !== kRilDefaultDataServiceId &&
-           aSubject.key !== kRilDefaultPaymentServiceId)) {
-        return;
-      }
-      this.setServiceId(aSubject.key, aSubject.value);
-    } catch (e) {
-      LOGE(e);
-    }
-  },
-
-  cleanup: function() {
-    Services.obs.removeObserver(this, kMozSettingsChangedObserverTopic);
-  }
-};
-
-function PaymentProviderStrategy() {
-  this._settings = new PaymentSettings();
-}
-
-PaymentProviderStrategy.prototype = {
-  get paymentServiceId() {
-    return this._settings.paymentServiceId;
-  },
-
-  set paymentServiceId(aServiceId) {
-    this._settings.paymentServiceId = aServiceId;
-  },
-
-  get iccInfo() {
-    if (!this._iccInfo) {
-      this._iccInfo = [];
-      for (let i = 0; i < gRil.numRadioInterfaces; i++) {
-        let icc = gIccService.getIccByServiceId(i);
-        let info = icc && icc.iccInfo;
-        if (!info) {
-          LOGE("Tried to get the ICC info for an invalid service ID " + i);
-          continue;
-        }
-
-        this._iccInfo.push({
-          iccId: info.iccid,
-          mcc: info.mcc,
-          mnc: info.mnc,
-          dataPrimary: i == this._settings.dataServiceId
-        });
-      }
-    }
-    return this._iccInfo;
-  },
-
-  cleanup: function() {
-    this._settings.cleanup();
-  },
-
-  classID: Components.ID("{4834b2e1-2c91-44ea-b020-e2581ed279a4}"),
-
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsIPaymentProviderStrategy])
-};
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([PaymentProviderStrategy]);
--- a/b2g/components/moz.build
+++ b/b2g/components/moz.build
@@ -12,20 +12,17 @@ EXTRA_COMPONENTS += [
     'B2GAppMigrator.js',
     'B2GPresentationDevicePrompt.js',
     'BootstrapCommandLine.js',
     'ContentPermissionPrompt.js',
     'FilePicker.js',
     'FxAccountsUIGlue.js',
     'HelperAppDialog.js',
     'MailtoProtocolHandler.js',
-    'MobileIdentityUIGlue.js',
     'OMAContentHandler.js',
-    'PaymentGlue.js',
-    'PaymentProviderStrategy.js',
     'PresentationRequestUIGlue.js',
     'ProcessGlobal.js',
     'SmsProtocolHandler.js',
     'SystemMessageInternal.js',
     'TelProtocolHandler.js',
     'WebappsUpdateTimer.js',
 ]
 
--- a/b2g/confvars.sh
+++ b/b2g/confvars.sh
@@ -34,17 +34,16 @@ MOZ_USE_NATIVE_POPUP_WINDOWS=1
 
 MOZ_XULRUNNER=
 
 MOZ_APP_ID={3c2e2abc-06d4-11e1-ac3b-374f68613e61}
 
 MOZ_TIME_MANAGER=1
 
 MOZ_SIMPLEPUSH=1
-MOZ_PAY=1
 MOZ_TOOLKIT_SEARCH=
 MOZ_B2G=1
 
 MOZ_JSDOWNLOADS=1
 
 MOZ_BUNDLED_FONTS=1
 
 export JS_GC_SMALL_CHUNK_SIZE=1
--- a/b2g/graphene/confvars.sh
+++ b/b2g/graphene/confvars.sh
@@ -35,17 +35,16 @@ if test "$OS_TARGET" = "Android"; then
 MOZ_CAPTURE=1
 MOZ_RAW=1
 MOZ_AUDIO_CHANNEL_MANAGER=1
 fi
 
 MOZ_APP_ID={d1bfe7d9-c01e-4237-998b-7b5f960a4314}
 MOZ_TIME_MANAGER=1
 
-MOZ_PAY=1
 MOZ_TOOLKIT_SEARCH=
 MOZ_PLACES=
 MOZ_B2G=1
 
 MOZ_JSDOWNLOADS=1
 
 MOZ_BUNDLED_FONTS=1
 
--- a/b2g/installer/package-manifest.in
+++ b/b2g/installer/package-manifest.in
@@ -181,17 +181,16 @@
 @RESPATH@/components/dom_secureelement.xpt
 #endif
 #ifdef MOZ_NFC
 @RESPATH@/components/dom_nfc.xpt
 #endif
 @RESPATH@/components/dom_notification.xpt
 @RESPATH@/components/dom_html.xpt
 @RESPATH@/components/dom_offline.xpt
-@RESPATH@/components/dom_payment.xpt
 @RESPATH@/components/dom_json.xpt
 @RESPATH@/components/dom_messages.xpt
 @RESPATH@/components/dom_power.xpt
 @RESPATH@/components/dom_push.xpt
 @RESPATH@/components/dom_quota.xpt
 @RESPATH@/components/dom_range.xpt
 @RESPATH@/components/dom_security.xpt
 @RESPATH@/components/dom_settings.xpt
@@ -622,21 +621,16 @@
 @RESPATH@/components/HCIEventTransactionSystemMessage.manifest
 @RESPATH@/components/HCIEventTransactionSystemMessageConfigurator.js
 
 @RESPATH@/components/ActivityProxy.js
 @RESPATH@/components/ActivityRequestHandler.js
 @RESPATH@/components/ActivityWrapper.js
 @RESPATH@/components/ActivityMessageConfigurator.js
 
-@RESPATH@/components/Payment.js
-@RESPATH@/components/PaymentFlowInfo.js
-@RESPATH@/components/PaymentProvider.js
-@RESPATH@/components/Payment.manifest
-
 @RESPATH@/components/DownloadsAPI.js
 @RESPATH@/components/DownloadsAPI.manifest
 
 ; InputMethod API
 @RESPATH@/components/MozKeyboard.js
 @RESPATH@/components/InputMethod.manifest
 #ifdef MOZ_B2G
 @RESPATH@/components/inputmethod.xpt
@@ -868,18 +862,16 @@ bin/libfreebl_32int64_3.so
 @RESPATH@/components/ContentPermissionPrompt.js
 #ifdef MOZ_UPDATER
 @RESPATH@/components/UpdatePrompt.js
 #endif
 @RESPATH@/components/WebappsUpdateTimer.js
 @RESPATH@/components/DirectoryProvider.js
 @RESPATH@/components/ProcessGlobal.js
 @RESPATH@/components/OMAContentHandler.js
-@RESPATH@/components/PaymentGlue.js
-@RESPATH@/components/PaymentProviderStrategy.js
 @RESPATH@/components/RecoveryService.js
 @RESPATH@/components/MailtoProtocolHandler.js
 @RESPATH@/components/SmsProtocolHandler.js
 @RESPATH@/components/TelProtocolHandler.js
 @RESPATH@/components/B2GAboutRedirector.js
 @RESPATH@/components/FilePicker.js
 @RESPATH@/components/HelperAppDialog.js
 @RESPATH@/components/DownloadsUI.js
@@ -890,22 +882,16 @@ bin/libfreebl_32int64_3.so
 
 #ifndef MOZ_WIDGET_GONK
 @RESPATH@/components/SimulatorScreen.js
 #endif
 
 @RESPATH@/components/FxAccountsUIGlue.js
 @RESPATH@/components/services_fxaccounts.xpt
 
-@RESPATH@/components/MobileIdentity.manifest
-@RESPATH@/components/MobileIdentity.js
-@RESPATH@/components/dom_mobileidentity.xpt
-@RESPATH@/components/MobileIdentityUIGlue.js
-@RESPATH@/components/services_mobileidentity.xpt
-
 #ifdef MOZ_WEBSPEECH
 @RESPATH@/components/dom_webspeechsynth.xpt
 #endif
 
 #ifdef XP_MACOSX
 @BINPATH@/@DLL_PREFIX@plugin_child_interpose@DLL_SUFFIX@
 #endif
 
--- a/browser/confvars.sh
+++ b/browser/confvars.sh
@@ -49,18 +49,16 @@ MOZ_APP_ID={ec8030f7-c20a-464f-9b0e-13a3
 # If more than one ID is needed, then you should use a comma separated list
 # of values.
 ACCEPTED_MAR_CHANNEL_IDS=firefox-mozilla-central
 # The MAR_CHANNEL_ID must not contain the following 3 characters: ",\t "
 MAR_CHANNEL_ID=firefox-mozilla-central
 MOZ_PROFILE_MIGRATOR=1
 MOZ_APP_STATIC_INI=1
 MOZ_WEBGL_CONFORMANT=1
-# Enable navigator.mozPay
-MOZ_PAY=1
 MOZ_JSDOWNLOADS=1
 MOZ_RUST_MP4PARSE=1
 
 # Enable checking that add-ons are signed by the trusted root
 MOZ_ADDON_SIGNING=1
 
 # Include the DevTools client, not just the server (which is the default)
 MOZ_DEVTOOLS=all
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -221,17 +221,16 @@
 #ifdef MOZ_WEBSPEECH
 @RESPATH@/components/dom_webspeechrecognition.xpt
 #endif
 @RESPATH@/components/dom_workers.xpt
 @RESPATH@/components/dom_xbl.xpt
 @RESPATH@/components/dom_xhr.xpt
 @RESPATH@/components/dom_xpath.xpt
 @RESPATH@/components/dom_xul.xpt
-@RESPATH@/components/dom_payment.xpt
 @RESPATH@/components/dom_presentation.xpt
 @RESPATH@/components/downloads.xpt
 @RESPATH@/components/editor.xpt
 @RESPATH@/components/embed_base.xpt
 @RESPATH@/components/extensions.xpt
 @RESPATH@/components/exthandler.xpt
 @RESPATH@/components/exthelper.xpt
 @RESPATH@/components/fastfind.xpt
@@ -540,20 +539,16 @@
 @RESPATH@/components/RemoteWebNavigation.js
 
 @RESPATH@/components/SlowScriptDebug.manifest
 @RESPATH@/components/SlowScriptDebug.js
 
 @RESPATH@/components/TVSimulatorService.js
 @RESPATH@/components/TVSimulatorService.manifest
 
-@RESPATH@/components/Payment.js
-@RESPATH@/components/PaymentFlowInfo.js
-@RESPATH@/components/Payment.manifest
-
 #ifdef MOZ_WEBRTC
 @RESPATH@/components/PeerConnection.js
 @RESPATH@/components/PeerConnection.manifest
 #endif
 
 @RESPATH@/chrome/marionette@JAREXT@
 @RESPATH@/chrome/marionette.manifest
 @RESPATH@/components/MarionetteComponents.manifest
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -14553,47 +14553,16 @@ nsDocShell::ChannelIntercepted(nsIInterc
                           isReload, isSubresourceLoad, error);
   if (NS_WARN_IF(error.Failed())) {
     return error.StealNSResult();
   }
 
   return NS_OK;
 }
 
-NS_IMETHODIMP
-nsDocShell::SetPaymentRequestId(const nsAString& aPaymentRequestId)
-{
-  mPaymentRequestId = aPaymentRequestId;
-  return NS_OK;
-}
-
-nsString
-nsDocShell::GetInheritedPaymentRequestId()
-{
-  if (!mPaymentRequestId.IsEmpty()) {
-    return mPaymentRequestId;
-  }
-
-  nsCOMPtr<nsIDocShellTreeItem> parentAsItem;
-  GetSameTypeParent(getter_AddRefs(parentAsItem));
-
-  nsCOMPtr<nsIDocShell> parent = do_QueryInterface(parentAsItem);
-  if (!parent) {
-    return mPaymentRequestId;
-  }
-  return static_cast<nsDocShell*>(parent.get())->GetInheritedPaymentRequestId();
-}
-
-NS_IMETHODIMP
-nsDocShell::GetPaymentRequestId(nsAString& aPaymentRequestId)
-{
-  aPaymentRequestId = GetInheritedPaymentRequestId();
-  return NS_OK;
-}
-
 bool
 nsDocShell::InFrameSwap()
 {
   RefPtr<nsDocShell> shell = this;
   do {
     if (shell->mInFrameSwap) {
       return true;
     }
--- a/docshell/base/nsDocShell.h
+++ b/docshell/base/nsDocShell.h
@@ -1012,20 +1012,16 @@ protected:
 
   // This represents the state of private browsing in the docshell.
   // Currently treated as a binary value: 1 - in private mode, 0 - not private mode
   // On content docshells mPrivateBrowsingId == mOriginAttributes.mPrivateBrowsingId
   // On chrome docshells this value will be set, but not have the corresponding
   // origin attribute set.
   uint32_t mPrivateBrowsingId;
 
-  nsString mPaymentRequestId;
-
-  nsString GetInheritedPaymentRequestId();
-
   nsString mInterceptedDocumentId;
 
 private:
   nsCString mForcedCharset;
   nsCString mParentCharset;
   int32_t mParentCharsetSource;
   nsCOMPtr<nsIPrincipal> mParentCharsetPrincipal;
   nsTObserverArray<nsWeakPtr> mPrivacyObservers;
--- a/docshell/base/nsIDocShell.idl
+++ b/docshell/base/nsIDocShell.idl
@@ -1069,21 +1069,16 @@ interface nsIDocShell : nsIDocShellTreeI
 
   /**
    * This attribute determines whether a document which is not about:blank has
    * already be loaded by this docShell.
    */
   [infallible] readonly attribute boolean hasLoadedNonBlankURI;
 
   /**
-   * Holds the id of the payment request associated with this docshell if any.
-   */
-  attribute DOMString paymentRequestId;
-
-  /**
    * Allow usage of -moz-window-dragging:drag for content docshells.
    * True for top level chrome docshells. Throws if set to false with
    * top level chrome docshell.
    */
   attribute boolean windowDraggingAllowed;
 
   /**
    * Sets/gets the current scroll restoration mode.
--- a/dom/apps/PermissionsTable.jsm
+++ b/dom/apps/PermissionsTable.jsm
@@ -410,21 +410,16 @@ this.PermissionsTable =  { geolocation: 
                              privileged: PROMPT_ACTION,
                              certified: ALLOW_ACTION
                            },
                            "feature-detection": {
                              app: DENY_ACTION,
                              privileged: ALLOW_ACTION,
                              certified: ALLOW_ACTION
                            },
-                           "mobileid": {
-                             app: DENY_ACTION,
-                             privileged: PROMPT_ACTION,
-                             certified: PROMPT_ACTION
-                           },
                            // This permission doesn't actually grant access to
                            // anything. It exists only to check the correctness
                            // of web prompt composed permissions in tests.
                            "test-permission": {
                              app: PROMPT_ACTION,
                              privileged: PROMPT_ACTION,
                              certified: ALLOW_ACTION,
                              access: ["read", "write", "create"]
--- a/dom/base/Navigator.cpp
+++ b/dom/base/Navigator.cpp
@@ -55,19 +55,16 @@
 #include "mozilla/dom/workers/RuntimeService.h"
 #include "mozilla/Hal.h"
 #include "nsISiteSpecificUserAgent.h"
 #include "mozilla/ClearOnShutdown.h"
 #include "mozilla/StaticPtr.h"
 #include "Connection.h"
 #include "mozilla/dom/Event.h" // for nsIDOMEvent::InternalDOMEvent()
 #include "nsGlobalWindow.h"
-#ifdef MOZ_B2G
-#include "nsIMobileIdentityService.h"
-#endif
 #ifdef MOZ_B2G_RIL
 #include "mozilla/dom/MobileConnectionArray.h"
 #endif
 #include "nsIIdleObserver.h"
 #include "nsIPermissionManager.h"
 #include "nsMimeTypes.h"
 #include "nsNetUtil.h"
 #include "nsStringStream.h"
@@ -122,21 +119,16 @@
 #include "mozilla/EMEUtils.h"
 #include "mozilla/DetailedPromise.h"
 #endif
 
 #ifdef MOZ_WIDGET_GONK
 #include <cutils/properties.h>
 #endif
 
-#ifdef MOZ_PAY
-#include "nsIPaymentContentHelperService.h"
-#include "mozilla/dom/DOMRequest.h"
-#endif
-
 namespace mozilla {
 namespace dom {
 
 static bool sVibratorEnabled   = false;
 static uint32_t sMaxVibrateMS  = 0;
 static uint32_t sMaxVibrateListLen = 0;
 static const char* kVibrationPermissionType = "vibration";
 
@@ -1778,23 +1770,16 @@ Navigator::HasFeature(const nsAString& a
       return p.forget();
     }
 
     if (featureName.EqualsLiteral("Navigator.mozCameras")) {
       p->MaybeResolve(true);
       return p.forget();
     }
 
-#ifdef MOZ_B2G
-    if (featureName.EqualsLiteral("Navigator.getMobileIdAssertion")) {
-      p->MaybeResolve(true);
-      return p.forget();
-    }
-#endif
-
     if (featureName.EqualsLiteral("XMLHttpRequest.mozSystem")) {
       p->MaybeResolve(true);
       return p.forget();
     }
 
     p->MaybeResolveWithUndefined();
     return p.forget();
   }
@@ -1904,55 +1889,16 @@ Navigator::GetInputPortManager(ErrorResu
 
 already_AddRefed<LegacyMozTCPSocket>
 Navigator::MozTCPSocket()
 {
   RefPtr<LegacyMozTCPSocket> socket = new LegacyMozTCPSocket(GetWindow());
   return socket.forget();
 }
 
-#ifdef MOZ_B2G
-already_AddRefed<Promise>
-Navigator::GetMobileIdAssertion(const MobileIdOptions& aOptions,
-                                ErrorResult& aRv)
-{
-  if (!mWindow || !mWindow->GetDocShell()) {
-    aRv.Throw(NS_ERROR_UNEXPECTED);
-    return nullptr;
-  }
-
-  nsCOMPtr<nsIMobileIdentityService> service =
-    do_GetService("@mozilla.org/mobileidentity-service;1");
-  if (!service) {
-    aRv.Throw(NS_ERROR_FAILURE);
-    return nullptr;
-  }
-
-  JSContext *cx = nsContentUtils::GetCurrentJSContext();
-  if (!cx) {
-    aRv.Throw(NS_ERROR_FAILURE);
-    return nullptr;
-  }
-
-  JS::Rooted<JS::Value> optionsValue(cx);
-  if (!ToJSValue(cx, aOptions, &optionsValue)) {
-    aRv.Throw(NS_ERROR_FAILURE);
-    return nullptr;
-  }
-
-  nsCOMPtr<nsISupports> promise;
-  aRv = service->GetMobileIdAssertion(mWindow,
-                                      optionsValue,
-                                      getter_AddRefs(promise));
-
-  RefPtr<Promise> p = static_cast<Promise*>(promise.get());
-  return p.forget();
-}
-#endif // MOZ_B2G
-
 #ifdef MOZ_B2G_RIL
 
 MobileConnectionArray*
 Navigator::GetMozMobileConnections(ErrorResult& aRv)
 {
   if (!mMobileConnections) {
     if (!mWindow) {
       aRv.Throw(NS_ERROR_UNEXPECTED);
@@ -2303,83 +2249,30 @@ bool
 Navigator::HasUserMediaSupport(JSContext* /* unused */,
                                JSObject* /* unused */)
 {
   // Make enabling peerconnection enable getUserMedia() as well
   return Preferences::GetBool("media.navigator.enabled", false) ||
          Preferences::GetBool("media.peerconnection.enabled", false);
 }
 
-#ifdef MOZ_B2G
-/* static */
-bool
-Navigator::HasMobileIdSupport(JSContext* aCx, JSObject* aGlobal)
-{
-  nsCOMPtr<nsPIDOMWindowInner> win = GetWindowFromGlobal(aGlobal);
-  if (!win) {
-    return false;
-  }
-
-  nsIDocument* doc = win->GetExtantDoc();
-  if (!doc) {
-    return false;
-  }
-
-  nsIPrincipal* principal = doc->NodePrincipal();
-  uint32_t permission = GetPermission(principal, "mobileid");
-
-  return permission == nsIPermissionManager::PROMPT_ACTION ||
-         permission == nsIPermissionManager::ALLOW_ACTION;
-}
-#endif
-
 /* static */
 bool
 Navigator::IsE10sEnabled(JSContext* aCx, JSObject* aGlobal)
 {
   return XRE_IsContentProcess();
 }
 
 bool
 Navigator::MozE10sEnabled()
 {
   // This will only be called if IsE10sEnabled() is true.
   return true;
 }
 
-#ifdef MOZ_PAY
-already_AddRefed<DOMRequest>
-Navigator::MozPay(JSContext* aCx,
-                  JS::Handle<JS::Value> aJwts,
-                  ErrorResult& aRv)
-{
-  if (!mWindow || !mWindow->GetDocShell()) {
-    aRv.Throw(NS_ERROR_UNEXPECTED);
-    return nullptr;
-  }
-
-  nsresult rv;
-  nsCOMPtr<nsIPaymentContentHelperService> service =
-    do_GetService("@mozilla.org/payment/content-helper-service;1", &rv);
-  if (!service) {
-    aRv.Throw(rv);
-    return nullptr;
-  }
-
-  RefPtr<nsIDOMDOMRequest> request;
-  rv = service->Pay(mWindow, aJwts, getter_AddRefs(request));
-  if (NS_FAILED(rv)) {
-    aRv.Throw(rv);
-    return nullptr;
-  }
-
-  return request.forget().downcast<DOMRequest>();
-}
-#endif // MOZ_PAY
-
 /* static */
 already_AddRefed<nsPIDOMWindowInner>
 Navigator::GetWindowFromGlobal(JSObject* aGlobal)
 {
   nsCOMPtr<nsPIDOMWindowInner> win =
     do_QueryInterface(nsJSUtils::GetStaticScriptGlobal(aGlobal));
   MOZ_ASSERT(!win || win->IsInnerWindow());
   return win.forget();
--- a/dom/base/Navigator.h
+++ b/dom/base/Navigator.h
@@ -34,17 +34,16 @@ class nsIURI;
 namespace mozilla {
 namespace dom {
 class Geolocation;
 class systemMessageCallback;
 class MediaDevices;
 struct MediaStreamConstraints;
 class WakeLock;
 class ArrayBufferViewOrBlobOrStringOrFormData;
-struct MobileIdOptions;
 class ServiceWorkerContainer;
 class DOMRequest;
 struct FlyWebPublishOptions;
 struct FlyWebFilter;
 } // namespace dom
 } // namespace mozilla
 
 //*****************************************************************************
@@ -245,20 +244,16 @@ public:
   Voicemail* GetMozVoicemail(ErrorResult& aRv);
   TVManager* GetTv();
   InputPortManager* GetInputPortManager(ErrorResult& aRv);
   already_AddRefed<LegacyMozTCPSocket> MozTCPSocket();
   network::Connection* GetConnection(ErrorResult& aRv);
   nsDOMCameraManager* GetMozCameras(ErrorResult& aRv);
   MediaDevices* GetMediaDevices(ErrorResult& aRv);
 
-#ifdef MOZ_B2G
-  already_AddRefed<Promise> GetMobileIdAssertion(const MobileIdOptions& options,
-                                                 ErrorResult& aRv);
-#endif
 #ifdef MOZ_B2G_RIL
   MobileConnectionArray* GetMozMobileConnections(ErrorResult& aRv);
 #endif // MOZ_B2G_RIL
 #ifdef MOZ_GAMEPAD
   void GetGamepads(nsTArray<RefPtr<Gamepad> >& aGamepads, ErrorResult& aRv);
   GamepadServiceTest* RequestGamepadServiceTest();
 #endif // MOZ_GAMEPAD
   already_AddRefed<Promise> GetVRDisplays(ErrorResult& aRv);
@@ -294,40 +289,30 @@ public:
                               ErrorResult& aRv);
 
   already_AddRefed<ServiceWorkerContainer> ServiceWorker();
 
   void GetLanguages(nsTArray<nsString>& aLanguages);
 
   bool MozE10sEnabled();
 
-#ifdef MOZ_PAY
-  already_AddRefed<DOMRequest> MozPay(JSContext* aCx,
-                                      JS::Handle<JS::Value> aJwts,
-                                      ErrorResult& aRv);
-#endif // MOZ_PAY
-
   static void GetAcceptLanguages(nsTArray<nsString>& aLanguages);
 
   // WebIDL helper methods
   static bool HasWakeLockSupport(JSContext* /* unused*/, JSObject* /*unused */);
   static bool HasCameraSupport(JSContext* /* unused */,
                                JSObject* aGlobal);
   static bool HasWifiManagerSupport(JSContext* /* unused */,
                                   JSObject* aGlobal);
 #ifdef MOZ_NFC
   static bool HasNFCSupport(JSContext* /* unused */, JSObject* aGlobal);
 #endif // MOZ_NFC
   static bool HasUserMediaSupport(JSContext* /* unused */,
                                   JSObject* /* unused */);
 
-#ifdef MOZ_B2G
-  static bool HasMobileIdSupport(JSContext* aCx, JSObject* aGlobal);
-#endif
-
   static bool IsE10sEnabled(JSContext* aCx, JSObject* aGlobal);
 
   nsPIDOMWindowInner* GetParentObject() const
   {
     return GetWindow();
   }
 
   virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) override;
--- a/dom/base/test/test_hasFeature.html
+++ b/dom/base/test/test_hasFeature.html
@@ -34,17 +34,16 @@ function testAPIs() {
     { name: "Navigator.push", enabled: pref("services.push.enabled") },
     // { name: "Navigator.mozTime", enabled: b2gOnly }, // conditional on MOZ_TIME_MANAGER, tricky to test
     // { name: "Navigator.mozFMRadio", enabled: b2gOnly }, // conditional on MOZ_B2G_FM, tricky to test
     { name: "Navigator.mozCameras", enabled: true },
     { name: "Navigator.mozAlarms", enabled: pref("dom.mozAlarms.enabled") },
     { name: "Navigator.mozTCPSocket", enabled: pref("dom.mozTCPSocket.enabled") },
     { name: "Navigator.mozInputMethod", enabled: pref("dom.mozInputMethod.enabled") },
     { name: "Navigator.mozMobileConnections", enabled: pref("dom.mobileconnection.enabled") },
-    { name: "Navigator.getMobileIdAssertion", enabled: b2gOnly },
     { name: "XMLHttpRequest.mozSystem", enabled: true }
   ];
 
   var promises = [];
   APIEndPoints.forEach(function(v) {
     promises.push(navigator.hasFeature("api.window." + v.name));
   });
 
deleted file mode 100644
--- a/dom/mobileid/MobileIdentity.js
+++ /dev/null
@@ -1,109 +0,0 @@
-/* -*- js-indent-level: 2; indent-tabs-mode: nil -*- */
-/* vim: set ft=javascript 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/. */
-
-"use strict"
-
-const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
-
-Cu.import("resource://gre/modules/DOMRequestHelper.jsm");
-Cu.import("resource://gre/modules/MobileIdentityCommon.jsm");
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-
-const MOBILEIDSERVICE_CID =
-  Components.ID("{6ec1806c-d61f-4724-9495-68c26d46dc53}");
-
-const IPC_MSG_NAMES = ["MobileId:GetAssertion:Return:OK",
-                       "MobileId:GetAssertion:Return:KO"];
-
-XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
-                                   "@mozilla.org/childprocessmessagemanager;1",
-                                   "nsIMessageSender");
-
-function MobileIdentityService() {
-}
-
-MobileIdentityService.prototype = {
-  __proto__: DOMRequestIpcHelper.prototype,
-
-  // TODO: this should be handled by DOMRequestIpcHelper. Bug 1020582
-  _windows: {},
-
-  getMobileIdAssertion: function(aWindow, aOptions) {
-    log.debug("getMobileIdAssertion");
-
-    if (!this.init) {
-      this.initDOMRequestHelper(aWindow, IPC_MSG_NAMES);
-      this.init = true;
-    }
-
-    return new aWindow.Promise(
-      (resolve, reject) => {
-        let promiseId = this.getPromiseResolverId({
-          resolve: resolve,
-          reject: reject
-        });
-
-        this._windows[promiseId] = aWindow;
-
-        cpmm.sendAsyncMessage("MobileId:GetAssertion", {
-          promiseId: promiseId,
-          options: aOptions
-        }, null, aWindow.document.nodePrincipal);
-      }
-    );
-  },
-
-  receiveMessage: function(aMessage) {
-    let name = aMessage.name;
-    let msg = aMessage.json;
-
-    log.debug("Received message " + name + ": " + JSON.stringify(msg));
-
-    let promiseId = msg.promiseId || msg.requestID;
-    let promise = this.takePromiseResolver(promiseId);
-    if (!promise) {
-      log.error("Promise not found");
-      return;
-    }
-
-    let _window = this._windows[promiseId];
-    delete this._windows[promiseId];
-    if (!_window) {
-      log.error("No window object found");
-      return;
-    }
-
-    switch (name) {
-      case "MobileId:GetAssertion:Return:OK":
-        if (!msg.result) {
-          promise.reject(new _window.DOMError(ERROR_INTERNAL_UNEXPECTED));
-        }
-
-        // Return the assertion
-        promise.resolve(msg.result);
-        break;
-      case "MobileId:GetAssertion:Return:KO":
-        promise.reject(new _window.DOMError(msg.error || ERROR_UNKNOWN));
-        break;
-    }
-  },
-
-  classID: MOBILEIDSERVICE_CID,
-
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsIMobileIdentityService,
-                                         Ci.nsISupportsWeakReference,
-                                         Ci.nsIObserver]),
-
-  classInfo: XPCOMUtils.generateCI({
-    classID: MOBILEIDSERVICE_CID,
-    contractID: "@mozilla.org/mobileidentity-service;1",
-    interfaces: [Ci.nsIMobileIdentityService],
-    flags: Ci.nsIClassInfo.SINGLETON
-  })
-
-};
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([MobileIdentityService]);
deleted file mode 100644
--- a/dom/mobileid/MobileIdentity.manifest
+++ /dev/null
@@ -1,2 +0,0 @@
-component {6ec1806c-d61f-4724-9495-68c26d46dc53} MobileIdentity.js
-contract @mozilla.org/mobileidentity-service;1 {6ec1806c-d61f-4724-9495-68c26d46dc53}
deleted file mode 100644
--- a/dom/mobileid/interfaces/moz.build
+++ /dev/null
@@ -1,11 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-XPIDL_SOURCES += [
-    'nsIMobileIdentityService.idl',
-]
-
-XPIDL_MODULE = 'dom_mobileidentity'
deleted file mode 100644
--- a/dom/mobileid/interfaces/nsIMobileIdentityService.idl
+++ /dev/null
@@ -1,14 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "nsISupports.idl"
-
-interface mozIDOMWindow;
-
-[scriptable, uuid(c03d38e3-bae6-4b62-ae96-cf8acc1501ec)]
-interface nsIMobileIdentityService : nsISupports
-{
-  nsISupports getMobileIdAssertion(in mozIDOMWindow window,
-                                   in jsval options);
-};
deleted file mode 100644
--- a/dom/mobileid/moz.build
+++ /dev/null
@@ -1,14 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-DIRS += ['interfaces']
-
-MOCHITEST_MANIFESTS += ['test/mochitest.ini']
-
-EXTRA_COMPONENTS += [
-    'MobileIdentity.js',
-    'MobileIdentity.manifest',
-]
deleted file mode 100644
--- a/dom/mobileid/test/mochitest.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[DEFAULT]
-skip-if = (buildapp != 'b2g')
-
-[test_mobileid_basics.html]
-[test_mobileid_no_permission.html]
deleted file mode 100644
--- a/dom/mobileid/test/test_mobileid_basics.html
+++ /dev/null
@@ -1,78 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-  <title>Test for navigator.getMobileIdAssertion</title>
-  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-</head>
-<body>
-<p id="display"></p>
-<div id="content" style="display: none">
-</div>
-<pre id="test">
-<script type="application/javascript">
-
-const MOCK_CID = SpecialPowers.wrap(SpecialPowers.Components)
-                              .ID("{4cb9b8b3-bc8c-46c0-a2b6-2eb0b1ffce94}");
-const MOBILE_ID_SERVICE_CONTRACT_ID = "@mozilla.org/mobileidentity-service;1";
-
-function finish() {
-  SpecialPowers.wrap(SpecialPowers.Components).manager
-               .QueryInterface(SpecialPowers.Ci.nsIComponentRegistrar)
-               .unregisterFactory(MOCK_CID, mockMobileIdService);
-  SimpleTest.finish();
-}
-
-SimpleTest.waitForExplicitFinish();
-
-var mockMobileIdService = {
-  QueryInterface: function(aIID) {
-    if (SpecialPowers.wrap(aIID).equals(SpecialPowers.Ci.nsISupports) ||
-        SpecialPowers.wrap(aIID).equals(SpecialPowers.Ci.nsIMobileIdentityService)) {
-      return this;
-    }
-    throw SpecialPowers.Components.results.NS_ERROR_NO_INTERFACE;
-  },
-
-  createInstance: function(aOuter, aIID) {
-    if (aOuter != null) {
-      throw SpecialPowers.Components.results.NS_ERROR_NO_AGGREGATION;
-    }
-    return this.QueryInterface(aIID);
-  },
-
-  getMobileIdAssertion: function(aWindow, aOptions) {
-    return new Promise(function(resolve, reject) {
-      resolve(aOptions);
-    });
-  }
-};
-mockMobileIdService = SpecialPowers.wrapCallbackObject(mockMobileIdService);
-
-SpecialPowers.wrap(SpecialPowers.Components).manager
-             .QueryInterface(SpecialPowers.Ci.nsIComponentRegistrar)
-             .registerFactory(MOCK_CID, "mobileid service",
-                              MOBILE_ID_SERVICE_CONTRACT_ID,
-                              mockMobileIdService);
-
-// Tests
-
-SpecialPowers.pushPermissions([{"type": "mobileid",
-                               "allow": 1,
-                               "context": document}], function() {
-  ok("getMobileIdAssertion" in navigator,
-     "navigator.getMobileIdAssertion should exist");
-
-  var options = { forceSelection: true };
-  var promise = navigator.getMobileIdAssertion(options)
-  .then(function(result) {
-    ok(promise instanceof Promise, "Should return a Promise");
-    is(result.forceSelection, options.forceSelection,
-       "MobileIdentityService should receive correct options");
-    finish();
-  });
-});
-</script>
-</pre>
-</body>
-</html>
deleted file mode 100644
--- a/dom/mobileid/test/test_mobileid_no_permission.html
+++ /dev/null
@@ -1,24 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-  <title>Test for navigator.getMobileIdAssertion - No permission</title>
-  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-</head>
-<body>
-<p id="display"></p>
-<div id="content" style="display: none">
-</div>
-<pre id="test">
-<script type="application/javascript">
-
-SimpleTest.waitForExplicitFinish();
-
-ok(!("getMobileIdAssertion" in navigator),
-   "navigator.getMobileIdAssertion should NOT exist");
-
-SimpleTest.finish();
-</script>
-</pre>
-</body>
-</html>
--- a/dom/moz.build
+++ b/dom/moz.build
@@ -127,35 +127,31 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk
         'wifi',
     ]
 
 if CONFIG['MOZ_B2G_RIL']:
     DIRS += [
         'wappush',
     ]
 
-if CONFIG['MOZ_PAY']:
-    DIRS += ['payment']
-
 if CONFIG['MOZ_NFC']:
     DIRS += ['nfc']
 
 if CONFIG['MOZ_SIMPLEPUSH']:
     DIRS += ['simplepush']
 else:
     DIRS += ['push']
 
 if CONFIG['MOZ_SECUREELEMENT']:
     DIRS += ['secureelement']
 
 if CONFIG['MOZ_B2G']:
     DIRS += [
         'downloads',
-        'identity',
-        'mobileid'
+        'identity'
     ]
 
 DIRS += ['presentation']
 
 TEST_DIRS += [
     'tests',
     'imptests',
 ]
deleted file mode 100644
--- a/dom/payment/Payment.js
+++ /dev/null
@@ -1,120 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/DOMRequestHelper.jsm");
-
-const PAYMENT_IPC_MSG_NAMES = ["Payment:Success",
-                               "Payment:Failed"];
-
-const PREF_DEBUG = "dom.payment.debug";
-
-XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
-                                   "@mozilla.org/childprocessmessagemanager;1",
-                                   "nsIMessageSender");
-
-var _debug;
-try {
-  _debug = Services.prefs.getPrefType(PREF_DEBUG) == Ci.nsIPrefBranch.PREF_BOOL
-           && Services.prefs.getBoolPref(PREF_DEBUG);
-} catch(e) {
-  _debug = false;
-}
-
-function LOG(s) {
-  if (!_debug) {
-    return;
-  }
-  dump("-*- PaymentContentHelper: " + s + "\n");
-}
-
-function PaymentContentHelper(aWindow) {
-  this.initDOMRequestHelper(aWindow, PAYMENT_IPC_MSG_NAMES);
-};
-
-PaymentContentHelper.prototype = {
-  __proto__: DOMRequestIpcHelper.prototype,
-
-  receiveMessage: function receiveMessage(aMessage) {
-    let name = aMessage.name;
-    let msg = aMessage.json;
-    if (_debug) {
-      LOG("Received message '" + name + "': " + JSON.stringify(msg));
-    }
-    let requestId = msg.requestId;
-    let request = this.takeRequest(requestId);
-    if (!request) {
-      return;
-    }
-    switch (name) {
-      case "Payment:Success":
-        Services.DOMRequest.fireSuccess(request, msg.result);
-        break;
-      case "Payment:Failed":
-        Services.DOMRequest.fireError(request, msg.errorMsg);
-        break;
-    }
-  },
-};
-
-function PaymentContentHelperService() {
-};
-
-PaymentContentHelperService.prototype = {
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsIPaymentContentHelperService]),
-  classID: Components.ID("{80035846-6732-4fcc-961b-f336b65218f4}"),
-  contractID: "@mozilla.org/payment/content-helper-service;1",
-
-  _xpcom_factory: XPCOMUtils.generateSingletonFactory(PaymentContentHelperService),
-
-  // keys are windows and values are PaymentContentHelpers
-  helpers: new WeakMap(),
-
-  // nsINavigatorPayment
-  pay: function pay(aWindow, aJwts) {
-    let requestHelper = this.helpers.get(aWindow);
-    if (!requestHelper) {
-      requestHelper = new PaymentContentHelper(aWindow);
-      this.helpers.set(aWindow, requestHelper);
-    }
-    let request = requestHelper.createRequest();
-    let requestId = requestHelper.getRequestId(request);
-
-    let docShell = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
-                   .getInterface(Ci.nsIWebNavigation)
-                   .QueryInterface(Ci.nsIDocShell);
-    if (!docShell.isActive) {
-      if (_debug) {
-        LOG("The caller application is a background app. No request will be " +
-            "sent");
-      }
-
-      let runnable = {
-        run: function run() {
-          Services.DOMRequest.fireError(request, "BACKGROUND_APP");
-        }
-      }
-      Services.tm.currentThread.dispatch(runnable,
-                                         Ci.nsIThread.DISPATCH_NORMAL);
-      return request;
-    }
-
-    if (!Array.isArray(aJwts)) {
-      aJwts = [aJwts];
-    }
-
-    cpmm.sendAsyncMessage("Payment:Pay", {
-      jwts: aJwts,
-      requestId: requestId
-    });
-    return request;
-  },
-};
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([PaymentContentHelperService]);
deleted file mode 100644
--- a/dom/payment/Payment.jsm
+++ /dev/null
@@ -1,422 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-
-this.EXPORTED_SYMBOLS = [];
-
-const PAYMENT_IPC_MSG_NAMES = ["Payment:Pay",
-                               "Payment:Success",
-                               "Payment:Failed"];
-
-const PREF_PAYMENTPROVIDERS_BRANCH = "dom.payment.provider.";
-const PREF_PAYMENT_BRANCH = "dom.payment.";
-const PREF_DEBUG = "dom.payment.debug";
-
-XPCOMUtils.defineLazyServiceGetter(this, "ppmm",
-                                   "@mozilla.org/parentprocessmessagemanager;1",
-                                   "nsIMessageListenerManager");
-
-XPCOMUtils.defineLazyServiceGetter(this, "prefService",
-                                   "@mozilla.org/preferences-service;1",
-                                   "nsIPrefService");
-
-var PaymentManager =  {
-  init: function init() {
-    // Payment providers data are stored as a preference.
-    this.registeredProviders = null;
-
-    this.messageManagers = {};
-
-    // The dom.payment.skipHTTPSCheck pref is supposed to be used only during
-    // development process. This preference should not be active for a
-    // production build.
-    let paymentPrefs = prefService.getBranch(PREF_PAYMENT_BRANCH);
-    this.checkHttps = true;
-    try {
-      if (paymentPrefs.getPrefType("skipHTTPSCheck")) {
-        this.checkHttps = !paymentPrefs.getBoolPref("skipHTTPSCheck");
-      }
-    } catch(e) {}
-
-    for (let msgname of PAYMENT_IPC_MSG_NAMES) {
-      ppmm.addMessageListener(msgname, this);
-    }
-
-    Services.obs.addObserver(this, "xpcom-shutdown", false);
-
-    try {
-      this._debug =
-        Services.prefs.getPrefType(PREF_DEBUG) == Ci.nsIPrefBranch.PREF_BOOL
-        && Services.prefs.getBoolPref(PREF_DEBUG);
-    } catch(e) {
-      this._debug = false;
-    }
-  },
-
-  /**
-   * Process a message from the content process.
-   */
-  receiveMessage: function receiveMessage(aMessage) {
-    let name = aMessage.name;
-    let msg = aMessage.json;
-    if (this._debug) {
-      this.LOG("Received '" + name + "' message from content process");
-    }
-
-    switch (name) {
-      case "Payment:Pay": {
-        // First of all, we register the payment providers.
-        if (!this.registeredProviders) {
-          this.registeredProviders = {};
-          this.registerPaymentProviders();
-        }
-
-        // We save the message target message manager so we can later dispatch
-        // back messages without broadcasting to all child processes.
-        let requestId = msg.requestId;
-        this.messageManagers[requestId] = aMessage.target;
-
-        // We check the jwt type and look for a match within the
-        // registered payment providers to get the correct payment request
-        // information.
-        let paymentRequests = [];
-        let jwtTypes = [];
-        for (let i in msg.jwts) {
-          let pr = this.getPaymentRequestInfo(requestId, msg.jwts[i]);
-          if (!pr) {
-            continue;
-          }
-          // We consider jwt type repetition an error.
-          if (jwtTypes[pr.type]) {
-            this.paymentFailed(requestId,
-                               "PAY_REQUEST_ERROR_DUPLICATED_JWT_TYPE");
-            return;
-          }
-          jwtTypes[pr.type] = true;
-          paymentRequests.push(pr);
-        }
-
-        if (!paymentRequests.length) {
-          this.paymentFailed(requestId,
-                             "PAY_REQUEST_ERROR_NO_VALID_REQUEST_FOUND");
-          return;
-        }
-
-        // After getting the list of valid payment requests, we ask the user
-        // for confirmation before sending any request to any payment provider.
-        // If there is more than one choice, we also let the user select the one
-        // that he prefers.
-        let glue = Cc["@mozilla.org/payment/ui-glue;1"]
-                   .createInstance(Ci.nsIPaymentUIGlue);
-        if (!glue) {
-          if (this._debug) {
-            this.LOG("Could not create nsIPaymentUIGlue instance");
-          }
-          this.paymentFailed(requestId,
-                             "INTERNAL_ERROR_CREATE_PAYMENT_GLUE_FAILED");
-          return;
-        }
-
-        let confirmPaymentSuccessCb = function successCb(aRequestId,
-                                                         aResult) {
-          // Get the appropriate payment provider data based on user's choice.
-          let selectedProvider = this.registeredProviders[aResult];
-          if (!selectedProvider || !selectedProvider.uri) {
-            if (this._debug) {
-              this.LOG("Could not retrieve a valid provider based on user's " +
-                        "selection");
-            }
-            this.paymentFailed(aRequestId,
-                               "INTERNAL_ERROR_NO_VALID_SELECTED_PROVIDER");
-            return;
-          }
-
-          let jwt;
-          for (let i in paymentRequests) {
-            if (paymentRequests[i].type == aResult) {
-              jwt = paymentRequests[i].jwt;
-              break;
-            }
-          }
-          if (!jwt) {
-            if (this._debug) {
-              this.LOG("The selected request has no JWT information " +
-                        "associated");
-            }
-            this.paymentFailed(aRequestId,
-                               "INTERNAL_ERROR_NO_JWT_ASSOCIATED_TO_REQUEST");
-            return;
-          }
-
-          this.showPaymentFlow(aRequestId, selectedProvider, jwt);
-        };
-
-        let confirmPaymentErrorCb = this.paymentFailed;
-
-        glue.confirmPaymentRequest(requestId,
-                                   paymentRequests,
-                                   confirmPaymentSuccessCb.bind(this),
-                                   confirmPaymentErrorCb.bind(this));
-        break;
-      }
-      case "Payment:Success":
-      case "Payment:Failed": {
-        let mm = this.messageManagers[msg.requestId];
-        mm.sendAsyncMessage(name, {
-          requestId: msg.requestId,
-          result: msg.result,
-          errorMsg: msg.errorMsg
-        });
-        break;
-      }
-    }
-  },
-
-  /**
-   * Helper function to register payment providers stored as preferences.
-   */
-  registerPaymentProviders: function registerPaymentProviders() {
-    let paymentProviders = prefService
-                           .getBranch(PREF_PAYMENTPROVIDERS_BRANCH)
-                           .getChildList("");
-
-    // First get the numbers of the providers by getting all ###.uri prefs.
-    let nums = [];
-    for (let i in paymentProviders) {
-      let match = /^(\d+)\.uri$/.exec(paymentProviders[i]);
-      if (!match) {
-        continue;
-      } else {
-        nums.push(match[1]);
-      }
-    }
-
-#ifdef MOZ_B2G
-    let appsService = Cc["@mozilla.org/AppsService;1"]
-                        .getService(Ci.nsIAppsService);
-    let systemAppId = Ci.nsIScriptSecurityManager.NO_APP_ID;
-
-    try {
-      let manifestURL = Services.prefs.getCharPref("b2g.system_manifest_url");
-      systemAppId = appsService.getAppLocalIdByManifestURL(manifestURL);
-      this.LOG("System app id=" + systemAppId);
-    } catch(e) {}
-#endif
-
-    // Now register the payment providers.
-    for (let i in nums) {
-      let branch = prefService
-                   .getBranch(PREF_PAYMENTPROVIDERS_BRANCH + nums[i] + ".");
-      let vals = branch.getChildList("");
-      if (vals.length == 0) {
-        return;
-      }
-      try {
-        let type = branch.getCharPref("type");
-        if (type in this.registeredProviders) {
-          continue;
-        }
-        let provider = this.registeredProviders[type] = {
-          name: branch.getCharPref("name"),
-          uri: branch.getCharPref("uri"),
-          description: branch.getCharPref("description"),
-          requestMethod: branch.getCharPref("requestMethod")
-        };
-
-#ifdef MOZ_B2G
-        // Let this payment provider access the firefox-accounts API when
-        // it's loaded in the trusted UI.
-        if (systemAppId != Ci.nsIScriptSecurityManager.NO_APP_ID) {
-          this.LOG("Granting firefox-accounts permission to " + provider.uri);
-          let uri = Services.io.newURI(provider.uri, null, null);
-          let attrs = {appId: systemAppId, inIsolatedMozBrowser: true};
-          let principal =
-            Services.scriptSecurityManager.createCodebasePrincipal(uri, attrs);
-
-          Services.perms.addFromPrincipal(principal, "firefox-accounts",
-                                          Ci.nsIPermissionManager.ALLOW_ACTION,
-                                          Ci.nsIPermissionManager.EXPIRE_SESSION);
-        }
-#endif
-
-        if (this._debug) {
-          this.LOG("Registered Payment Providers: " +
-                    JSON.stringify(this.registeredProviders[type]));
-        }
-      } catch (ex) {
-        if (this._debug) {
-          this.LOG("An error ocurred registering a payment provider. " + ex);
-        }
-      }
-    }
-  },
-
-  /**
-   * Helper for sending a Payment:Failed message to the parent process.
-   */
-  paymentFailed: function paymentFailed(aRequestId, aErrorMsg) {
-    let mm = this.messageManagers[aRequestId];
-    mm.sendAsyncMessage("Payment:Failed", {
-      requestId: aRequestId,
-      errorMsg: aErrorMsg
-    });
-  },
-
-  /**
-   * Helper function to get the payment request info according to the jwt
-   * type. Payment provider's data is stored as a preference.
-   */
-  getPaymentRequestInfo: function getPaymentRequestInfo(aRequestId, aJwt) {
-    if (!aJwt) {
-      this.paymentFailed(aRequestId, "INTERNAL_ERROR_CALL_WITH_MISSING_JWT");
-      return true;
-    }
-
-    // First thing, we check that the jwt type is an allowed type and has a
-    // payment provider flow information associated.
-
-    // A jwt string consists in three parts separated by period ('.'): header,
-    // payload and signature.
-    let segments = aJwt.split('.');
-    if (segments.length !== 3) {
-      if (this._debug) {
-        this.LOG("Error getting payment provider's uri. " +
-                  "Not enough or too many segments");
-      }
-      this.paymentFailed(aRequestId,
-                         "PAY_REQUEST_ERROR_WRONG_SEGMENTS_COUNT");
-      return true;
-    }
-
-    let payloadObject;
-    try {
-      // We only care about the payload segment, which contains the jwt type
-      // that should match with any of the stored payment provider's data and
-      // the payment request information to be shown to the user.
-      // Before decoding the JWT string we need to normalize it to be compliant
-      // with RFC 4648.
-      segments[1] = segments[1].replace(/-/g, "+").replace(/_/g, "/");
-      let payload = atob(segments[1]);
-      if (this._debug) {
-        this.LOG("Payload " + payload);
-      }
-      if (!payload.length) {
-        this.paymentFailed(aRequestId, "PAY_REQUEST_ERROR_EMPTY_PAYLOAD");
-        return true;
-      }
-      payloadObject = JSON.parse(payload);
-      if (!payloadObject) {
-        this.paymentFailed(aRequestId,
-                           "PAY_REQUEST_ERROR_ERROR_PARSING_JWT_PAYLOAD");
-        return true;
-      }
-    } catch (e) {
-      this.paymentFailed(aRequestId,
-                         "PAY_REQUEST_ERROR_ERROR_DECODING_JWT");
-      return true;
-    }
-
-    if (!payloadObject.typ) {
-      this.paymentFailed(aRequestId,
-                         "PAY_REQUEST_ERROR_NO_TYP_PARAMETER");
-      return true;
-    }
-
-    if (!payloadObject.request) {
-      this.paymentFailed(aRequestId,
-                         "PAY_REQUEST_ERROR_NO_REQUEST_PARAMETER");
-      return true;
-    }
-
-    // Once we got the jwt 'typ' value we look for a match within the payment
-    // providers stored preferences. If the jwt 'typ' is not recognized as one
-    // of the allowed values for registered payment providers, we skip the jwt
-    // validation but we don't fire any error. This way developers might have
-    // a default set of well formed JWTs that might be used in different B2G
-    // devices with a different set of allowed payment providers.
-    let provider = this.registeredProviders[payloadObject.typ];
-    if (!provider) {
-      if (this._debug) {
-        this.LOG("Not registered payment provider for jwt type: " +
-                  payloadObject.typ);
-      }
-      return false;
-    }
-
-    if (!provider.uri || !provider.name) {
-      this.paymentFailed(aRequestId,
-                         "INTERNAL_ERROR_WRONG_REGISTERED_PAY_PROVIDER");
-      return true;
-    }
-
-    // We only allow https for payment providers uris.
-    if (this.checkHttps && !/^https/.exec(provider.uri.toLowerCase())) {
-      // We should never get this far.
-      if (this._debug) {
-        this.LOG("Payment provider uris must be https: " + provider.uri);
-      }
-      this.paymentFailed(aRequestId,
-                         "INTERNAL_ERROR_NON_HTTPS_PROVIDER_URI");
-      return true;
-    }
-
-    let pldRequest = payloadObject.request;
-    return { jwt: aJwt, type: payloadObject.typ, providerName: provider.name };
-  },
-
-  showPaymentFlow: function showPaymentFlow(aRequestId,
-                                            aPaymentProvider,
-                                            aJwt) {
-    let paymentFlowInfo = Cc["@mozilla.org/payment/flow-info;1"]
-                          .createInstance(Ci.nsIPaymentFlowInfo);
-    paymentFlowInfo.uri = aPaymentProvider.uri;
-    paymentFlowInfo.requestMethod = aPaymentProvider.requestMethod;
-    paymentFlowInfo.jwt = aJwt;
-    paymentFlowInfo.name = aPaymentProvider.name;
-    paymentFlowInfo.description = aPaymentProvider.description;
-
-    let glue = Cc["@mozilla.org/payment/ui-glue;1"]
-               .createInstance(Ci.nsIPaymentUIGlue);
-    if (!glue) {
-      if (this._debug) {
-        this.LOG("Could not create nsIPaymentUIGlue instance");
-      }
-      this.paymentFailed(aRequestId,
-                         "INTERNAL_ERROR_CREATE_PAYMENT_GLUE_FAILED");
-      return false;
-    }
-    glue.showPaymentFlow(aRequestId,
-                         paymentFlowInfo,
-                         this.paymentFailed.bind(this));
-  },
-
-  // nsIObserver
-
-  observe: function observe(subject, topic, data) {
-    if (topic == "xpcom-shutdown") {
-      for (let msgname of PAYMENT_IPC_MSG_NAMES) {
-        ppmm.removeMessageListener(msgname, this);
-      }
-      this.registeredProviders = null;
-      this.messageManagers = null;
-
-      Services.obs.removeObserver(this, "xpcom-shutdown");
-    }
-  },
-
-  LOG: function LOG(s) {
-    if (!this._debug) {
-      return;
-    }
-    dump("-*- PaymentManager: " + s + "\n");
-  }
-};
-
-PaymentManager.init();
deleted file mode 100644
--- a/dom/payment/Payment.manifest
+++ /dev/null
@@ -1,8 +0,0 @@
-component {80035846-6732-4fcc-961b-f336b65218f4} Payment.js
-contract @mozilla.org/payment/content-helper-service;1 {80035846-6732-4fcc-961b-f336b65218f4}
-
-component {b8bce4e7-fbf0-4719-a634-b1bf9018657c} PaymentFlowInfo.js
-contract @mozilla.org/payment/flow-info;1 {b8bce4e7-fbf0-4719-a634-b1bf9018657c}
-
-component {82144756-72ab-45b7-8621-f3dad431dd2f} PaymentProvider.js
-contract @mozilla.org/payment/provider;1 {82144756-72ab-45b7-8621-f3dad431dd2f}
deleted file mode 100644
--- a/dom/payment/PaymentFlowInfo.js
+++ /dev/null
@@ -1,24 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-
-function PaymentFlowInfo() {
-};
-
-PaymentFlowInfo.prototype = {
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsIPaymentFlowInfo]),
-  classID: Components.ID("{b8bce4e7-fbf0-4719-a634-b1bf9018657c}"),
-  uri: null,
-  jwt: null,
-  requestMethod: null,
-  name: null,
-  description: null
-};
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([PaymentFlowInfo]);
deleted file mode 100644
--- a/dom/payment/PaymentProvider.js
+++ /dev/null
@@ -1,306 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-
-XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
-                                   "@mozilla.org/childprocessmessagemanager;1",
-                                   "nsIMessageSender");
-
-XPCOMUtils.defineLazyServiceGetter(this, "uuidgen",
-                                   "@mozilla.org/uuid-generator;1",
-                                   "nsIUUIDGenerator");
-
-
-const PREF_DEBUG = "dom.payment.debug";
-
-var _debug;
-try {
-  _debug = Services.prefs.getPrefType(PREF_DEBUG) == Ci.nsIPrefBranch.PREF_BOOL
-           && Services.prefs.getBoolPref(PREF_DEBUG);
-} catch(e) {
-  _debug = false;
-}
-
-function DEBUG(s) {
-  if (!_debug) {
-    return;
-  }
-  dump("== Payment Provider == " + s + "\n");
-}
-
-function DEBUG_E(s) {
-  dump("== Payment Provider ERROR == " + s + "\n");
-}
-
-const kPaymentFlowCancelled = "payment-flow-cancelled";
-
-function PaymentProvider() {
-}
-
-PaymentProvider.prototype = {
-  init: function(aWindow) {
-    let docshell = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
-                          .getInterface(Ci.nsIWebNavigation)
-                          .QueryInterface(Ci.nsIDocShell);
-    this._requestId = docshell.paymentRequestId;
-    this._oncancelObserver = this.oncancel.bind(this);
-    Services.obs.addObserver(this._oncancelObserver,
-                             kPaymentFlowCancelled,
-                             false);
-    this._strategy = Cc["@mozilla.org/payment/provider-strategy;1"]
-                       .createInstance(Ci.nsIPaymentProviderStrategy);
-    this._window = aWindow;
-  },
-
-  paymentSuccess: function(aResult) {
-    _debug && DEBUG("paymentSuccess " + aResult);
-    let glue = Cc["@mozilla.org/payment/ui-glue;1"]
-                 .createInstance(Ci.nsIPaymentUIGlue);
-    glue.closePaymentFlow(this._requestId).then(() => {
-      if (!this._requestId) {
-        return;
-      }
-      cpmm.sendAsyncMessage("Payment:Success", { result: aResult,
-                                                 requestId: this._requestId });
-    });
-  },
-
-  paymentFailed: function(aError) {
-    _debug && DEBUG("paymentFailed " + aError);
-    let glue = Cc["@mozilla.org/payment/ui-glue;1"]
-                 .createInstance(Ci.nsIPaymentUIGlue);
-    glue.closePaymentFlow(this._requestId).then(() => {
-      if (!this._requestId) {
-        return;
-      }
-      cpmm.sendAsyncMessage("Payment:Failed", { errorMsg: aError,
-                                                requestId: this._requestId });
-    });
-
-  },
-
-  get paymentServiceId() {
-    return this._strategy.paymentServiceId;
-  },
-
-  set paymentServiceId(aServiceId) {
-    this._strategy.paymentServiceId = aServiceId;
-  },
-
-  /**
-   * We expose to the payment provider the information of all the SIMs
-   * available in the device. iccInfo is an object of this form:
-   * {
-   *   "serviceId1": {
-   *      mcc: <string>,
-   *      mnc: <string>,
-   *      iccId: <string>,
-   *      dataPrimary: <boolean>
-   *    },
-   *   "serviceIdN": {...}
-   * }
-   */
-  get iccInfo() {
-    return this._strategy.iccInfo;
-  },
-
-  oncancel: function() {
-    _debug && DEBUG("Cleaning up!");
-
-    this._strategy.cleanup();
-    Services.obs.removeObserver(this._oncancelObserver, kPaymentFlowCancelled);
-    if (this._cleanup) {
-      this._cleanup();
-    }
-  },
-
-  classID: Components.ID("{82144756-72ab-45b7-8621-f3dad431dd2f}"),
-
-  contractID: "@mozilla.org/payment/provider;1",
-
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports,
-                                         Ci.nsIObserver,
-                                         Ci.nsIDOMGlobalPropertyInitializer])
-};
-
-#if defined(MOZ_B2G_RIL) || defined(MOZ_WIDGET_ANDROID)
-
-XPCOMUtils.defineLazyServiceGetter(this, "smsService",
-                                   "@mozilla.org/sms/smsservice;1",
-                                   "nsISmsService");
-
-const kSilentSmsReceivedTopic = "silent-sms-received";
-
-// In order to send messages through nsISmsService, we need to implement
-// nsIMobileMessageCallback, as the WebSMS API implementation is not usable
-// from JS.
-function SilentSmsRequest(aDOMRequest) {
-  this.request = aDOMRequest;
-}
-
-SilentSmsRequest.prototype = {
-
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsIMobileMessageCallback]),
-
-  classID: Components.ID("{1d58889c-5660-4cca-a8fd-97ef63e5d3b2}"),
-
-  notifyMessageSent: function notifyMessageSent(aMessage) {
-    _debug && DEBUG("Silent message successfully sent");
-    Services.DOMRequest.fireSuccessAsync(this.request, aMessage);
-  },
-
-  notifySendMessageFailed: function notifySendMessageFailed(aError) {
-    DEBUG_E("Error sending silent message " + aError);
-    Services.DOMRequest.fireErrorAsync(this.request, aError);
-  }
-};
-
-PaymentProvider.prototype._silentNumbers = null;
-
-PaymentProvider.prototype._silentSmsObservers = null;
-
-PaymentProvider.prototype.sendSilentSms = function(aNumber, aMessage) {
-  _debug && DEBUG("Sending silent message " + aNumber + " - " + aMessage);
-
-  let request = Services.DOMRequest.createRequest(this._window);
-
-  if (this._strategy.paymentServiceId === null) {
-    DEBUG_E("No payment service ID set. Cannot send silent SMS");
-    Services.DOMRequest.fireErrorAsync(request,
-                                       "NO_PAYMENT_SERVICE_ID");
-    return request;
-  }
-
-  let smsRequest = new SilentSmsRequest(request);
-  smsService.send(this._strategy.paymentServiceId, aNumber, aMessage, true,
-                  smsRequest);
-  return request;
-};
-
-PaymentProvider.prototype.observeSilentSms = function(aNumber, aCallback) {
-  _debug && DEBUG("observeSilentSms " + aNumber);
-
-  if (!this._silentSmsObservers) {
-    this._silentSmsObservers = {};
-    this._silentNumbers = [];
-    this._onSilentSmsObserver = this._onSilentSms.bind(this);
-    Services.obs.addObserver(this._onSilentSmsObserver,
-                             kSilentSmsReceivedTopic,
-                             false);
-  }
-
-  if (!this._silentSmsObservers[aNumber]) {
-    this._silentSmsObservers[aNumber] = [];
-    this._silentNumbers.push(aNumber);
-    smsService.addSilentNumber(aNumber);
-  }
-
-  if (this._silentSmsObservers[aNumber].indexOf(aCallback) == -1) {
-    this._silentSmsObservers[aNumber].push(aCallback);
-  }
-  return;
-};
-
-PaymentProvider.prototype.removeSilentSmsObserver = function(aNumber, aCallback) {
-  _debug && DEBUG("removeSilentSmsObserver " + aNumber);
-
-  if (!this._silentSmsObservers || !this._silentSmsObservers[aNumber]) {
-    _debug && DEBUG("No observers for " + aNumber);
-    return;
-  }
-
-  let index = this._silentSmsObservers[aNumber].indexOf(aCallback);
-  if (index != -1) {
-    this._silentSmsObservers[aNumber].splice(index, 1);
-    if (this._silentSmsObservers[aNumber].length == 0) {
-      this._silentSmsObservers[aNumber] = null;
-      this._silentNumbers.splice(this._silentNumbers.indexOf(aNumber), 1);
-      smsService.removeSilentNumber(aNumber);
-    }
-  } else if (_debug) {
-    DEBUG("No callback found for " + aNumber);
-  }
-  return;
-};
-
-PaymentProvider.prototype._onSilentSms = function(aSubject, aTopic, aData) {
-  if (!aSubject || !(aSubject instanceof Ci.nsISmsMessage)) {
-    _debug && DEBUG("Invalid subject when receiving silent message!");
-    return;
-  }
-
-  let message = aSubject.QueryInterface(Ci.nsISmsMessage);
-
-  _debug && DEBUG("Got silent message! " + message.sender + " - " + message.body);
-
-  let number = message.sender;
-  if (!number || this._silentNumbers.indexOf(number) == -1) {
-    _debug && DEBUG("No observers for " + number);
-    return;
-  }
-
-  // If the service ID is null it means that the payment provider asked the
-  // user for her MSISDN, so we are in a MT only SMS auth flow. In this case
-  // we manually set the service ID to the one corresponding with the SIM
-  // that received the SMS.
-  if (this._strategy.paymentServiceId === null) {
-    let i = 0;
-    while(i < gRil.numRadioInterfaces) {
-      if (this.iccInfo[i].iccId === message.iccId) {
-        this._strategy.paymentServiceId = i;
-        break;
-      }
-      i++;
-    }
-  }
-
-  this._silentSmsObservers[number].forEach(function(callback) {
-    callback({
-      iccId: message.iccId,
-      sender: message.sender,
-      body: message.body,
-      timestamp: message.timestamp,
-      sentTimestamp: message.sentTimestamp
-    });
-  });
-};
-
-PaymentProvider.prototype._cleanup = function() {
-  if (!this._silentNumbers) {
-    return;
-  }
-
-  while (this._silentNumbers.length) {
-    let number = this._silentNumbers.pop();
-    smsService.removeSilentNumber(number);
-  }
-  this._silentNumbers = null;
-  this._silentSmsObservers = null;
-  Services.obs.removeObserver(this._onSilentSmsObserver,
-                              kSilentSmsReceivedTopic);
-};
-
-#else
-
-PaymentProvider.prototype.sendSilentSms = function(aNumber, aMessage) {
-  throw Cr.NS_ERROR_NOT_IMPLEMENTED;
-};
-
-PaymentProvider.prototype.observeSilentSms = function(aNumber, aCallback) {
-  throw Cr.NS_ERROR_NOT_IMPLEMENTED;
-};
-
-PaymentProvider.prototype.removeSilentSmsObserver = function(aNumber, aCallback) {
-  throw Cr.NS_ERROR_NOT_IMPLEMENTED;
-};
-
-#endif
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([PaymentProvider]);
deleted file mode 100644
--- a/dom/payment/PaymentProviderUtils.cpp
+++ /dev/null
@@ -1,30 +0,0 @@
-/* -*- 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/. */
-
-#include "mozilla/dom/NavigatorBinding.h"
-#include "PaymentProviderUtils.h"
-#include "nsGlobalWindow.h"
-#include "nsJSUtils.h"
-#include "nsIDocShell.h"
-
-using namespace mozilla::dom;
-
-/* static */ bool
-PaymentProviderUtils::EnabledForScope(JSContext* aCx,
-                                      JSObject* aGlobal)
-{
-  nsCOMPtr<nsPIDOMWindowInner> win =
-    do_QueryInterface(nsJSUtils::GetStaticScriptGlobal(aGlobal));
-  NS_ENSURE_TRUE(win, false);
-
-  nsIDocShell *docShell = win->GetDocShell();
-  NS_ENSURE_TRUE(docShell, false);
-
-  nsString paymentRequestId;
-  docShell->GetPaymentRequestId(paymentRequestId);
-
-  return !paymentRequestId.IsEmpty();
-}
deleted file mode 100644
--- a/dom/payment/PaymentProviderUtils.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/* -*- 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_payment_PaymentProviderEnabler_h
-#define mozilla_dom_payment_PaymentProviderEnabler_h
-
-#include "jsapi.h"
-
-struct JSContext;
-class JSObject;
-
-namespace mozilla {
-namespace dom {
-  
-class PaymentProviderUtils
-{
-public:
-  static bool EnabledForScope(JSContext*, JSObject*);
-};
-
-} // namespace dom
-} // namespace mozilla
-
-#endif // mozilla_dom_payment_PaymentProviderEnabler_h
deleted file mode 100644
--- a/dom/payment/interfaces/moz.build
+++ /dev/null
@@ -1,15 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-XPIDL_SOURCES += [
-    'nsIPaymentContentHelperService.idl',
-    'nsIPaymentFlowInfo.idl',
-    'nsIPaymentProviderStrategy.idl',
-    'nsIPaymentUIGlue.idl',
-]
-
-XPIDL_MODULE = 'dom_payment'
-
deleted file mode 100644
--- a/dom/payment/interfaces/nsIPaymentContentHelperService.idl
+++ /dev/null
@@ -1,18 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "domstubs.idl"
-
-interface nsIDOMDOMRequest;
-interface mozIDOMWindow;
-
-[scriptable, uuid(80035846-6732-4fcc-961b-f336b65218f4)]
-interface nsIPaymentContentHelperService : nsISupports
-{
-  // The 'jwts' parameter can be either a single DOMString or an array of
-  // DOMStrings. In both cases, it represents the base64url encoded and
-  // digitally signed payment information. Each payment provider should
-  // define its supported JWT format.
-  nsIDOMDOMRequest pay(in mozIDOMWindow window, in jsval jwts);
-};
deleted file mode 100644
--- a/dom/payment/interfaces/nsIPaymentFlowInfo.idl
+++ /dev/null
@@ -1,25 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "nsISupports.idl"
-
-[scriptable, uuid(f3fe3b48-fe81-4ec9-90ab-648ac9403466)]
-interface nsIPaymentFlowInfo : nsISupports
-{
-  // Payment provider uri.
-  attribute DOMString uri;
-
-  // Base64 encoded and digitally signed payment request information.
-  attribute DOMString jwt;
-
-  // Payment providers expect the payment information as GET or POST
-  // parameters.
-  attribute DOMString requestMethod;
-
-  // Payment provider name.
-  attribute DOMString name;
-
-  // Payment provider description.
-  attribute DOMString description;
-};
deleted file mode 100644
--- a/dom/payment/interfaces/nsIPaymentProviderStrategy.idl
+++ /dev/null
@@ -1,14 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "nsISupports.idl"
-
-[scriptable, uuid(c3971bd9-0fbf-48d3-9498-0ac340d0d216)]
-interface nsIPaymentProviderStrategy : nsISupports
-{
-  attribute DOMString paymentServiceId;
-  readonly attribute jsval iccInfo;
-
-  void cleanup();
-};
deleted file mode 100644
--- a/dom/payment/interfaces/nsIPaymentUIGlue.idl
+++ /dev/null
@@ -1,32 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "nsISupports.idl"
-
-interface nsIPaymentFlowInfo;
-
-[scriptable, function, uuid(b9afa678-71a5-4975-bcdb-0c4098730eff)]
-interface nsIPaymentUIGlueCallback : nsISupports
-{
-    void onresult(in DOMString requestId, in DOMString result);
-};
-
-[scriptable, uuid(4dc09e33-d395-4e1d-acb4-e85415181270)]
-interface nsIPaymentUIGlue : nsISupports
-{
-    // The 'paymentRequestsInfo' contains the payment request information
-    // for each JWT provided via navigator.mozPay call.
-    void confirmPaymentRequest(in DOMString requestId,
-                               in jsval paymentRequestsInfo,
-                               in nsIPaymentUIGlueCallback successCb,
-                               in nsIPaymentUIGlueCallback errorCb);
-
-    void showPaymentFlow(in DOMString requestId,
-                         in nsIPaymentFlowInfo paymentFlowInfo,
-                         in nsIPaymentUIGlueCallback errorCb);
-
-    // The promise resolves with no value as soon as the payment window is
-    // closed.
-    jsval /*Promise*/ closePaymentFlow(in DOMString requestId);
-};
deleted file mode 100644
--- a/dom/payment/moz.build
+++ /dev/null
@@ -1,39 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-DIRS += ['interfaces']
-
-EXPORTS.mozilla.dom += [
-    'PaymentProviderUtils.h',
-]
-
-SOURCES += [
-    'PaymentProviderUtils.cpp',
-]
-
-EXTRA_PP_JS_MODULES += [
-    'Payment.jsm',
-]
-
-EXTRA_COMPONENTS += [
-    'Payment.js',
-    'Payment.manifest',
-    'PaymentFlowInfo.js'
-]
-
-EXTRA_PP_COMPONENTS += [
-    'PaymentProvider.js'
-]
-
-FINAL_LIBRARY = 'xul'
-
-LOCAL_INCLUDES += [
-    '/dom/base'
-]
-
-XPCSHELL_TESTS_MANIFESTS += ['tests/unit/xpcshell.ini']
-
-MOCHITEST_MANIFESTS += ['tests/mochitest/mochitest.ini']
deleted file mode 100644
--- a/dom/payment/tests/mochitest/MockPaymentsUIChromeScript.js
+++ /dev/null
@@ -1,91 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cm = Components.manager;
-const Cu = Components.utils;
-
-const CONTRACT_ID = "@mozilla.org/payment/ui-glue;1";
-
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-
-var registrar = Cm.QueryInterface(Ci.nsIComponentRegistrar);
-var oldClassID, oldFactory;
-var newClassID = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator).generateUUID();
-var newFactory = {
-  createInstance: function(aOuter, aIID) {
-    if (aOuter) {
-      throw Components.results.NS_ERROR_NO_AGGREGATION;
-    }
-    return new MockPaymentsUIGlueInstance().QueryInterface(aIID);
-  },
-  lockFactory: function(aLock) {
-    throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
-  },
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsIFactory])
-};
-
-addMessageListener("MockPaymentsUIGlue.init", function (message) {
-  try {
-    oldClassID = registrar.contractIDToCID(CONTRACT_ID);
-    oldFactory = Cm.getClassObject(oldClassID, Ci.nsIFactory);
-  } catch (ex) {
-    oldClassID = "";
-    oldFactory = null;
-    dump("TEST-INFO | can't get payments ui glue registered component, " +
-         "assuming there is none\n");
-  }
-  if (oldFactory) {
-    registrar.unregisterFactory(oldClassID, oldFactory);
-  }
-  registrar.registerFactory(newClassID, "", CONTRACT_ID, newFactory);});
-
-addMessageListener("MockPaymentsUIGlue.cleanup", function (message) {
-  if (oldClassID) {
-    registrar.registerFactory(oldClassID, "", CONTRACT_ID, null);
-  }
-});
-
-var payments = new Map();
-
-function MockPaymentsUIGlueInstance() {
-};
-
-MockPaymentsUIGlueInstance.prototype = {
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsIPaymentUIGlue]),
-
-  confirmPaymentRequest: function(aRequestId,
-                                  aRequests,
-                                  aSuccessCb,
-                                  aErrorCb) {
-    aSuccessCb.onresult(aRequestId, aRequests[0].type);
-  },
-
-  showPaymentFlow: function(aRequestId,
-                            aPaymentFlowInfo,
-                            aErrorCb) {
-    let win = Services.ww.openWindow(null,
-                                     null,
-                                     "_blank",
-                                     "chrome,dialog=no,resizable,scrollbars,centerscreen",
-                                     null);
-
-    payments.set(aRequestId, win);
-    let docshell = win.QueryInterface(Ci.nsIInterfaceRequestor)
-                      .getInterface(Ci.nsIWebNavigation)
-                      .QueryInterface(Ci.nsIDocShell);
-    docshell.paymentRequestId = aRequestId;
-
-    win.document.location = aPaymentFlowInfo.uri + aPaymentFlowInfo.jwt;
-  },
-
-  closePaymentFlow: function(aRequestId) {
-    payments.get(aRequestId).close();
-    payments.delete(aRequestId);
-
-    return Promise.resolve();
-  },
-};
deleted file mode 100644
--- a/dom/payment/tests/mochitest/file_mozpayproviderchecker.html
+++ /dev/null
@@ -1,28 +0,0 @@
-<!--
-  * This Source Code Form is subject to the terms of the Mozilla Public
-  * License, v. 2.0. If a copy of the MPL was not distributed with this
-  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
- -->
-<!DOCTYPE html>
-<html>
-<head>
-  <meta charset="utf-8">
-  <title>Test app for bug 1097928 - Check if MozPaymentProvider API is exposed</title>
-</head>
-<body>
-<div id='test'>
-<script type="application/javascript;version=1.8">
-  function receiveMessage(event) {
-    let message = JSON.parse(event.data);
-    let exposed = (navigator.mozPaymentProvider != undefined);
-    window.parent.postMessage(JSON.stringify({
-      iframeType: message.iframeType,
-      exposed: exposed
-    }), "*");
-  }
-
-  window.addEventListener("message", receiveMessage, false, true);
-</script>
-</div>
-</body>
-</html>
deleted file mode 100644
--- a/dom/payment/tests/mochitest/file_payproviderfailure.html
+++ /dev/null
@@ -1,12 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-  <head>
-    <meta charset="utf-8">
-  </head>
-  <body>
-    <script>
-    navigator.mozPaymentProvider.paymentFailed();
-    </script>
-  </body>
-</html>
-
deleted file mode 100644
--- a/dom/payment/tests/mochitest/file_payprovidersuccess.html
+++ /dev/null
@@ -1,12 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-  <head>
-    <meta charset="utf-8">
-  </head>
-  <body>
-    <script>
-    navigator.mozPaymentProvider.paymentSuccess("aResult");
-    </script>
-  </body>
-</html>
-
deleted file mode 100644
--- a/dom/payment/tests/mochitest/mochitest.ini
+++ /dev/null
@@ -1,11 +0,0 @@
-[DEFAULT]
-skip-if=buildapp != 'b2g'
-
-support-files=
-  file_mozpayproviderchecker.html
-  file_payprovidersuccess.html
-  file_payproviderfailure.html
-  MockPaymentsUIChromeScript.js
-
-[test_mozpaymentprovider.html]
-[test_mozpay_callbacks.html]
deleted file mode 100644
--- a/dom/payment/tests/mochitest/test_mozpay_callbacks.html
+++ /dev/null
@@ -1,112 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-  https://bugzilla.mozilla.org/show_bug.cgi?id=1097928
--->
-<html>
-<head>
-  <title>Test for navigator.mozPay. Bug 1097928</title>
-  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-</head>
-<body>
-<p id="display"></p>
-<div id="content" style="display: none">
-</div>
-<pre id="test">
-<script type="application/javascript;version=1.8">
-
-SimpleTest.waitForExplicitFinish();
-
-let tests = [() => {
-  /*
-  {
-   "iss": "323d34dc-b5cf-4822-8e47-6a4515dc74db",
-    "typ": "mozilla/payments/test/success",
-    "request": {
-        "name": "Virtual Kiwi",
-        "id": "af1f960a-3f90-4e2d-a20f-d5170aee49f2",
-        "postbackURL": "https://inapp-pay-test.paas.allizom.org/mozpay",
-        "productData": "localTransID=14546cd1-db9b-4759-986f-2a6a295fdcc1",
-        "chargebackURL": "https://inapp-pay-test.paas.allizom.org/mozpay",
-        "description": "The forbidden fruit"
-    }
-  }
-  */
-  let jwt = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiIzMjNkMzRkYy1iNWNmLTQ4MjItOGU0Ny02YTQ1MTVkYzc0ZGIiLCJyZXF1ZXN0Ijp7ImRlc2NyaXB0aW9uIjoiVGhlIGZvcmJpZGRlbiBmcnVpdCIsImlkIjoiYWYxZjk2MGEtM2Y5MC00ZTJkLWEyMGYtZDUxNzBhZWU0OWYyIiwicG9zdGJhY2tVUkwiOiJodHRwczovL2luYXBwLXBheS10ZXN0LnBhYXMuYWxsaXpvbS5vcmcvbW96cGF5L3Bvc3RiYWNrIiwicHJvZHVjdERhdGEiOiJsb2NhbFRyYW5zSUQ9MTQ1NDZjZDEtZGI5Yi00NzU5LTk4NmYtMmE2YTI5NWZkY2MxIiwiY2hhcmdlYmFja1VSTCI6Imh0dHBzOi8vaW5hcHAtcGF5LXRlc3QucGFhcy5hbGxpem9tLm9yZy9tb3pwYXkvY2hhcmdlYmFjayIsIm5hbWUiOiJWaXJ0dWFsIEtpd2kifSwidHlwIjoibW96aWxsYS9wYXltZW50cy90ZXN0L3N1Y2Nlc3MifQ.8zaeYFUCwKkZWk2TFf2wEJWrmiSYQGNbpKc2ADkvL9s";
-  let req = window.navigator.mozPay(jwt);
-  req.onsuccess = (result) => {
-    ok(true, "Expected mozPay success");
-    runTest();
-  };
-  req.onerror = (error) => {
-    ok(false, "Unexpected mozPay error " + error);
-    SimpleTest.finish();
-  };
-}, () => {
-  /*
-  {
-      "iss": "323d34dc-b5cf-4822-8e47-6a4515dc74db",
-      "typ": "mozilla/payments/test/failure",
-      "request": {
-          "name": "Virtual Kiwi",
-          "id": "af1f960a-3f90-4e2d-a20f-d5170aee49f2",
-          "postbackURL": "https://inapp-pay-test.paas.allizom.org/mozpay",
-          "productData": "localTransID=cc3c0994-33e8-4a21-aa2c-75ee44f5fe75",
-          "chargebackURL": "https://inapp-pay-test.paas.allizom.org/mozpay",
-          "description": "The forbidden fruit"
-      }
-  }
-   */
-  let jwt = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiIzMjNkMzRkYy1iNWNmLTQ4MjItOGU0Ny02YTQ1MTVkYzc0ZGIiLCJyZXF1ZXN0Ijp7ImRlc2NyaXB0aW9uIjoiVGhlIGZvcmJpZGRlbiBmcnVpdCIsImlkIjoiYWYxZjk2MGEtM2Y5MC00ZTJkLWEyMGYtZDUxNzBhZWU0OWYyIiwicG9zdGJhY2tVUkwiOiJodHRwczovL2luYXBwLXBheS10ZXN0LnBhYXMuYWxsaXpvbS5vcmcvbW96cGF5L3Bvc3RiYWNrIiwicHJvZHVjdERhdGEiOiJsb2NhbFRyYW5zSUQ9Y2MzYzA5OTQtMzNlOC00YTIxLWFhMmMtNzVlZTQ0ZjVmZTc1IiwiY2hhcmdlYmFja1VSTCI6Imh0dHBzOi8vaW5hcHAtcGF5LXRlc3QucGFhcy5hbGxpem9tLm9yZy9tb3pwYXkvY2hhcmdlYmFjayIsIm5hbWUiOiJWaXJ0dWFsIEtpd2kifSwidHlwIjoibW96aWxsYS9wYXltZW50cy90ZXN0L2ZhaWx1cmUifQ.1uV4-HkmwO0oDv50wi1Ma4tNpnxoFGaw5zaPj8xkcAc";
-  let req = window.navigator.mozPay(jwt);
-  req.onsuccess = (result) => {
-    ok(false, "Unexpected mozPay success " + result);
-    SimpleTest.finish();
-  };
-  req.onerror = (error) => {
-    ok(true, "Expected mozPay error");
-    runTest();
-  };
-}];
-
-function runTest() {
-  if (!tests.length) {
-    ok(true, "Done!");
-    SimpleTest.finish();
-    return;
-  }
-  tests.shift()();
-}
-
-const uiGlue = SpecialPowers.loadChromeScript(SimpleTest.getTestFileURL('MockPaymentsUIChromeScript.js'));
-SimpleTest.registerCleanupFunction(() => {
- uiGlue.sendAsyncMessage("MockPaymentsUIGlue.cleanup", {});
-});
-uiGlue.sendAsyncMessage("MockPaymentsUIGlue.init", {});
-
-SpecialPowers.pushPrefEnv({
-  "set": [
-    ["dom.payment.skipHTTPSCheck", "true"],
-    ["dom.payment.debug", "true"],
-    ["dom.payment.provider.1.name", "SuccessProvider"],
-    ["dom.payment.provider.1.description", ""],
-    ["dom.payment.provider.1.uri",
-     "https://example.com:443/tests/dom/payment/tests/mochitest/file_payprovidersuccess.html?req="],
-    ["dom.payment.provider.1.type", "mozilla/payments/test/success"],
-    ["dom.payment.provider.1.requestMethod", "GET"],
-    ["dom.payment.provider.2.name", "FailureProvider"],
-    ["dom.payment.provider.2.description", ""],
-    ["dom.payment.provider.2.uri",
-     "https://example.com:443/tests/dom/payment/tests/mochitest/file_payproviderfailure.html?req="],
-    ["dom.payment.provider.2.type", "mozilla/payments/test/failure"],
-    ["dom.payment.provider.2.requestMethod", "GET"],
-  ]
-  }, () => {
-    runTest();
-  });
-
-</script>
-</pre>
-</body>
-</html>
deleted file mode 100644
--- a/dom/payment/tests/mochitest/test_mozpaymentprovider.html
+++ /dev/null
@@ -1,93 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-  https://bugzilla.mozilla.org/show_bug.cgi?id=1097928
--->
-<html>
-<head>
-  <title>Test for navigator.mozPaymentProvider exposure. Bug 1097928</title>
-  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-</head>
-<body>
-<p id="display"></p>
-<div id="content" style="display: none">
-</div>
-<pre id="test">
-<script type="application/javascript;version=1.8">
-
-SimpleTest.waitForExplicitFinish();
-
-// We create two iframes. The first one is a regular iframe with no payment
-// information and so it should not have access to the MozPaymentProvider
-// API. For the second iframe we set a dummy payment request ID which should
-// expose the MozPaymentProvider API.
-let tests = [function() {
-  // Iframe with no payment information.
-  let iframe = document.createElement("iframe");
-  iframe.setAttribute("mozbrowser", "true");
-  iframe.src = "file_mozpayproviderchecker.html";
-
-  document.getElementById("content").appendChild(iframe);
-
-  iframe.addEventListener("load", function onLoad() {
-    iframe.removeEventListener("load", onLoad);
-    iframe.contentWindow.postMessage(JSON.stringify({
-      iframeType: "regular"
-    }), "*");
-  }, false);
-}, function() {
-  // Payment iframe.
-  let paymentIframe = document.createElement("iframe");
-  paymentIframe.setAttribute("mozbrowser", "true");
-  paymentIframe.src = "file_mozpayproviderchecker.html";
-
-  document.getElementById("content").appendChild(paymentIframe);
-
-  let Ci = SpecialPowers.Ci;
-  let docshell = SpecialPowers.wrap(paymentIframe.contentWindow)
-                              .QueryInterface(Ci.nsIInterfaceRequestor)
-                              .getInterface(Ci.nsIWebNavigation)
-                              .QueryInterface(Ci.nsIDocShell);
-  docshell.paymentRequestId = "dummyid";
-
-  paymentIframe.addEventListener("load", function onLoad() {
-    paymentIframe.removeEventListener("load", onLoad);
-    paymentIframe.contentWindow.postMessage(JSON.stringify({
-      iframeType: "payment"
-    }), "*");
-  }, false);
-}];
-
-function receiveMessage(event) {
-  let message = JSON.parse(event.data);
-  switch (message.iframeType) {
-    case "regular":
-      ok(!message.exposed, "MozPaymentProvider is not exposed in regular iframe");
-      break;
-    case "payment":
-      ok(message.exposed, "MozPaymentProvider is exposed in payment iframe");
-      break;
-    default:
-      ok(false, "Unexpected iframe type");
-      SimpleTest.finish();
-  }
-  runTest();
-}
-
-function runTest() {
-  if (!tests.length) {
-    ok(true, "Done!");
-    SimpleTest.finish();
-    return;
-  }
-  tests.shift()();
-}
-
-window.addEventListener("message", receiveMessage, false, true);
-runTest();
-
-</script>
-</pre>
-</body>
-</html>
deleted file mode 100644
--- a/dom/payment/tests/unit/header_helper.js
+++ /dev/null
@@ -1,38 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
-   http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
-
-var subscriptLoader = Cc["@mozilla.org/moz/jssubscript-loader;1"]
-                        .getService(Ci.mozIJSSubScriptLoader);
-
-/**
- * Start a new payment module.
- *
- * @param custom_ns
- *        Namespace with symbols to be injected into the new payment module
- *        namespace.
- *
- * @return an object that represents the payment module's namespace.
- */
-function newPaymentModule(custom_ns) {
-  let payment_ns = {
-    importScripts: function fakeImportScripts() {
-      Array.slice(arguments).forEach(function (script) {
-        subscriptLoader.loadSubScript("resource://gre/modules/" + script, this);
-      }, this);
-    },
-  };
-
-  // Copy the custom definitions over.
-  for (let key in custom_ns) {
-    payment_ns[key] = custom_ns[key];
-  }
-
-  // Load the payment module itself.
-  payment_ns.importScripts("Payment.jsm");
-
-  return payment_ns;
-}
deleted file mode 100644
--- a/dom/payment/tests/unit/test_paymanager_get_payment_request.js
+++ /dev/null
@@ -1,348 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
-   http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-function getPaymentHelper() {
-  let error;
-  let paym = newPaymentModule();
-
-  paym.PaymentManager.paymentFailed = function paymentFailed(aRequestId,
-                                                             errorMsg) {
-    error = errorMsg;
-  };
-
-  return {
-    get paymentModule() {
-      return paym;
-    },
-    get error() {
-      return error;
-    }
-  };
-}
-
-function run_test() {
-  run_next_test();
-}
-
-function testGetPaymentRequest(paymentProviders, test) {
-  let helper = getPaymentHelper();
-  let paym = helper.paymentModule;
-
-  paym.PaymentManager.registeredProviders = paymentProviders;
-
-  let ret = paym.PaymentManager.getPaymentRequestInfo("", test.jwt);
-  if (!test.result) {
-    test.ret ? do_check_true(ret) : do_check_false(ret);
-  }
-  if (test.error !== null) {
-    do_check_eq(helper.error, test.error);
-  } else {
-    do_check_eq(typeof ret, "object");
-    do_check_eq(ret.jwt, test.jwt);
-    do_check_eq(ret.type, test.result.type);
-    do_check_eq(ret.providerName, test.result.providerName);
-  }
-}
-
-add_test(function test_successfull_request() {
-  let providers = {};
-  let type = "mock/payments/inapp/v1";
-  providers[type] = {
-    name: "mockprovider",
-    description: "Mock Payment Provider",
-    uri: "https://mockpayprovider.phpfogapp.com/?req=",
-    requestMethod: "GET"
-  };
-
-  // Payload
-  //  {
-  //    "aud": "mockpayprovider.phpfogapp.com",
-  //    "iss": "Enter you app key here!",
-  //    "request": {
-  //      "name": "Piece of Cake",
-  //      "price": "10.50",
-  //      "priceTier": 1,
-  //      "productdata": "transaction_id=86",
-  //      "currencyCode": "USD",
-  //      "description": "Virtual chocolate cake to fill your virtual tummy"
-  //    },
-  //    "exp": 1352232792,
-  //    "iat": 1352229192,
-  //    "typ": "mock/payments/inapp/v1"
-  //  }
-  let jwt = "eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.eyJhdWQiOiAibW9j" +
-            "a3BheXByb3ZpZGVyLnBocGZvZ2FwcC5jb20iLCAiaXNzIjogIkVudGVyI" +
-            "HlvdSBhcHAga2V5IGhlcmUhIiwgInJlcXVlc3QiOiB7Im5hbWUiOiAiUG" +
-            "llY2Ugb2YgQ2FrZSIsICJwcmljZSI6ICIxMC41MCIsICJwcmljZVRpZXI" +
-            "iOiAxLCAicHJvZHVjdGRhdGEiOiAidHJhbnNhY3Rpb25faWQ9ODYiLCAi" +
-            "Y3VycmVuY3lDb2RlIjogIlVTRCIsICJkZXNjcmlwdGlvbiI6ICJWaXJ0d" +
-            "WFsIGNob2NvbGF0ZSBjYWtlIHRvIGZpbGwgeW91ciB2aXJ0dWFsIHR1bW" +
-            "15In0sICJleHAiOiAxMzUyMjMyNzkyLCAiaWF0IjogMTM1MjIyOTE5Miw" +
-            "gInR5cCI6ICJtb2NrL3BheW1lbnRzL2luYXBwL3YxIn0.QZxc62USCy4U" +
-            "IyKIC1TKelVhNklvk-Ou1l_daKntaFI";
-
-  testGetPaymentRequest(providers, {
-    jwt: jwt,
-    ret: true,
-    error: null,
-    result: {
-      type: type,
-      providerName: providers[type].name
-    }
-  });
-
-  run_next_test();
-});
-
-add_test(function test_successfull_request_html_description() {
-  let providers = {};
-  let type = "mozilla/payments/pay/v1";
-  providers[type] = {
-    name: "webpay",
-    description: "Mozilla Payment Provider",
-    uri: "https://marketplace.firefox.com/mozpay/?req=",
-    requestMethod: "GET"
-  };
-
-  // Payload
-  //  {
-  //    "aud": "marketplace.firefox.com",
-  //    "iss": "marketplace-dev.allizom.org",
-  //    "request": {
-  //      "name": "Krupa's paid app 1",
-  //      "chargebackURL": "http://localhost:8002/telefonica/services/webpay/"
-  //                       "chargeback",
-  //      "postbackURL": "http://localhost:8002/telefonica/services/webpay/"
-  //                     "postback",
-  //      "productData": "addon_id=85&seller_uuid=d4855df9-6ce0-45cd-81cb-"
-  //                     "cf8737e1e7aa&contrib_uuid=201868b7ac2cda410a99b3"
-  //                     "ed4c11a8ea",
-  //      "pricePoint": 1,
-  //      "id": "maude:85",
-  //      "description": "This app has been automatically generated by <a href="
-  //                     "\"http://outgoing.mozilla.org/v1/ba7f373ae16789eff3ab"
-  //                     "fd95ca8d3c15d18dc9009afa204dc43f85a55b1f6ef1/http%3A/"
-  //                     "/testmanifest.com\" rel=\"nofollow\">testmanifest.com"
-  //                     "</a>"
-  //    },
-  //    "exp": 1358379147,
-  //    "iat": 1358375547,
-  //    "typ": "mozilla/payments/pay/v1"
-  //  }
-  let jwt = "eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.eyJhdWQiOiAibWFya2V0cGx" +
-            "hY2UuZmlyZWZveC5jb20iLCAiaXNzIjogIm1hcmtldHBsYWNlLWRldi5hbGxpem9" +
-            "tLm9yZyIsICJyZXF1ZXN0IjogeyJuYW1lIjogIktydXBhJ3MgcGFpZCBhcHAgMSI" +
-            "sICJjaGFyZ2ViYWNrVVJMIjogImh0dHA6Ly9sb2NhbGhvc3Q6ODAwMi90ZWxlZm9" +
-            "uaWNhL3NlcnZpY2VzL3dlYnBheS9jaGFyZ2ViYWNrIiwgInBvc3RiYWNrVVJMIjo" +
-            "gImh0dHA6Ly9sb2NhbGhvc3Q6ODAwMi90ZWxlZm9uaWNhL3NlcnZpY2VzL3dlYnB" +
-            "heS9wb3N0YmFjayIsICJwcm9kdWN0RGF0YSI6ICJhZGRvbl9pZD04NSZzZWxsZXJ" +
-            "fdXVpZD1kNDg1NWRmOS02Y2UwLTQ1Y2QtODFjYi1jZjg3MzdlMWU3YWEmY29udHJ" +
-            "pYl91dWlkPTIwMTg2OGI3YWMyY2RhNDEwYTk5YjNlZDRjMTFhOGVhIiwgInByaWN" +
-            "lUG9pbnQiOiAxLCAiaWQiOiAibWF1ZGU6ODUiLCAiZGVzY3JpcHRpb24iOiAiVGh" +
-            "pcyBhcHAgaGFzIGJlZW4gYXV0b21hdGljYWxseSBnZW5lcmF0ZWQgYnkgPGEgaHJ" +
-            "lZj1cImh0dHA6Ly9vdXRnb2luZy5tb3ppbGxhLm9yZy92MS9iYTdmMzczYWUxNjc" +
-            "4OWVmZjNhYmZkOTVjYThkM2MxNWQxOGRjOTAwOWFmYTIwNGRjNDNmODVhNTViMWY" +
-            "2ZWYxL2h0dHAlM0EvL3Rlc3RtYW5pZmVzdC5jb21cIiByZWw9XCJub2ZvbGxvd1w" +
-            "iPnRlc3RtYW5pZmVzdC5jb208L2E-In0sICJleHAiOiAxMzU4Mzc5MTQ3LCAiaWF" +
-            "0IjogMTM1ODM3NTU0NywgInR5cCI6ICJtb3ppbGxhL3BheW1lbnRzL3BheS92MSJ" +
-            "9.kgSt636OSRBezMGtm9QLeDxlEOevL4xcOoDj8VRJyD8";
-
-  testGetPaymentRequest(providers, {
-    jwt: jwt,
-    ret: true,
-    error: null,
-    result: {
-      type: type,
-      providerName: providers[type].name
-    }
-  });
-
-  run_next_test();
-});
-
-add_test(function test_empty_jwt() {
-  testGetPaymentRequest(null, {
-    jwt: "",
-    ret: true,
-    error: "INTERNAL_ERROR_CALL_WITH_MISSING_JWT"
-  });
-
-  run_next_test();
-});
-
-add_test(function test_wrong_segments_count() {
-  // 1 segment JWT
-  let OneSegJwt = "eyJhbGciOiJIUzI1NiJ9";
-  testGetPaymentRequest(null, {
-    jwt: OneSegJwt,
-    ret: true,
-    error: "PAY_REQUEST_ERROR_WRONG_SEGMENTS_COUNT"
-  });
-
-  // 2 segments JWT
-  let TwoSegJwt = "eyJhbGciOiJIUzI1NiJ9.eyJpc3MiOiIwNTg2NDkwMTM2NTY2N" +
-                  "zU1ODY2MSIsImF1ZCI6Ikdvb2dsZSIsInR5cCI6Imdvb2dsZS9" +
-                  "wYXltZW50cy9pbmFwcC9pdGVtL3YxIiwiaWF0IjoxMzUyMjIwM" +
-                  "jEyLCJleHAiOjEzNTIzMDY2MTIsInJlcXVlc3QiOnsiY3VycmV" +
-                  "uY3lDb2RlIjoiVVNEIiwicHJpY2UiOiIzLjAwIiwibmFtZSI6I" +
-                  "kdvbGQgU3RhciIsInNlbGxlckRhdGEiOiJzb21lIG9wYXF1ZSB" +
-                  "kYXRhIiwiZGVzY3JpcHRpb24iOiJBIHNoaW5pbmcgYmFkZ2Ugb" +
-                  "2YgZGlzdGluY3Rpb24ifX0";
-
-  testGetPaymentRequest(null, {
-    jwt: TwoSegJwt,
-    ret: true,
-    error: "PAY_REQUEST_ERROR_WRONG_SEGMENTS_COUNT"
-  });
-
-  run_next_test();
-});
-
-add_test(function test_empty_payload() {
-  let EmptyPayloadJwt = "eyJhbGciOiJIUzI1NiJ9..eyJpc3MiOiIwNTg2NDkwMTM2NTY2N";
-
-  testGetPaymentRequest(null, {
-    jwt: EmptyPayloadJwt,
-    ret: true,
-    error: "PAY_REQUEST_ERROR_EMPTY_PAYLOAD"
-  });
-
-  run_next_test();
-});
-
-add_test(function test_missing_typ_parameter() {
-  // Payload
-  //  {
-  //    "iss": "640ae477-df33-45cd-83b8-6f1f910a6494",
-  //    "iat": 1361203745,
-  //    "request": {
-  //      "description": "detailed description",
-  //      "id": "799db970-7afa-4028-bdb7-8b045eb8babc",
-  //      "postbackURL": "http://inapp-pay-test.farmdev.com/postback",
-  //      "productData": "transaction_id=58",
-  //      "pricePoint": 1,
-  //      "chargebackURL": "http://inapp-pay-test.farmdev.com/chargeback",
-  //      "name": "The Product"
-  //    },
-  //    "aud": "marketplace-dev.allizom.org",
-  //    "exp": 1361207345
-  //  }
-  let missingTypJwt = "eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9." +
-                      "eyJpc3MiOiAiNjQwYWU0NzctZGYzMy00NWNkLTgzY" +
-                      "jgtNmYxZjkxMGE2NDk0IiwgImlhdCI6IDEzNjEyMD" +
-                      "M3NDUsICJyZXF1ZXN0IjogeyJkZXNjcmlwdGlvbiI" +
-                      "6ICJkZXRhaWxlZCBkZXNjcmlwdGlvbiIsICJpZCI6" +
-                      "ICI3OTlkYjk3MC03YWZhLTQwMjgtYmRiNy04YjA0N" +
-                      "WViOGJhYmMiLCAicG9zdGJhY2tVUkwiOiAiaHR0cD" +
-                      "ovL2luYXBwLXBheS10ZXN0LmZhcm1kZXYuY29tL3B" +
-                      "vc3RiYWNrIiwgInByb2R1Y3REYXRhIjogInRyYW5z" +
-                      "YWN0aW9uX2lkPTU4IiwgInByaWNlUG9pbnQiOiAxL" +
-                      "CAiY2hhcmdlYmFja1VSTCI6ICJodHRwOi8vaW5hcH" +
-                      "AtcGF5LXRlc3QuZmFybWRldi5jb20vY2hhcmdlYmF" +
-                      "jayIsICJuYW1lIjogIlRoZSBQcm9kdWN0In0sICJh" +
-                      "dWQiOiAibWFya2V0cGxhY2UtZGV2LmFsbGl6b20ub" +
-                      "3JnIiwgImV4cCI6IDEzNjEyMDczNDV9.KAHsJX1Hy" +
-                      "fmwNvAckdVUqlpPvdHggpx9yX276TWacRg";
-  testGetPaymentRequest(null, {
-    jwt: missingTypJwt,
-    ret: true,
-    error: "PAY_REQUEST_ERROR_NO_TYP_PARAMETER"
-  });
-
-  run_next_test();
-});
-
-add_test(function test_missing_request_parameter() {
-  // Payload
-  //  {
-  //    "iss": "Enter you app key here!",
-  //    "iat": 1352225299,
-  //    "typ": "mock/payments/inapp/v1",
-  //    "aud": "mockpayprovider.phpfogapp.com",
-  //    "exp": 1352228899
-  //  }
-  let missingRequestJwt = "eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9." +
-                          "eyJpc3MiOiAiRW50ZXIgeW91IGFwcCBrZXkgaGVyZ" +
-                          "SEiLCAiaWF0IjogMTM1MjIyNTI5OSwgInR5cCI6IC" +
-                          "Jtb2NrL3BheW1lbnRzL2luYXBwL3YxIiwgImF1ZCI" +
-                          "6ICJtb2NrcGF5cHJvdmlkZXIucGhwZm9nYXBwLmNv" +
-                          "bSIsICJleHAiOiAxMzUyMjI4ODk5fQ.yXGinvZiUs" +
-                          "v9JWvdfM6zPD0iOX9DgCPcIwIbCrL4tcs";
-
-  testGetPaymentRequest(null, {
-    jwt: missingRequestJwt,
-    ret: true,
-    error: "PAY_REQUEST_ERROR_NO_REQUEST_PARAMETER"
-  });
-
-  run_next_test();
-});
-
-add_test(function test_jwt_decoding_error() {
-  let wrongJwt = "eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.^eyJhdWQiOiAibW9" +
-                 "a3BheXByb3ZpZGVyLnBocGZvZ2FwcC5jb20iLCAiaXNzIjogIkVudGVyI" +
-                 "HlvdSBhcHAga2V5IGhlcmUhIiwgInJlcXVlc3QiOiB7Im5hbWUiOiAiUG" +
-                 "llY2Ugb2YgQ2FrZSIsICJwcmljZSI6ICIxMC41MCIsICJwcmljZVRpZXI" +
-                 "iOiAxLCAicHJvZHVjdGRhdGEiOiAidHJhbnNhY3Rpb25faWQ9ODYiLCAi" +
-                 "Y3VycmVuY3lDb2RlIjogIlVTRCIsICJkZXNjcmlwdGlvbiI6ICJWaXJ0d" +
-                 "WFsIGNob2NvbGF0ZSBjYWtlIHRvIGZpbGwgeW91ciB2aXJ0dWFsIHR1bW" +
-                 "15In0sICJleHAiOiAxMzUyMjMyNzkyLCAiaWF0IjogMTM1MjIyOTE5Miw" +
-                 "gInR5cCI6ICJtb2NrL3BheW1lbnRzL2luYXBwL3YxIn0.QZxc62USCy4U" +
-                 "IyKIC1TKelVhNklvk-Ou1l_daKntaFI";
-
-  testGetPaymentRequest(null, {
-    jwt: wrongJwt,
-    ret: true,
-    error: "PAY_REQUEST_ERROR_ERROR_DECODING_JWT"
-  });
-
-  run_next_test();
-});
-
-add_test(function test_non_https_provider() {
-  let providers = {};
-  let type = "mock/payments/inapp/v1";
-  providers[type] = {
-    name: "mockprovider",
-    description: "Mock Payment Provider",
-    uri: "http://mockpayprovider.phpfogapp.com/?req=",
-    requestMethod: "GET"
-  };
-
-  // Payload
-  //  {
-  //    "aud": "mockpayprovider.phpfogapp.com",
-  //    "iss": "Enter you app key here!",
-  //    "request": {
-  //      "name": "Piece of Cake",
-  //      "price": "10.50",
-  //      "priceTier": 1,
-  //      "productdata": "transaction_id=86",
-  //      "currencyCode": "USD",
-  //      "description": "Virtual chocolate cake to fill your virtual tummy"
-  //    },
-  //    "exp": 1352232792,
-  //    "iat": 1352229192,
-  //    "typ": "mock/payments/inapp/v1"
-  //  }
-  let jwt = "eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.eyJhdWQiOiAibW9j" +
-            "a3BheXByb3ZpZGVyLnBocGZvZ2FwcC5jb20iLCAiaXNzIjogIkVudGVyI" +
-            "HlvdSBhcHAga2V5IGhlcmUhIiwgInJlcXVlc3QiOiB7Im5hbWUiOiAiUG" +
-            "llY2Ugb2YgQ2FrZSIsICJwcmljZSI6ICIxMC41MCIsICJwcmljZVRpZXI" +
-            "iOiAxLCAicHJvZHVjdGRhdGEiOiAidHJhbnNhY3Rpb25faWQ9ODYiLCAi" +
-            "Y3VycmVuY3lDb2RlIjogIlVTRCIsICJkZXNjcmlwdGlvbiI6ICJWaXJ0d" +
-            "WFsIGNob2NvbGF0ZSBjYWtlIHRvIGZpbGwgeW91ciB2aXJ0dWFsIHR1bW" +
-            "15In0sICJleHAiOiAxMzUyMjMyNzkyLCAiaWF0IjogMTM1MjIyOTE5Miw" +
-            "gInR5cCI6ICJtb2NrL3BheW1lbnRzL2luYXBwL3YxIn0.QZxc62USCy4U" +
-            "IyKIC1TKelVhNklvk-Ou1l_daKntaFI";
-
-  testGetPaymentRequest(providers, {
-    jwt: jwt,
-    ret: true,
-    error: "INTERNAL_ERROR_NON_HTTPS_PROVIDER_URI"
-  });
-
-  run_next_test();
-});
deleted file mode 100644
--- a/dom/payment/tests/unit/xpcshell.ini
+++ /dev/null
@@ -1,6 +0,0 @@
-[DEFAULT]
-head = header_helper.js
-tail =
-skip-if = toolkit == 'gonk'
-
-[test_paymanager_get_payment_request.js]
deleted file mode 100644
--- a/dom/webidl/MozPaymentProvider.webidl
+++ /dev/null
@@ -1,41 +0,0 @@
-/* -*- Mode: IDL; 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/.
- */
-
-dictionary PaymentIccInfo {
-  DOMString mcc;
-  DOMString mnc;
-  DOMString iccId;
-  boolean dataPrimary;
-};
-
-dictionary PaymentSmsMessage {
-  DOMString iccId;
-  DOMString sender;
-  DOMString body;
-  DOMTimeStamp timestamp;
-  DOMTimeStamp sentTimestamp;
-};
-
-callback SilentSmsCallback = void (optional PaymentSmsMessage message);
-
-[NavigatorProperty="mozPaymentProvider",
- NoInterfaceObject,
- HeaderFile="mozilla/dom/PaymentProviderUtils.h",
- Func="mozilla::dom::PaymentProviderUtils::EnabledForScope",
- JSImplementation="@mozilla.org/payment/provider;1"]
-interface PaymentProvider {
-  readonly attribute DOMString? paymentServiceId;
-  // We expose to the payment provider the information of all the SIMs
-  // available in the device.
-  [Cached, Pure] readonly attribute sequence<PaymentIccInfo>? iccInfo;
-
-  void paymentSuccess(optional DOMString result);
-  void paymentFailed(optional DOMString error);
-
-  DOMRequest sendSilentSms(DOMString number, DOMString message);
-  void observeSilentSms(DOMString number, SilentSmsCallback callback);
-  void removeSilentSmsObserver(DOMString number, SilentSmsCallback callback);
-};
--- a/dom/webidl/Navigator.webidl
+++ b/dom/webidl/Navigator.webidl
@@ -170,33 +170,16 @@ partial interface Navigator {
 callback interface MozIdleObserver {
   // Time is in seconds and is read only when idle observers are added
   // and removed.
   readonly attribute unsigned long time;
   void onidle();
   void onactive();
 };
 
-#ifdef MOZ_B2G
-dictionary MobileIdOptions {
-  boolean forceSelection = false;
-};
-
-[NoInterfaceObject]
-interface NavigatorMobileId {
-    // Ideally we would use [CheckAnyPermissions] here, but the "mobileid"
-    // permission is set to PROMPT_ACTION and [CheckAnyPermissions] only checks
-    // for ALLOW_ACTION.
-    // XXXbz what is this promise resolved with?
-    [NewObject, Func="Navigator::HasMobileIdSupport"]
-    Promise<any> getMobileIdAssertion(optional MobileIdOptions options);
-};
-Navigator implements NavigatorMobileId;
-#endif // MOZ_B2G
-
 // nsIDOMNavigator
 partial interface Navigator {
   [Throws, Constant, Cached]
   readonly attribute DOMString oscpu;
   // WebKit/Blink support this; Trident/Presto do not.
   readonly attribute DOMString vendor;
   // WebKit/Blink supports this (hardcoded ""); Trident/Presto do not.
   readonly attribute DOMString vendorSub;
@@ -451,23 +434,12 @@ partial interface Navigator {
 
 #ifdef NIGHTLY_BUILD
 partial interface Navigator {
   [Func="Navigator::IsE10sEnabled"]
   readonly attribute boolean mozE10sEnabled;
 };
 #endif
 
-#ifdef MOZ_PAY
-partial interface Navigator {
-  [Throws, NewObject, Pref="dom.mozPay.enabled"]
-  // The 'jwts' parameter can be either a single DOMString or an array of
-  // DOMStrings. In both cases, it represents the base64url encoded and
-  // digitally signed payment information. Each payment provider should
-  // define its supported JWT format.
-  DOMRequest mozPay(any jwts);
-};
-#endif
-
 [NoInterfaceObject, Exposed=(Window,Worker)]
 interface NavigatorConcurrentHardware {
   readonly attribute unsigned long long hardwareConcurrency;
 };
--- a/dom/webidl/moz.build
+++ b/dom/webidl/moz.build
@@ -913,21 +913,16 @@ if CONFIG['MOZ_EME']:
         'MediaKeys.webidl',
         'MediaKeySession.webidl',
         'MediaKeysRequestStatus.webidl',
         'MediaKeyStatusMap.webidl',
         'MediaKeySystemAccess.webidl',
         'WidevineCDMManifest.webidl',
     ]
 
-if CONFIG['MOZ_PAY']:
-    WEBIDL_FILES += [
-        'MozPaymentProvider.webidl'
-    ]
-
 if CONFIG['MOZ_B2G']:
     WEBIDL_FILES += [
         'Apps.webidl',
         'Identity.webidl',
         'MozApplicationEvent.webidl'
     ]
     GENERATED_EVENTS_WEBIDL_FILES += [
         'MozApplicationEvent.webidl'
--- a/dom/workers/RuntimeService.cpp
+++ b/dom/workers/RuntimeService.cpp
@@ -2119,17 +2119,17 @@ RuntimeService::GetWorkersForWindow(nsPI
   }
 }
 
 void
 RuntimeService::CancelWorkersForWindow(nsPIDOMWindowInner* aWindow)
 {
   AssertIsOnMainThread();
 
-  AutoTArray<WorkerPrivate*, MAX_WORKERS_PER_DOMAIN> workers;
+  nsTArray<WorkerPrivate*> workers;
   GetWorkersForWindow(aWindow, workers);
 
   if (!workers.IsEmpty()) {
     for (uint32_t index = 0; index < workers.Length(); index++) {
       WorkerPrivate*& worker = workers[index];
 
       if (worker->IsSharedWorker()) {
         worker->CloseSharedWorkersForWindow(aWindow);
@@ -2141,59 +2141,59 @@ RuntimeService::CancelWorkersForWindow(n
 }
 
 void
 RuntimeService::FreezeWorkersForWindow(nsPIDOMWindowInner* aWindow)
 {
   AssertIsOnMainThread();
   MOZ_ASSERT(aWindow);
 
-  AutoTArray<WorkerPrivate*, MAX_WORKERS_PER_DOMAIN> workers;
+  nsTArray<WorkerPrivate*> workers;
   GetWorkersForWindow(aWindow, workers);
 
   for (uint32_t index = 0; index < workers.Length(); index++) {
     workers[index]->Freeze(aWindow);
   }
 }
 
 void
 RuntimeService::ThawWorkersForWindow(nsPIDOMWindowInner* aWindow)
 {
   AssertIsOnMainThread();
   MOZ_ASSERT(aWindow);
 
-  AutoTArray<WorkerPrivate*, MAX_WORKERS_PER_DOMAIN> workers;
+  nsTArray<WorkerPrivate*> workers;
   GetWorkersForWindow(aWindow, workers);
 
   for (uint32_t index = 0; index < workers.Length(); index++) {
     workers[index]->Thaw(aWindow);
   }
 }
 
 void
 RuntimeService::SuspendWorkersForWindow(nsPIDOMWindowInner* aWindow)
 {
   AssertIsOnMainThread();
   MOZ_ASSERT(aWindow);
 
-  AutoTArray<WorkerPrivate*, MAX_WORKERS_PER_DOMAIN> workers;
+  nsTArray<WorkerPrivate*> workers;
   GetWorkersForWindow(aWindow, workers);
 
   for (uint32_t index = 0; index < workers.Length(); index++) {
     workers[index]->Suspend();
   }
 }
 
 void
 RuntimeService::ResumeWorkersForWindow(nsPIDOMWindowInner* aWindow)
 {
   AssertIsOnMainThread();
   MOZ_ASSERT(aWindow);
 
-  AutoTArray<WorkerPrivate*, MAX_WORKERS_PER_DOMAIN> workers;
+  nsTArray<WorkerPrivate*> workers;
   GetWorkersForWindow(aWindow, workers);
 
   for (uint32_t index = 0; index < workers.Length(); index++) {
     workers[index]->Resume();
   }
 }
 
 nsresult
--- a/dom/workers/test/mochitest.ini
+++ b/dom/workers/test/mochitest.ini
@@ -139,17 +139,16 @@ support-files =
 [test_bug1036484.html]
 [test_bug1060621.html]
 [test_bug1062920.html]
 [test_bug1063538.html]
 [test_bug1104064.html]
 [test_bug1132395.html]
 skip-if = true # bug 1176225
 [test_bug1132924.html]
-[test_bug1241485.html]
 [test_chromeWorker.html]
 [test_clearTimeouts.html]
 [test_close.html]
 [test_closeOnGC.html]
 [test_console.html]
 [test_consoleAndBlobs.html]
 [test_consoleReplaceable.html]
 [test_consoleSharedWorkers.html]
deleted file mode 100644
--- a/dom/workers/test/test_bug1241485.html
+++ /dev/null
@@ -1,84 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=1241485
--->
-<head>
-  <meta charset="utf-8">
-  <title>Test for Bug 1241485</title>
-  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-  <script type="application/javascript">
-
-  /** Test for Bug 1241485 **/
-SimpleTest.waitForExplicitFinish();
-SimpleTest.requestCompleteLog();
-SimpleTest.requestFlakyTimeout("requestFlakyTimeout is silly.");
-
-var limit = 10;
-
-SpecialPowers.pushPrefEnv({"set":[["dom.workers.maxPerDomain", limit]] },
-function() {
-  var workers = new Array();
-  var workerToWait = null;
-  var url = URL.createObjectURL(new Blob(["postMessage('loaded');"]));
-  var timeouts = new Array();
-
-  function addTimeout(fn, time) {
-    timeouts.push(setTimeout(fn, time));
-  }
-
-  function createWorker() {
-    workerToWait = new Worker(url);
-    workerToWait.onmessage = function(e) {
-        if (!workers) {
-          // finish() has been called already.
-          return;
-        }
-        workers.push(workerToWait);
-        info(workers.length + " workers");
-        addTimeout(createWorker, 0);
-        if (workers.length == limit) {
-          // Just give the worker creation loop some more time to try to
-          // create more workers to check that we don't go over the limit.
-          addTimeout(finish, 250);
-        }
-      };
-  }
-
-  function finish() {
-    for (var i = 0; i < timeouts.length; ++i) {
-      clearTimeout(timeouts[i]);
-    }
-
-    if (workerToWait) {
-      workerToWait.onmessage = null;
-    }
-
-    ok(workers.length <= limit, "Too many workers created!");
-
-    workers = null;
-    SpecialPowers.gc();
-
-    SimpleTest.finish();
-  }
-
-  info("Expecting no more than " + limit + " workers.");
-  // Make sure we finish at some point, even if creating workers takes
-  // lots of time.
-  addTimeout(finish, 10000);
-  addTimeout(createWorker, 0);
-});
-
-  </script>
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1241485">Mozilla Bug 1241485</a>
-<p id="display"></p>
-<div id="content" style="display: none">
-
-</div>
-<pre id="test">
-</pre>
-</body>
-</html>
--- a/editor/libeditor/HTMLEditRules.cpp
+++ b/editor/libeditor/HTMLEditRules.cpp
@@ -2289,48 +2289,34 @@ HTMLEditRules::WillDeleteSelection(Selec
         // Are the blocks siblings?
         nsCOMPtr<nsINode> leftBlockParent = leftParent->GetParentNode();
         nsCOMPtr<nsINode> rightBlockParent = rightParent->GetParentNode();
 
         // MOOSE: this could conceivably screw up a table.. fix me.
         NS_ENSURE_STATE(mHTMLEditor);
         if (leftBlockParent == rightBlockParent &&
             mHTMLEditor->NodesSameType(GetAsDOMNode(leftParent),
-                                       GetAsDOMNode(rightParent))) {
-          if (leftParent->IsHTMLElement(nsGkAtoms::p)) {
-            // First delete the selection
-            NS_ENSURE_STATE(mHTMLEditor);
-            res = mHTMLEditor->DeleteSelectionImpl(aAction, aStripWrappers);
-            NS_ENSURE_SUCCESS(res, res);
-            // Then join paragraphs, insert break
-            NS_ENSURE_STATE(mHTMLEditor);
-            EditorDOMPoint pt =
-              mHTMLEditor->JoinNodeDeep(*leftParent, *rightParent);
-            NS_ENSURE_STATE(pt.node);
-            // Fix up selection
-            res = aSelection->Collapse(pt.node, pt.offset);
-            NS_ENSURE_SUCCESS(res, res);
-            return NS_OK;
-          }
-          if (HTMLEditUtils::IsListItem(leftParent) ||
-              HTMLEditUtils::IsHeader(*leftParent)) {
+                                       GetAsDOMNode(rightParent)) &&
+            // XXX What's special about these three types of block?
+            (leftParent->IsHTMLElement(nsGkAtoms::p) ||
+             HTMLEditUtils::IsListItem(leftParent) ||
+             HTMLEditUtils::IsHeader(*leftParent))) {
             // First delete the selection
             NS_ENSURE_STATE(mHTMLEditor);
             res = mHTMLEditor->DeleteSelectionImpl(aAction, aStripWrappers);
             NS_ENSURE_SUCCESS(res, res);
             // Join blocks
             NS_ENSURE_STATE(mHTMLEditor);
             EditorDOMPoint pt =
               mHTMLEditor->JoinNodeDeep(*leftParent, *rightParent);
             NS_ENSURE_STATE(pt.node);
             // Fix up selection
             res = aSelection->Collapse(pt.node, pt.offset);
             NS_ENSURE_SUCCESS(res, res);
             return NS_OK;
-          }
         }
 
         // Else blocks not same type, or not siblings.  Delete everything
         // except table elements.
         join = true;
 
         uint32_t rangeCount = aSelection->RangeCount();
         for (uint32_t rangeIdx = 0; rangeIdx < rangeCount; ++rangeIdx) {
@@ -2495,28 +2481,30 @@ HTMLEditRules::InsertBRIfNeeded(Selectio
       return br ? NS_OK : NS_ERROR_FAILURE;
     }
   }
   return NS_OK;
 }
 
 /**
  * GetGoodSelPointForNode() finds where at a node you would want to set the
- * selection if you were trying to have a caret next to it.
+ * selection if you were trying to have a caret next to it.  Always returns a
+ * valid value (unless mHTMLEditor has gone away).
  *
  * @param aNode         The node
  * @param aAction       Which edge to find: eNext indicates beginning,
  *                      ePrevious ending.
  */
 EditorDOMPoint
 HTMLEditRules::GetGoodSelPointForNode(nsINode& aNode,
                                       nsIEditor::EDirection aAction)
 {
   NS_ENSURE_TRUE(mHTMLEditor, EditorDOMPoint());
-  if (aNode.GetAsText() || mHTMLEditor->IsContainer(&aNode)) {
+  if (aNode.GetAsText() || mHTMLEditor->IsContainer(&aNode) ||
+      NS_WARN_IF(!aNode.GetParentNode())) {
     return EditorDOMPoint(&aNode,
                           aAction == nsIEditor::ePrevious ? aNode.Length() : 0);
   }
 
   EditorDOMPoint ret;
   ret.node = aNode.GetParentNode();
   ret.offset = ret.node ? ret.node->IndexOf(&aNode) : -1;
   NS_ENSURE_TRUE(mHTMLEditor, EditorDOMPoint());
@@ -4831,34 +4819,36 @@ HTMLEditRules::CheckForEmptyBlock(nsINod
           res = aSelection->Collapse(listParent, listOffset);
           NS_ENSURE_SUCCESS(res, res);
         }
         // Else just let selection percolate up.  We'll adjust it in
         // AfterEdit()
       }
     } else {
       if (aAction == nsIEditor::eNext) {
-        // Adjust selection to be right after it.
-        res = aSelection->Collapse(blockParent, offset + 1);
-        NS_ENSURE_SUCCESS(res, res);
-
-        // Move to the start of the next node if it's a text.
+        // Move to the start of the next node, if any
         nsCOMPtr<nsIContent> nextNode = mHTMLEditor->GetNextNode(blockParent,
                                                                  offset + 1, true);
-        if (nextNode && mHTMLEditor->IsTextNode(nextNode)) {
-          res = aSelection->Collapse(nextNode, 0);
+        if (nextNode) {
+          EditorDOMPoint pt = GetGoodSelPointForNode(*nextNode, aAction);
+          res = aSelection->Collapse(pt.node, pt.offset);
+          NS_ENSURE_SUCCESS(res, res);
+        } else {
+          // Adjust selection to be right after it.
+          res = aSelection->Collapse(blockParent, offset + 1);
           NS_ENSURE_SUCCESS(res, res);
         }
       } else {
-        // Move to the end of the previous node if it's a text.
+        // Move to the end of the previous node
         nsCOMPtr<nsIContent> priorNode = mHTMLEditor->GetPriorNode(blockParent,
                                                                    offset,
                                                                    true);
-        if (priorNode && mHTMLEditor->IsTextNode(priorNode)) {
-          res = aSelection->Collapse(priorNode, priorNode->TextLength());
+        if (priorNode) {
+          EditorDOMPoint pt = GetGoodSelPointForNode(*priorNode, aAction);
+          res = aSelection->Collapse(pt.node, pt.offset);
           NS_ENSURE_SUCCESS(res, res);
         } else {
           res = aSelection->Collapse(blockParent, offset + 1);
           NS_ENSURE_SUCCESS(res, res);
         }
       }
     }
     NS_ENSURE_STATE(mHTMLEditor);
@@ -7367,36 +7357,25 @@ HTMLEditRules::AdjustSelection(Selection
   // look for a nearby text node.
   // prefer the correct direction.
   nsCOMPtr<nsIDOMNode> nearNodeDOM = GetAsDOMNode(nearNode);
   res = FindNearSelectableNode(GetAsDOMNode(selNode), selOffset, aAction,
                                address_of(nearNodeDOM));
   NS_ENSURE_SUCCESS(res, res);
   nearNode = do_QueryInterface(nearNodeDOM);
 
-  if (nearNode)
-  {
-    // is the nearnode a text node?
-    textNode = do_QueryInterface(nearNode);
-    if (textNode)
-    {
-      int32_t offset = 0;
-      // put selection in right place:
-      if (aAction == nsIEditor::ePrevious)
-        textNode->GetLength((uint32_t*)&offset);
-      res = aSelection->Collapse(nearNode,offset);
-    }
-    else  // must be break or image
-    {
-      selNode = EditorBase::GetNodeLocation(nearNode, &selOffset);
-      if (aAction == nsIEditor::ePrevious) selOffset++;  // want to be beyond it if we backed up to it
-      res = aSelection->Collapse(selNode, selOffset);
-    }
-  }
-  return res;
+  if (!nearNode) {
+    return NS_OK;
+  }
+  EditorDOMPoint pt = GetGoodSelPointForNode(*nearNode, aAction);
+  res = aSelection->Collapse(pt.node, pt.offset);
+  if (NS_WARN_IF(NS_FAILED(res))) {
+    return res;
+  }
+  return NS_OK;
 }
 
 
 nsresult
 HTMLEditRules::FindNearSelectableNode(nsIDOMNode* aSelNode,
                                       int32_t aSelOffset,
                                       nsIEditor::EDirection& aDirection,
                                       nsCOMPtr<nsIDOMNode>* outSelectableNode)
--- a/editor/libeditor/HTMLEditor.cpp
+++ b/editor/libeditor/HTMLEditor.cpp
@@ -948,35 +948,40 @@ HTMLEditor::IsPrevCharInNodeWhitespace(n
 bool
 HTMLEditor::IsVisBreak(nsINode* aNode)
 {
   MOZ_ASSERT(aNode);
   if (!TextEditUtils::IsBreak(aNode)) {
     return false;
   }
   // Check if there is a later node in block after br
-  nsCOMPtr<nsINode> priorNode = GetPriorHTMLNode(aNode, true);
-  if (priorNode && TextEditUtils::IsBreak(priorNode)) {
-    return true;
-  }
   nsCOMPtr<nsINode> nextNode = GetNextHTMLNode(aNode, true);
   if (nextNode && TextEditUtils::IsBreak(nextNode)) {
     return true;
   }
 
-  // If we are right before block boundary, then br not visible
+  // A single line break before a block boundary is not displayed, so e.g.
+  // foo<p>bar<br></p> and foo<br><p>bar</p> display the same as foo<p>bar</p>.
+  // But if there are multiple <br>s in a row, all but the last are visible.
   if (!nextNode) {
     // This break is trailer in block, it's not visible
     return false;
   }
   if (IsBlockNode(nextNode)) {
     // Break is right before a block, it's not visible
     return false;
   }
 
+  // If there's an inline node after this one that's not a break, and also a
+  // prior break, this break must be visible.
+  nsCOMPtr<nsINode> priorNode = GetPriorHTMLNode(aNode, true);
+  if (priorNode && TextEditUtils::IsBreak(priorNode)) {
+    return true;
+  }
+
   // Sigh.  We have to use expensive whitespace calculation code to
   // determine what is going on
   int32_t selOffset;
   nsCOMPtr<nsINode> selNode = GetNodeLocation(aNode, &selOffset);
   // Let's look after the break
   selOffset++;
   WSRunObject wsObj(this, selNode, selOffset);
   nsCOMPtr<nsINode> unused;
--- a/js/public/GCAPI.h
+++ b/js/public/GCAPI.h
@@ -60,17 +60,17 @@ namespace JS {
     D(ALLOC_TRIGGER)                            \
     D(DEBUG_GC)                                 \
     D(COMPARTMENT_REVIVED)                      \
     D(RESET)                                    \
     D(OUT_OF_NURSERY)                           \
     D(EVICT_NURSERY)                            \
     D(FULL_STORE_BUFFER)                        \
     D(SHARED_MEMORY_LIMIT)                      \
-    D(PERIODIC_FULL_GC)                         \
+    D(UNUSED1)                                  \
     D(INCREMENTAL_TOO_SLOW)                     \
     D(ABORT_GC)                                 \
                                                 \
     /* These are reserved for future use. */    \
     D(RESERVED0)                                \
     D(RESERVED1)                                \
     D(RESERVED2)                                \
     D(RESERVED3)                                \
--- a/js/src/gc/GCRuntime.h
+++ b/js/src/gc/GCRuntime.h
@@ -454,24 +454,16 @@ class GCSchedulingTunables
  *      phase, we have a highFrequencyGCMode that ups the growth rate to 300%
  *      of the current size[retained] so that we'll do fewer longer GCs at the
  *      end of the mutator startup rather than more, smaller GCs.
  *
  *          Assumptions:
  *            -> Responsiveness is proportional to t[marking] + t[sweeping].
  *            -> size[retained] is proportional only to GC allocations.
  *
- *      PERIODIC_FULL_GC
- *      ----------------
- *      When we return to the event loop and it has been 20 seconds since we've
- *      done a GC, we start an incremenal, all-zones, shrinking GC.
- *
- *          Assumptions:
- *            -> Our triggers are incomplete.
- *
  *      ALLOC_TRIGGER (non-incremental)
  *      -------------------------------
  *      If we do not return to the event loop before getting all the way to our
  *      gc trigger bytes then MAYBEGC will never fire. To avoid OOMing, we
  *      succeed the current allocation and set the script interrupt so that we
  *      will (hopefully) do a GC before we overflow our max and have to raise
  *      an OOM exception for the script.
  *
@@ -618,18 +610,17 @@ class GCRuntime
 
     MOZ_MUST_USE bool setParameter(JSGCParamKey key, uint32_t value, AutoLockGC& lock);
     uint32_t getParameter(JSGCParamKey key, const AutoLockGC& lock);
 
     MOZ_MUST_USE bool triggerGC(JS::gcreason::Reason reason);
     void maybeAllocTriggerZoneGC(Zone* zone, const AutoLockGC& lock);
     // The return value indicates if we were able to do the GC.
     bool triggerZoneGC(Zone* zone, JS::gcreason::Reason reason);
-    MOZ_MUST_USE bool maybeGC(Zone* zone);
-    void maybePeriodicFullGC();
+    void maybeGC(Zone* zone);
     void minorGC(JS::gcreason::Reason reason,
                  gcstats::Phase phase = gcstats::PHASE_MINOR_GC) JS_HAZ_GC_CALL;
     void evictNursery(JS::gcreason::Reason reason = JS::gcreason::EVICT_NURSERY) {
         minorGC(reason, gcstats::PHASE_EVICT_NURSERY);
     }
     // The return value indicates whether a major GC was performed.
     bool gcIfRequested();
     void gc(JSGCInvocationKind gckind, JS::gcreason::Reason reason);
@@ -1067,17 +1058,16 @@ class GCRuntime
     /*
      * Number of the committed arenas in all GC chunks including empty chunks.
      */
     mozilla::Atomic<uint32_t, mozilla::ReleaseAcquire> numArenasFreeCommitted;
     VerifyPreTracer* verifyPreData;
 
   private:
     bool chunkAllocationSinceLastGC;
-    int64_t nextFullGCTime;
     int64_t lastGCTime;
 
     JSGCMode mode;
 
     mozilla::Atomic<size_t, mozilla::ReleaseAcquire> numActiveZoneIters;
 
     uint64_t decommitThreshold;
 
--- a/js/src/gc/Nursery.cpp
+++ b/js/src/gc/Nursery.cpp
@@ -153,18 +153,18 @@ js::Nursery::init(uint32_t maxNurseryByt
         return false;
 
     setCurrentChunk(0);
     setStartPosition();
 
     char* env = getenv("JS_GC_PROFILE_NURSERY");
     if (env) {
         if (0 == strcmp(env, "help")) {
-            fprintf(stderr, "JS_GC_PROFILE_NURSERY=N\n\n"
-                    "\tReport minor GC's taking more than N microseconds.");
+            fprintf(stderr, "JS_GC_PROFILE_NURSERY=N\n"
+                    "\tReport minor GC's taking more than N microseconds.\n");
             exit(0);
         }
         enableProfiling_ = true;
         profileThreshold_ = atoi(env);
     }
 
     PodZero(&startTimes_);
     PodZero(&profileTimes_);
--- a/js/src/gc/Statistics.cpp
+++ b/js/src/gc/Statistics.cpp
@@ -753,38 +753,53 @@ Statistics::Statistics(JSRuntime* rt)
     timedGCStart(0),
     preBytes(0),
     maxPauseInInterval(0),
     phaseNestingDepth(0),
     activeDagSlot(PHASE_DAG_NONE),
     suspended(0),
     sliceCallback(nullptr),
     nurseryCollectionCallback(nullptr),
-    aborted(false)
+    aborted(false),
+    enableProfiling_(false),
+    sliceCount_(0)
 {
     PodArrayZero(phaseTotals);
     PodArrayZero(counts);
     PodArrayZero(phaseStartTimes);
     for (auto d : MakeRange(NumTimingArrays))
         PodArrayZero(phaseTimes[d]);
 
-    char* env = getenv("MOZ_GCTIMER");
+    const char* env = getenv("MOZ_GCTIMER");
     if (env) {
         if (strcmp(env, "none") == 0) {
             fp = nullptr;
         } else if (strcmp(env, "stdout") == 0) {
             fp = stdout;
         } else if (strcmp(env, "stderr") == 0) {
             fp = stderr;
         } else {
             fp = fopen(env, "a");
             if (!fp)
                 MOZ_CRASH("Failed to open MOZ_GCTIMER log file.");
         }
     }
+
+    env = getenv("JS_GC_PROFILE");
+    if (env) {
+        if (0 == strcmp(env, "help")) {
+            fprintf(stderr, "JS_GC_PROFILE=N\n"
+                    "\tReport major GC's taking more than N milliseconds.\n");
+            exit(0);
+        }
+        enableProfiling_ = true;
+        profileThreshold_ = atoi(env);
+    }
+
+    PodZero(&totalTimes_);
 }
 
 Statistics::~Statistics()
 {
     if (fp && fp != stdout && fp != stderr)
         fclose(fp);
 }
 
@@ -1041,22 +1056,27 @@ Statistics::endSlice()
                 runtime->addTelemetry(JS_TELEMETRY_GC_ANIMATION_MS, t(sliceTime));
 
             // Record any phase that goes more than 2x over its budget.
             if (sliceTime > 2 * budget_ms * 1000) {
                 Phase longest = LongestPhase(slices.back().phaseTimes);
                 runtime->addTelemetry(JS_TELEMETRY_GC_SLOW_PHASE, phases[longest].telemetryBucket);
             }
         }
+
+        sliceCount_++;
     }
 
     bool last = !runtime->gc.isIncrementalGCInProgress();
     if (last)
         endGC();
 
+    if (enableProfiling_ && !aborted && slices.back().duration() >= profileThreshold_)
+        printSliceProfile();
+
     // Slice callbacks should only fire for the outermost level.
     if (gcDepth == 1 && !aborted) {
         bool wasFullGC = zoneStats.isCollectingAllZones();
         if (sliceCallback)
             (*sliceCallback)(runtime->contextFromMainThread(),
                              last ? JS::GC_CYCLE_END : JS::GC_SLICE_END,
                              JS::GCDescription(!wasFullGC, gckind, slices.back().reason));
     }
@@ -1254,8 +1274,64 @@ Statistics::computeMMU(int64_t window) c
         if (slices[endIndex].end - slices[startIndex].start > window)
             cur -= (slices[endIndex].end - slices[startIndex].start - window);
         if (cur > gcMax)
             gcMax = cur;
     }
 
     return double(window - gcMax) / window;
 }
+
+/* static */ void
+Statistics::printProfileHeader()
+{
+    fprintf(stderr, " %6s", "total");
+#define PRINT_PROFILE_HEADER(name, text, phase)                               \
+    fprintf(stderr, " %6s", text);
+FOR_EACH_GC_PROFILE_TIME(PRINT_PROFILE_HEADER)
+#undef PRINT_PROFILE_HEADER
+    fprintf(stderr, "\n");
+}
+
+/* static */ void
+Statistics::printProfileTimes(const ProfileTimes& times)
+{
+    for (auto time : times)
+        fprintf(stderr, " %6" PRIi64, time / PRMJ_USEC_PER_MSEC);
+    fprintf(stderr, "\n");
+}
+
+void
+Statistics::printSliceProfile()
+{
+    const SliceData& slice = slices.back();
+
+    static int printedHeader = 0;
+    if ((printedHeader++ % 200) == 0) {
+        fprintf(stderr, "MajorGC:               Reason States      ");
+        printProfileHeader();
+    }
+
+    fprintf(stderr, "MajorGC: %20s %1d -> %1d      ",
+            ExplainReason(slice.reason), slice.initialState, slice.finalState);
+
+    ProfileTimes times;
+    times[ProfileKey::Total] = slice.duration();
+    totalTimes_[ProfileKey::Total] += times[ProfileKey::Total];
+
+#define GET_PROFILE_TIME(name, text, phase)                                   \
+    times[ProfileKey::name] = slice.phaseTimes[PHASE_DAG_NONE][phase];                     \
+    totalTimes_[ProfileKey::name] += times[ProfileKey::name];
+FOR_EACH_GC_PROFILE_TIME(GET_PROFILE_TIME)
+#undef GET_PROFILE_TIME
+
+    printProfileTimes(times);
+}
+
+void
+Statistics::printTotalProfileTimes()
+{
+    if (enableProfiling_) {
+        fprintf(stderr, "MajorGC TOTALS: %7" PRIu64 " slices:           ", sliceCount_);
+        printProfileTimes(totalTimes_);
+    }
+}
+
--- a/js/src/gc/Statistics.h
+++ b/js/src/gc/Statistics.h
@@ -2,16 +2,17 @@
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * 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 gc_Statistics_h
 #define gc_Statistics_h
 
+#include "mozilla/EnumeratedArray.h"
 #include "mozilla/IntegerRange.h"
 #include "mozilla/PodOperations.h"
 
 #include "jsalloc.h"
 #include "jsgc.h"
 #include "jspubtd.h"
 
 #include "js/GCAPI.h"
@@ -129,16 +130,28 @@ struct ZoneGCStats
     bool isCollectingAllZones() const { return collectedZoneCount == zoneCount; }
 
     ZoneGCStats()
       : collectedZoneCount(0), zoneCount(0), sweptZoneCount(0),
         collectedCompartmentCount(0), compartmentCount(0), sweptCompartmentCount(0)
     {}
 };
 
+#define FOR_EACH_GC_PROFILE_TIME(_)                                           \
+    _(BeginCallback, "beginCB",  PHASE_GC_BEGIN)                              \
+    _(WaitBgThread,  "waitBG",   PHASE_WAIT_BACKGROUND_THREAD)                \
+    _(DiscardCode,   "discard",  PHASE_MARK_DISCARD_CODE)                     \
+    _(RelazifyFunc,  "relazify", PHASE_RELAZIFY_FUNCTIONS)                    \
+    _(Purge,         "purge",    PHASE_PURGE)                                 \
+    _(Mark,          "mark",     PHASE_MARK)                                  \
+    _(Sweep,         "sweep",    PHASE_SWEEP)                                 \
+    _(Compact,       "compact",  PHASE_COMPACT)                               \
+    _(EndCallback,   "endCB",    PHASE_GC_END)                                \
+    _(Barriers,      "barriers", PHASE_BARRIER)
+
 /*
  * Struct for collecting timing statistics on a "phase tree". The tree is
  * specified as a limited DAG, but the timings are collected for the whole tree
  * that you would get by expanding out the DAG by duplicating subtrees rooted
  * at nodes with multiple parents.
  *
  * During execution, a child phase can be activated multiple times, and the
  * total time will be accumulated. (So for example, you can start and end
@@ -275,16 +288,19 @@ struct Statistics
     };
 
     typedef Vector<SliceData, 8, SystemAllocPolicy> SliceDataVector;
     typedef SliceDataVector::ConstRange SliceRange;
 
     SliceRange sliceRange() const { return slices.all(); }
     size_t slicesLength() const { return slices.length(); }
 
+    /* Print total profile times on shutdown. */
+    void printTotalProfileTimes();
+
   private:
     JSRuntime* runtime;
 
     int64_t startupTime;
 
     /* File pointer used for MOZ_GCTIMER output. */
     FILE* fp;
 
@@ -346,16 +362,35 @@ struct Statistics
     JS::GCNurseryCollectionCallback nurseryCollectionCallback;
 
     /*
      * True if we saw an OOM while allocating slices. The statistics for this
      * GC will be invalid.
      */
     bool aborted;
 
+    /* Profiling data. */
+
+    enum class ProfileKey
+    {
+        Total,
+#define DEFINE_TIME_KEY(name, text, phase)                                    \
+        name,
+FOR_EACH_GC_PROFILE_TIME(DEFINE_TIME_KEY)
+#undef DEFINE_TIME_KEY
+        KeyCount
+    };
+
+    using ProfileTimes = mozilla::EnumeratedArray<ProfileKey, ProfileKey::KeyCount, int64_t>;
+
+    int64_t profileThreshold_;
+    bool enableProfiling_;
+    ProfileTimes totalTimes_;
+    uint64_t sliceCount_;
+
     void beginGC(JSGCInvocationKind kind);
     void endGC();
 
     void recordPhaseEnd(Phase phase);
 
     void gcDuration(int64_t* total, int64_t* maxPause) const;
     void sccDurations(int64_t* total, int64_t* maxPause);
     void printStats();
@@ -367,16 +402,20 @@ struct Statistics
     UniqueChars formatDetailedPhaseTimes(const PhaseTimeTable phaseTimes);
     UniqueChars formatDetailedTotals();
 
     UniqueChars formatJsonDescription(uint64_t timestamp);
     UniqueChars formatJsonSliceDescription(unsigned i, const SliceData& slice);
     UniqueChars formatJsonPhaseTimes(const PhaseTimeTable phaseTimes);
 
     double computeMMU(int64_t resolution) const;
+
+    void printSliceProfile();
+    static void printProfileHeader();
+    static void printProfileTimes(const ProfileTimes& times);
 };
 
 struct MOZ_RAII AutoGCSlice
 {
     AutoGCSlice(Statistics& stats, const ZoneGCStats& zoneStats, JSGCInvocationKind gckind,
                 SliceBudget budget, JS::gcreason::Reason reason)
       : stats(stats)
     {
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -1334,18 +1334,17 @@ JS_GC(JSContext* cx)
     JS::PrepareForFullGC(cx);
     cx->gc.gc(GC_NORMAL, JS::gcreason::API);
 }
 
 JS_PUBLIC_API(void)
 JS_MaybeGC(JSContext* cx)
 {
     GCRuntime& gc = cx->runtime()->gc;
-    if (!gc.maybeGC(cx->zone()))
-        gc.maybePeriodicFullGC();
+    gc.maybeGC(cx->zone());
 }
 
 JS_PUBLIC_API(void)
 JS_SetGCCallback(JSContext* cx, JSGCCallback cb, void* data)
 {
     AssertHeapIsIdle(cx);
     cx->gc.setGCCallback(cb, data);
 }
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -519,25 +519,25 @@ class HandleValueArray
     }
 };
 
 }  /* namespace JS */
 
 /************************************************************************/
 
 struct JSFreeOp {
-  private:
+  protected:
     JSRuntime*  runtime_;
 
-  protected:
     explicit JSFreeOp(JSRuntime* rt)
       : runtime_(rt) { }
 
   public:
     JSRuntime* runtime() const {
+        MOZ_ASSERT(runtime_);
         return runtime_;
     }
 };
 
 /* Callbacks and their arguments. */
 
 /************************************************************************/
 
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -244,19 +244,16 @@ using namespace js::gc;
 
 using mozilla::ArrayLength;
 using mozilla::Get;
 using mozilla::Maybe;
 using mozilla::Swap;
 
 using JS::AutoGCRooter;
 
-/* Perform a Full GC every 20 seconds if MaybeGC is called */
-static const uint64_t GC_IDLE_FULL_SPAN = 20 * 1000 * 1000;
-
 /* Increase the IGC marking slice time if we are in highFrequencyGC mode. */
 static const int IGC_MARK_SLICE_MULTIPLIER = 2;
 
 const AllocKind gc::slotsToThingKind[] = {
     /*  0 */ AllocKind::OBJECT0,  AllocKind::OBJECT2,  AllocKind::OBJECT2,  AllocKind::OBJECT4,
     /*  4 */ AllocKind::OBJECT4,  AllocKind::OBJECT8,  AllocKind::OBJECT8,  AllocKind::OBJECT8,
     /*  8 */ AllocKind::OBJECT8,  AllocKind::OBJECT12, AllocKind::OBJECT12, AllocKind::OBJECT12,
     /* 12 */ AllocKind::OBJECT12, AllocKind::OBJECT16, AllocKind::OBJECT16, AllocKind::OBJECT16,
@@ -489,22 +486,22 @@ FinalizeTypedArenas(FreeOp* fop,
                     Arena** src,
                     SortedArenaList& dest,
                     AllocKind thingKind,
                     SliceBudget& budget,
                     ArenaLists::KeepArenasEnum keepArenas)
 {
     // When operating in the foreground, take the lock at the top.
     Maybe<AutoLockGC> maybeLock;
-    if (!fop->onBackgroundThread())
+    if (fop->onMainThread())
         maybeLock.emplace(fop->runtime());
 
     // During background sweeping free arenas are released later on in
     // sweepBackgroundThings().
-    MOZ_ASSERT_IF(fop->onBackgroundThread(), keepArenas == ArenaLists::KEEP_ARENAS);
+    MOZ_ASSERT_IF(!fop->onMainThread(), keepArenas == ArenaLists::KEEP_ARENAS);
 
     size_t thingSize = Arena::thingSize(thingKind);
     size_t thingsPerArena = Arena::thingsPerArena(thingKind);
 
     while (Arena* arena = *src) {
         *src = arena->next;
         size_t nmarked = arena->finalize<T>(fop, thingKind, thingSize);
         size_t nfree = thingsPerArena - nmarked;
@@ -802,17 +799,16 @@ GCRuntime::GCRuntime(JSRuntime* rt) :
     marker(rt),
     usage(nullptr),
     mMemProfiler(rt),
     maxMallocBytes(0),
     nextCellUniqueId_(LargestTaggedNullCellPointer + 1), // Ensure disjoint from null tagged pointers.
     numArenasFreeCommitted(0),
     verifyPreData(nullptr),
     chunkAllocationSinceLastGC(false),
-    nextFullGCTime(0),
     lastGCTime(PRMJ_Now()),
     mode(JSGC_MODE_INCREMENTAL),
     numActiveZoneIters(0),
     decommitThreshold(32 * 1024 * 1024),
     cleanUpEverything(false),
     grayBufferState(GCRuntime::GrayBufferState::Unused),
     grayBitsValid(false),
     majorGCTriggerReason(JS::gcreason::NO_REASON),
@@ -1110,16 +1106,17 @@ GCRuntime::finish()
 
     FreeChunkPool(rt, fullChunks_);
     FreeChunkPool(rt, availableChunks_);
     FreeChunkPool(rt, emptyChunks_);
 
     FinishTrace();
 
     nursery.printTotalProfileTimes();
+    stats.printTotalProfileTimes();
 }
 
 bool
 GCRuntime::setParameter(JSGCParamKey key, uint32_t value, AutoLockGC& lock)
 {
     switch (key) {
       case JSGC_MAX_MALLOC_BYTES:
         setMaxMallocBytes(value);
@@ -2785,17 +2782,17 @@ ArenaLists::backgroundFinalize(FreeOp* f
     ArenaList finalized = finalizedSorted.toArenaList();
 
     // We must take the GC lock to be able to safely modify the ArenaList;
     // however, this does not by itself make the changes visible to all threads,
     // as not all threads take the GC lock to read the ArenaLists.
     // That safety is provided by the ReleaseAcquire memory ordering of the
     // background finalize state, which we explicitly set as the final step.
     {
-        AutoLockGC lock(fop->runtime());
+        AutoLockGC lock(lists->runtime_);
         MOZ_ASSERT(lists->backgroundFinalizeState[thingKind] == BFS_RUN);
 
         // Join |al| and |finalized| into a single list.
         *al = finalized.insertListWithCursorAtEnd(*al);
 
         lists->arenaListsToSweep[thingKind] = nullptr;
     }
 
@@ -3034,70 +3031,40 @@ GCRuntime::triggerZoneGC(Zone* zone, JS:
         return true;
     }
 
     PrepareZoneForGC(zone);
     requestMajorGC(reason);
     return true;
 }
 
-bool
+void
 GCRuntime::maybeGC(Zone* zone)
 {
     MOZ_ASSERT(CurrentThreadCanAccessRuntime(rt));
 
 #ifdef JS_GC_ZEAL
     if (hasZealMode(ZealMode::Alloc) || hasZealMode(ZealMode::Poke)) {
         JS::PrepareForFullGC(rt->contextFromMainThread());
         gc(GC_NORMAL, JS::gcreason::DEBUG_GC);
-        return true;
+        return;
     }
 #endif
 
     if (gcIfRequested())
-        return true;
+        return;
 
     if (zone->usage.gcBytes() > 1024 * 1024 &&
         zone->usage.gcBytes() >= zone->threshold.allocTrigger(schedulingState.inHighFrequencyGCMode()) &&
         !isIncrementalGCInProgress() &&
         !isBackgroundSweeping())
     {
         PrepareZoneForGC(zone);
         startGC(GC_NORMAL, JS::gcreason::EAGER_ALLOC_TRIGGER);
-        return true;
-    }
-
-    return false;
-}
-
-void
-GCRuntime::maybePeriodicFullGC()
-{
-    /*
-     * Trigger a periodic full GC.
-     *
-     * This is a source of non-determinism, but is not called from the shell.
-     *
-     * Access to the counters and, on 32 bit, setting gcNextFullGCTime below
-     * is not atomic and a race condition could trigger or suppress the GC. We
-     * tolerate this.
-     */
-#ifndef JS_MORE_DETERMINISTIC
-    int64_t now = PRMJ_Now();
-    if (nextFullGCTime && nextFullGCTime <= now && !isIncrementalGCInProgress()) {
-        if (chunkAllocationSinceLastGC ||
-            numArenasFreeCommitted > decommitThreshold)
-        {
-            JS::PrepareForFullGC(rt->contextFromMainThread());
-            startGC(GC_SHRINK, JS::gcreason::PERIODIC_FULL_GC);
-        } else {
-            nextFullGCTime = now + GC_IDLE_FULL_SPAN;
-        }
-    }
-#endif
+    }
 }
 
 // Do all possible decommit immediately from the current thread without
 // releasing the GC lock or allocating any memory.
 void
 GCRuntime::decommitAllWithoutUnlocking(const AutoLockGC& lock)
 {
     MOZ_ASSERT(emptyChunks(lock).count() == 0);
@@ -3187,17 +3154,17 @@ GCRuntime::sweepBackgroundThings(ZoneLis
 {
     freeBlocks.freeAll();
 
     if (zones.isEmpty())
         return;
 
     // We must finalize thing kinds in the order specified by BackgroundFinalizePhases.
     Arena* emptyArenas = nullptr;
-    FreeOp fop(rt, threadType);
+    FreeOp fop(threadType == MainThread ? rt : nullptr);
     for (unsigned phase = 0 ; phase < ArrayLength(BackgroundFinalizePhases) ; ++phase) {
         for (Zone* zone = zones.front(); zone; zone = zone->nextZone()) {
             for (auto kind : BackgroundFinalizePhases[phase].kinds) {
                 Arena* arenas = zone->arenas.arenaListsToSweep[kind];
                 MOZ_RELEASE_ASSERT(uintptr_t(arenas) != uintptr_t(-1));
                 if (arenas)
                     ArenaLists::backgroundFinalize(&fop, arenas, &emptyArenas);
             }
@@ -6136,20 +6103,16 @@ GCRuntime::gcCycle(bool nonincrementalBy
     /* The GC was reset, so we need a do-over. */
     if (prevState != State::NotActive && !isIncrementalGCInProgress())
         return true;
 
     TraceMajorGCStart();
 
     incrementalCollectSlice(budget, reason, session.lock);
 
-#ifndef JS_MORE_DETERMINISTIC
-    nextFullGCTime = PRMJ_Now() + GC_IDLE_FULL_SPAN;
-#endif
-
     chunkAllocationSinceLastGC = false;
 
 #ifdef JS_GC_ZEAL
     /* Keeping these around after a GC is dangerous. */
     clearSelectedForMarking();
 #endif
 
     /* Clear gcMallocBytes for all zones. */
--- a/js/src/vm/Runtime.cpp
+++ b/js/src/vm/Runtime.cpp
@@ -197,17 +197,17 @@ JSRuntime::JSRuntime(JSRuntime* parentRu
     spsProfiler(thisFromCtor()),
     profilingScripts(false),
     suppressProfilerSampling(false),
     hadOutOfMemory(false),
 #if defined(DEBUG) || defined(JS_OOM_BREAKPOINT)
     runningOOMTest(false),
 #endif
     allowRelazificationForTesting(false),
-    defaultFreeOp_(thisFromCtor()),
+    defaultFreeOp_(nullptr),
     debuggerMutations(0),
     securityCallbacks(&NullSecurityCallbacks),
     DOMcallbacks(nullptr),
     destroyPrincipals(nullptr),
     readPrincipals(nullptr),
     warningReporter(nullptr),
     buildIdOp(nullptr),
     propertyRemovals(0),
@@ -286,16 +286,20 @@ JSRuntime::init(uint32_t maxbytes, uint3
     if (!regexpStack.init())
         return false;
 
     if (CanUseExtraThreads() && !EnsureHelperThreadsInitialized())
         return false;
 
     js::TlsPerThreadData.set(&mainThread);
 
+    defaultFreeOp_ = js_new<js::FreeOp>(this);
+    if (!defaultFreeOp_)
+        return false;
+
     if (!gc.init(maxbytes, maxNurseryBytes))
         return false;
 
     ScopedJSDeletePtr<Zone> atomsZone(new_<Zone>(this));
     if (!atomsZone || !atomsZone->init(true))
         return false;
 
     JS::CompartmentOptions options;
@@ -418,16 +422,18 @@ JSRuntime::destroyRuntime()
 
 #if !EXPOSE_INTL_API
     FinishRuntimeNumberState(this);
 #endif
 
     gc.finish();
     atomsCompartment_ = nullptr;
 
+    js_delete(defaultFreeOp_);
+
     js_free(defaultLocale);
     js_delete(jitRuntime_);
 
     js_delete(ionPcScriptCache);
 
     gc.storeBuffer.disable();
     gc.nursery.disable();
 
@@ -674,25 +680,37 @@ JSRuntime::triggerActivityCallback(bool 
      * suppression serves to inform the exact rooting hazard analysis of this
      * property and ensures that it remains true in the future.
      */
     AutoSuppressGC suppress(contextFromMainThread());
 
     activityCallback(activityCallbackArg, active);
 }
 
+FreeOp::FreeOp(JSRuntime* maybeRuntime)
+  : JSFreeOp(maybeRuntime)
+{
+    MOZ_ASSERT_IF(maybeRuntime, CurrentThreadCanAccessRuntime(maybeRuntime));
+}
+
 FreeOp::~FreeOp()
 {
     for (size_t i = 0; i < freeLaterList.length(); i++)
         free_(freeLaterList[i]);
 
     if (!jitPoisonRanges.empty())
         jit::ExecutableAllocator::poisonCode(runtime(), jitPoisonRanges);
 }
 
+bool
+FreeOp::isDefaultFreeOp() const
+{
+    return runtime_ && runtime_->defaultFreeOp() == this;
+}
+
 JSObject*
 JSRuntime::getIncumbentGlobal(JSContext* cx)
 {
     MOZ_ASSERT(cx->runtime()->getIncumbentGlobalCallback,
                "Must set a callback using JS_SetGetIncumbentGlobalCallback before using Promises");
 
     return cx->runtime()->getIncumbentGlobalCallback(cx);
 }
--- a/js/src/vm/Runtime.h
+++ b/js/src/vm/Runtime.h
@@ -116,33 +116,31 @@ class Simulator;
  *
  * FreeOp is passed to finalizers and other sweep-phase hooks so that we do not
  * need to pass a JSContext to those hooks.
  */
 class FreeOp : public JSFreeOp
 {
     Vector<void*, 0, SystemAllocPolicy> freeLaterList;
     jit::JitPoisonRangeVector jitPoisonRanges;
-    ThreadType threadType;
 
   public:
     static FreeOp* get(JSFreeOp* fop) {
         return static_cast<FreeOp*>(fop);
     }
 
-    explicit FreeOp(JSRuntime* rt, ThreadType thread = MainThread)
-      : JSFreeOp(rt), threadType(thread)
-    {}
-
+    explicit FreeOp(JSRuntime* maybeRuntime);
     ~FreeOp();
 
-    bool onBackgroundThread() {
-        return threadType == BackgroundThread;
+    bool onMainThread() const {
+        return runtime_ != nullptr;
     }
 
+    bool isDefaultFreeOp() const;
+
     inline void free_(void* p);
     inline void freeLater(void* p);
 
     inline bool appendJitPoisonRange(const jit::JitPoisonRange& range);
 
     template <class T>
     inline void delete_(T* p) {
         if (p) {
@@ -917,21 +915,22 @@ struct JSRuntime : public JS::shadow::Ru
      */
     JSCList             onNewGlobalObjectWatchers;
 
 #if defined(XP_DARWIN) && defined(ASMJS_MAY_USE_SIGNAL_HANDLERS)
     js::wasm::MachExceptionHandler wasmMachExceptionHandler;
 #endif
 
   private:
-    js::FreeOp          defaultFreeOp_;
+    js::FreeOp*         defaultFreeOp_;
 
   public:
     js::FreeOp* defaultFreeOp() {
-        return &defaultFreeOp_;
+        MOZ_ASSERT(defaultFreeOp_);
+        return defaultFreeOp_;
     }
 
     uint32_t            debuggerMutations;
 
     const JSSecurityCallbacks* securityCallbacks;
     const js::DOMCallbacks* DOMcallbacks;
     JSDestroyPrincipalsOp destroyPrincipals;
     JSReadPrincipalsOp readPrincipals;
@@ -1338,29 +1337,29 @@ FreeOp::free_(void* p)
     js_free(p);
 }
 
 inline void
 FreeOp::freeLater(void* p)
 {
     // FreeOps other than the defaultFreeOp() are constructed on the stack,
     // and won't hold onto the pointers to free indefinitely.
-    MOZ_ASSERT(this != runtime()->defaultFreeOp());
+    MOZ_ASSERT(!isDefaultFreeOp());
 
     AutoEnterOOMUnsafeRegion oomUnsafe;
     if (!freeLaterList.append(p))
         oomUnsafe.crash("FreeOp::freeLater");
 }
 
 inline bool
 FreeOp::appendJitPoisonRange(const jit::JitPoisonRange& range)
 {
     // FreeOps other than the defaultFreeOp() are constructed on the stack,
     // and won't hold onto the pointers to free indefinitely.
-    MOZ_ASSERT(this != runtime()->defaultFreeOp());
+    MOZ_ASSERT(!isDefaultFreeOp());
 
     return jitPoisonRanges.append(range);
 }
 
 /*
  * RAII class that takes the GC lock while it is live.
  *
  * Note that the lock may be temporarily released by use of AutoUnlockGC when
--- a/js/src/vm/TypedArrayObject.cpp
+++ b/js/src/vm/TypedArrayObject.cpp
@@ -150,20 +150,18 @@ TypedArrayObject::finalize(FreeOp* fop, 
     MOZ_ASSERT(!IsInsideNursery(obj));
     TypedArrayObject* curObj = &obj->as<TypedArrayObject>();
 
     // Typed arrays with a buffer object do not need to be free'd
     if (curObj->hasBuffer())
         return;
 
     // Free the data slot pointer if it does not point into the old JSObject.
-    Nursery& nursery = fop->runtime()->gc.nursery;
-    if (!curObj->hasInlineElements() && !nursery.isInside(curObj->elements())) {
+    if (!curObj->hasInlineElements())
         js_free(curObj->elements());
-    }
 }
 
 /* static */ void
 TypedArrayObject::objectMoved(JSObject* obj, const JSObject* old)
 {
     TypedArrayObject* newObj = &obj->as<TypedArrayObject>();
     const TypedArrayObject* oldObj = &old->as<TypedArrayObject>();
 
--- a/mobile/android/tests/browser/robocop/robocop.ini
+++ b/mobile/android/tests/browser/robocop/robocop.ini
@@ -71,17 +71,16 @@ skip-if = android_version == "18"
 # [src/org/mozilla/gecko/tests/testVkbOverlap.java] # see bug 907274
 
 # Using JavascriptTest
 # (If your test can be written entirely in Javascript, consider writing
 # it as a chrome test instead. See mobile/android/tests/browser/chrome.)
 [src/org/mozilla/gecko/tests/testBrowserDiscovery.java]
 [src/org/mozilla/gecko/tests/testFilePicker.java]
 [src/org/mozilla/gecko/tests/testHistoryService.java]
-# [src/org/mozilla/gecko/tests/testMozPay.java] # see bug 945675
 [src/org/mozilla/gecko/tests/testOSLocale.java]
 # disabled on 4.3: Bug 1124494
 skip-if = android_version == "18"
 [src/org/mozilla/gecko/tests/testReadingListCache.java]
 [src/org/mozilla/gecko/tests/testRestrictions.java]
 [src/org/mozilla/gecko/tests/testSnackbarAPI.java]
 [src/org/mozilla/gecko/tests/testTrackingProtection.java]
 [src/org/mozilla/gecko/tests/testUITelemetry.java]
deleted file mode 100644
--- a/mobile/android/tests/browser/robocop/roboextender/base/paymentsUI.html
+++ /dev/null
@@ -1,25 +0,0 @@
-<html>
-  <head>
-    <script type="text/javascript">
-function start() {
-  if (!mozPaymentProvider)
-    window.close();
-
-  // We don't have a way to mock these values yet. This check just makes sure the world
-  // doesn't crash if we ask for them.
-  var mcc = mozPaymentProvider.mcc;
-  var mnc = mozPaymentProvider.mnc;
-
-  // We use the jwt passed in here to test calling paymentFailed/Success
-  if (window.location.hash == "#pass")
-    mozPaymentProvider.paymentSuccess("PAID CORRECTLY");
-  else if (window.location.hash == "#fail")
-    mozPaymentProvider.paymentFailed("FAILED CORRECTLY");
-  else
-    mozPaymentProvider.paymentFailed("invalid hash " + window.location.hash);
-}
-
-document.addEventListener("DOMContentLoaded", start);
-    </script>
-  </head>
-</html>
deleted file mode 100644
--- a/mobile/android/tests/browser/robocop/src/org/mozilla/gecko/tests/testMozPay.java
+++ /dev/null
@@ -1,13 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.gecko.tests;
-
-
-
-public class testMozPay extends JavascriptTest {
-    public testMozPay() {
-        super("testMozPay.js");
-    }
-}
deleted file mode 100644
--- a/mobile/android/tests/browser/robocop/testMozPay.js
+++ /dev/null
@@ -1,102 +0,0 @@
-// -*- indent-tabs-mode: nil; js-indent-level: 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/. */
-
-var Cc = Components.classes;
-var Ci = Components.interfaces;
-var Cu = Components.utils;
-
-Components.utils.import("resource://gre/modules/SharedPreferences.jsm");
-Components.utils.import("resource://gre/modules/Promise.jsm");
-
-var ppmm = Cc["@mozilla.org/parentprocessmessagemanager;1"].getService(Ci.nsIMessageListenerManager);
-var deferred = 0;
-var shouldPass = true;
-var reqId = 0;
-function getRequestId(increment) {
-  reqId += increment;
-  return "Request" + reqId;
-}
-
-var paymentSuccess = {
-  receiveMessage: function(aMsg) {
-    let msg = aMsg.json;
-    if (shouldPass) {
-      do_check_eq(msg.requestId, getRequestId(0));
-    } else {
-      do_throw("Test should not have passed");
-    }
-    deferred.resolve();
-  }
-}
-
-var paymentFailed = {
-  receiveMessage: function(aMsg) {
-    let msg = aMsg.json;
-    if (shouldPass) {
-      do_throw("Test should not have failed: " + msg.errorMsg);
-    } else {
-      do_check_eq(msg.requestId, getRequestId(0));
-      do_check_eq(msg.errorMsg, "FAILED CORRECTLY");
-    }
-    deferred.resolve();
-  }
-}
-
-add_task(function test_get_set() {
-  let ui = Cc["@mozilla.org/payment/ui-glue;1"].getService(Ci.nsIPaymentUIGlue);
-  deferred = Promise.defer();
-  let id = getRequestId(1);
-  ui.confirmPaymentRequest(id,
-                           [{ wrappedJSObject: { type: "Fake Provider" } }],
-                           function(aRequestId, type) {
-                             do_check_eq(type, "Fake Provider");
-                             deferred.resolve();
-                           },
-                           function(id, msg) {
-                             do_throw("confirmPaymentRequest should not have failed");
-                             deferred.resolve();
-                           });
-  yield deferred.promise;
-});
-
-add_task(function test_default() {
-  ppmm.addMessageListener("Payment:Success", paymentSuccess);
-  ppmm.addMessageListener("Payment:Failed", paymentFailed);
-
-  let ui = Cc["@mozilla.org/payment/ui-glue;1"].getService(Ci.nsIPaymentUIGlue);
-  deferred = Promise.defer();
-  let id = getRequestId(1);
-  shouldPass = true;
-  ui.showPaymentFlow(id,
-                     {
-                       uri: "chrome://roboextender/content/paymentsUI.html",
-                       jwt: "#pass"
-                     },
-                     function(id, msg) {
-                       do_throw("confirmPaymentRequest should not have failed");
-                       deferred.resolve();
-                     });
-  yield deferred.promise;
-
-  deferred = Promise.defer();
-  id = getRequestId(1);
-  shouldPass = false;
-  ui.showPaymentFlow(id,
-                     {
-                       uri: "chrome://roboextender/content/paymentsUI.html",
-                       jwt: "#fail"
-                     },
-                     function(id, msg) {
-                       do_throw("confirmPaymentRequest should not have failed");
-                       deferred.resolve();
-                     });
-
-  yield deferred.promise;
-
-  ppmm.removeMessageListener("Payment:Success", paymentSuccess);
-  ppmm.removeMessageListener("Payment:Failed", paymentFailed);
-});
-
-run_next_test();
--- a/old-configure.in
+++ b/old-configure.in
@@ -2369,17 +2369,16 @@ NECKO_COOKIES=1
 NECKO_PROTOCOLS_DEFAULT="about data file ftp http res viewsource websocket wyciwyg device"
 BUILD_CTYPES=1
 MOZ_USE_NATIVE_POPUP_WINDOWS=
 MOZ_EXCLUDE_HYPHENATION_DICTIONARIES=
 MOZ_INSTALL_TRACKING=
 ACCESSIBILITY=1
 MOZ_TIME_MANAGER=
 MOZ_SIMPLEPUSH=
-MOZ_PAY=
 MOZ_AUDIO_CHANNEL_MANAGER=
 MOZ_CONTENT_SANDBOX=
 MOZ_GMP_SANDBOX=
 MOZ_SANDBOX=1
 MOZ_BINARY_EXTENSIONS=
 MOZ_DEVTOOLS=server
 
 case "$target_os" in
@@ -4933,24 +4932,16 @@ dnl = Enable Support for SimplePush (Gon
 dnl   This will disable the Push API.
 dnl ========================================================
 if test -n "$MOZ_SIMPLEPUSH"; then
     AC_DEFINE(MOZ_SIMPLEPUSH)
 fi
 AC_SUBST(MOZ_SIMPLEPUSH)
 
 dnl ========================================================
-dnl = Enable Support for Payment API
-dnl ========================================================
-if test -n "$MOZ_PAY"; then
-    AC_DEFINE(MOZ_PAY)
-fi
-AC_SUBST(MOZ_PAY)
-
-dnl ========================================================
 dnl = Enable Support for AudioChannelManager API
 dnl ========================================================
 if test -n "$MOZ_AUDIO_CHANNEL_MANAGER"; then
     AC_DEFINE(MOZ_AUDIO_CHANNEL_MANAGER)
 fi
 AC_SUBST(MOZ_AUDIO_CHANNEL_MANAGER)
 
 dnl ========================================================
deleted file mode 100644
--- a/services/mobileid/MobileIdentityClient.jsm
+++ /dev/null
@@ -1,158 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-// REST client for
-// https://github.com/mozilla-services/msisdn-gateway/blob/master/API.md
-
-"use strict";
-
-this.EXPORTED_SYMBOLS = ["MobileIdentityClient"];
-
-const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
-
-Cu.import("resource://services-common/hawkclient.js");
-Cu.import("resource://services-common/hawkrequest.js");
-Cu.import("resource://services-common/utils.js");
-Cu.import("resource://services-crypto/utils.js");
-Cu.import("resource://gre/modules/MobileIdentityCommon.jsm");
-Cu.import("resource://gre/modules/Promise.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-
-this.MobileIdentityClient = function(aServerUrl) {
-  let serverUrl = aServerUrl || SERVER_URL;
-  let forceHttps = true;
-  try {
-    forceHttps = Services.prefs.getBoolPref(PREF_FORCE_HTTPS);
-  } catch(e) {
-    log.warn("Getting force HTTPS pref failed. If this was not intentional " +
-             "check that " + PREF_FORCE_HTTPS + " is defined");
-  }
-
-  log.debug("Force HTTPS " + forceHttps);
-
-  if (forceHttps && !/^https/.exec(serverUrl.toLowerCase())) {
-    throw new Error(ERROR_INTERNAL_HTTP_NOT_ALLOWED);
-  }
-
-  this.hawk = new HawkClient(serverUrl);
-  this.hawk.observerPrefix = "MobileId:hawk";
-};
-
-this.MobileIdentityClient.prototype = {
-
-  discover: function(aMsisdn, aMcc, aMnc, aRoaming) {
-    return this._request(DISCOVER, "POST", null, {
-      msisdn: aMsisdn || undefined,
-      mcc: aMcc,
-      mnc: aMnc,
-      roaming: aRoaming
-    });
-  },
-
-  register: function() {
-    return this._request(REGISTER, "POST", null, {});
-  },
-
-  smsMtVerify: function(aSessionToken, aMsisdn, aMcc, aMnc,
-                        aWantShortCode = false) {
-    let credentials = this._deriveHawkCredentials(aSessionToken);
-    return this._request(SMS_MT_VERIFY, "POST", credentials, {
-      msisdn: aMsisdn,
-      mcc: aMcc,
-      mnc: aMnc,
-      shortVerificationCode: aWantShortCode
-    });
-  },
-
-  verifyCode: function(aSessionToken, aVerificationCode) {
-    log.debug("verificationCode " + aVerificationCode);
-    let credentials = this._deriveHawkCredentials(aSessionToken);
-    return this._request(SMS_VERIFY_CODE, "POST", credentials, {
-      code: aVerificationCode
-    });
-  },
-
-  sign: function(aSessionToken, aDuration, aPublicKey) {
-    let credentials = this._deriveHawkCredentials(aSessionToken);
-    return this._request(SIGN, "POST", credentials, {
-      duration: aDuration,
-      publicKey: aPublicKey
-    });
-  },
-
-  unregister: function(aSessionToken) {
-    let credentials = this._deriveHawkCredentials(aSessionToken);
-    return this._request(UNREGISTER, "POST", credentials, {});
-  },
-
-  /**
-   * The MobileID server expects requests to certain endpoints to be
-   * authorized using Hawk.
-   *
-   * Hawk credentials are derived using shared secrets.
-   *
-   * @param tokenHex
-   *        The current session token encoded in hex
-   * @param context
-   *        A context for the credentials
-   * @param size
-   *        The size in bytes of the expected derived buffer
-   * @return credentials
-   *        Returns an object:
-   *        {
-   *          algorithm: sha256
-   *          id: the Hawk id (from the first 32 bytes derived)
-   *          key: the Hawk key (from bytes 32 to 64)
-   *        }
-   */
-  _deriveHawkCredentials: function(aSessionToken) {
-    return deriveHawkCredentials(aSessionToken, CREDENTIALS_DERIVATION_INFO,
-                                 CREDENTIALS_DERIVATION_SIZE, true /*hexKey*/);
-  },
-
-  /**
-   * A general method for sending raw API calls to the mobile id verification
-   * server.
-   * All request bodies and responses are JSON.
-   *
-   * @param path
-   *        API endpoint path
-   * @param method
-   *        The HTTP request method
-   * @param credentials
-   *        Hawk credentials
-   * @param jsonPayload
-   *        A JSON payload
-   * @return Promise
-   *        Returns a promise that resolves to the JSON response of the API
-   *        call, or is rejected with an error.
-   */
-  _request: function(path, method, credentials, jsonPayload) {
-    let deferred = Promise.defer();
-
-    this.hawk.request(path, method, credentials, jsonPayload).then(
-      (response) => {
-        log.debug("MobileIdentityClient -> response.body " + response.body);
-        try {
-          let responseObj;
-          // We parse the response body unless we are handling a 204 response,
-          // which MUST NOT include a message body.
-          if (response.status != 204) {
-            responseObj = JSON.parse(response.body);
-          }
-          deferred.resolve(responseObj);
-        } catch (err) {
-          deferred.reject({error: err});
-        }
-      },
-      (error) => {
-        log.error("MobileIdentityClient -> Error ${}", error);
-        deferred.reject(SERVER_ERRNO_TO_ERROR[error.errno] || ERROR_UNKNOWN);
-      }
-    );
-
-    return deferred.promise;
-  },
-
-};
deleted file mode 100644
--- a/services/mobileid/MobileIdentityCommon.jsm
+++ /dev/null
@@ -1,144 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-const { interfaces: Ci, utils: Cu } = Components;
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/Log.jsm");
-
-// loglevel should be one of "Fatal", "Error", "Warn", "Info", "Config",
-// "Debug", "Trace" or "All". If none is specified, "Error" will be used by
-// default.
-const PREF_LOG_LEVEL = "services.mobileid.loglevel";
-
-XPCOMUtils.defineLazyGetter(this, "log", function() {
-  let log = Log.repository.getLogger("MobileId");
-  log.addAppender(new Log.DumpAppender());
-  log.level = Log.Level.Error;
-  try {
-    let level =
-      Services.prefs.getPrefType(PREF_LOG_LEVEL) == Ci.nsIPrefBranch.PREF_STRING
-      && Services.prefs.getCharPref(PREF_LOG_LEVEL);
-    log.level = Log.Level[level] || Log.Level.Error;
-  } catch (e) {
-    log.error(e);
-  }
-
-  return log;
-});
-
-this.PREF_FORCE_HTTPS = "services.mobileid.forcehttps";
-
-// Permission.
-this.MOBILEID_PERM = "mobileid";
-
-// IPC messages.
-this.GET_ASSERTION_IPC_MSG = "MobileId:GetAssertion";
-
-// Verification methods.
-this.SMS_MT    = "sms/mt";
-this.SMS_MO_MT = "sms/momt";
-
-// Server endpoints.
-this.DISCOVER         = "/discover";
-this.REGISTER         = "/register";
-this.SMS_MT_VERIFY    = "/" + this.SMS_MT + "/verify";
-this.SMS_MO_MT_VERIFY = "/" + this.SMS_MO_MT + "/verify";
-this.SMS_VERIFY_CODE  = "/sms/verify_code";
-this.SIGN             = "/certificate/sign";
-this.UNREGISTER       = "/unregister";
-
-// Server consts.
-this.SERVER_URL = Services.prefs.getCharPref("services.mobileid.server.uri");
-this.CREDENTIALS_DERIVATION_INFO = "sessionToken";
-this.CREDENTIALS_DERIVATION_SIZE = 2 * 32;
-
-this.SILENT_SMS_RECEIVED_TOPIC = "silent-sms-received";
-
-this.ASSERTION_LIFETIME   = 1000 * 60 * 5;   // 5 minutes.
-this.CERTIFICATE_LIFETIME = 1000 * 3600 * 6; // 6 hours.
-this.KEY_LIFETIME         = 1000 * 3600 * 12; // 12 hours.
-
-this.VERIFICATIONCODE_TIMEOUT = 60000;
-this.VERIFICATIONCODE_RETRIES = 3;
-
-// Internal Errors.
-this.ERROR_INTERNAL_CANNOT_CREATE_VERIFICATION_FLOW = "INTERNAL_CANNOT_CREATE_VERIFICATION_FLOW";
-this.ERROR_INTERNAL_CANNOT_GENERATE_ASSERTION       = "INTERNAL_CANNOT_GENERATE_ASSERTION";
-this.ERROR_INTERNAL_CANNOT_VERIFY_SELECTION         = "INTERNAL_CANNOT_VERIFY_SELECTION";
-this.ERROR_INTERNAL_DB_ERROR                        = "INTERNAL_DB_ERROR";
-this.ERROR_INTERNAL_HTTP_NOT_ALLOWED                = "INTERNAL_HTTP_NOT_ALLOWED";
-this.ERROR_INTERNAL_INVALID_CERTIFICATE             = "INTERNAL_INVALID_CERTIFICATE";
-this.ERROR_INTERNAL_INVALID_PROMPT_RESULT           = "INTERNAL_INVALID_PROMPT_RESULT";
-this.ERROR_INTERNAL_INVALID_USER_SELECTION          = "INTERNAL_INVALID_USER_SELECTION";
-this.ERROR_INTERNAL_INVALID_VERIFICATION_FLOW       = "INTERNAL_INVALID_VERIFICATION_FLOW";
-this.ERROR_INTERNAL_INVALID_VERIFICATION_RESULT     = "INTERNAL_INVALID_VERIFICATION_RESULT";
-this.ERROR_INTERNAL_UNEXPECTED                      = "INTERNAL_UNEXPECTED";
-
-// Errors.
-this.ERROR_ENDPOINT_NOT_SUPPORTED                 = "ENDPOINT_NOT_SUPPORTED";
-this.ERROR_INVALID_ASSERTION                      = "INVALID_ASSERTION";
-this.ERROR_INVALID_AUTH_TOKEN                     = "INVALID_AUTH_TOKEN";
-this.ERROR_INVALID_BODY_JSON                      = "INVALID_BODY_JSON";
-this.ERROR_INVALID_BODY_MISSING_PARAMS            = "INVALID_BODY_MISSING_PARAMS";
-this.ERROR_INVALID_BODY_PARAMS                    = "INVALID_BODY_PARAMS";
-this.ERROR_INVALID_PHONE_NUMBER                   = "INVALID_PHONE_NUMBER";
-this.ERROR_INVALID_PROMPT_RESULT                  = "INVALID_PROMPT_RESULT";
-this.ERROR_INVALID_REQUEST_SIGNATURE              = "INVALID_REQUEST_SIGNATURE";
-this.ERROR_INVALID_VERIFICATION_CODE              = "INVALID_VERIFICATION_CODE";
-this.ERROR_MISSING_CONTENT_LENGTH_HEADER          = "MISSING_CONTENT_LENGTH_HEADER";
-this.ERROR_NO_RETRIES_LEFT                        = "NO_RETRIES_LEFT";
-this.ERROR_OFFLINE                                = "OFFLINE";
-this.ERROR_PERMISSION_DENIED                      = "PERMISSION_DENIED";
-this.ERROR_REQUEST_BODY_TOO_LARGE                 = "REQUEST_BODY_TOO_LARGE";
-this.ERROR_SERVICE_TEMPORARILY_UNAVAILABLE        = "SERVICE_TEMPORARILY_UNAVAILABLE";
-this.ERROR_TOO_MANY_REQUESTS_MSISDN               = "TOO_MANY_REQUESTS_MSISDN";
-this.ERROR_TOO_MANY_REQUESTS_UNSPECIFIED          = "TOO_MANY_REQUESTS_UNSPECIFIED";
-this.ERROR_TOO_MANY_REQUESTS_VERIFICAITON_CODE    = "TOO_MANY_REQUESTS_VERIFICATION_CODE";
-this.ERROR_TOO_MANY_REQUESTS_VERIFICATION_METHOD  = "TOO_MANY_REQUESTS_VERIFICATION_METHOD";
-this.ERROR_UNKNOWN                                = "UNKNOWN";
-this.ERROR_UNVERIFIED_ACCOUNT                     = "UNVERIFIED_ACCOUNT";
-this.ERROR_VERIFICATION_CODE_TIMEOUT              = "VERIFICATION_CODE_TIMEOUT";
-
-// Server errno.
-// From https://github.com/mozilla-services/msisdn-gateway/blob/master/API.md#response-format
-this.ERRNO_UNVERIFIED_ACCOUNT                     = 104;
-this.ERRNO_INVALID_VERIFICATION_CODE              = 105;
-this.ERRNO_INVALID_BODY_JSON                      = 106;
-this.ERRNO_INVALID_BODY_INVALID_PARAMS            = 107;
-this.ERRNO_INVALID_BODY_MISSING_PARAMS            = 108;
-this.ERRNO_INVALID_REQUEST_SIGNATURE              = 109;
-this.ERRNO_INVALID_AUTH_TOKEN                     = 110;
-this.ERRNO_ENDPOINT_NOT_SUPPORTED                 = 111;
-this.ERRNO_MISSING_CONTENT_LENGTH_HEADER          = 112;
-this.ERRNO_REQUEST_BODY_TOO_LARGE                 = 113;
-this.ERRNO_TOO_MANY_REQUESTS_VERIFICATION_CODE    = 114;
-this.ERRNO_TOO_MANY_REQUESTS_MSISDN               = 115;
-this.ERRNO_TOO_MANY_REQUESTS_VERIFICATION_METHOD  = 116;
-this.ERRNO_TOO_MANY_REQUESTS_UNSPECIFIED          = 117;
-this.ERRNO_SERVICE_TEMPORARILY_UNAVAILABLE        = 201;
-this.ERRNO_UNKNOWN_ERROR                          = 999;
-
-// Error matching.
-this.SERVER_ERRNO_TO_ERROR = {};
-SERVER_ERRNO_TO_ERROR[ERRNO_UNVERIFIED_ACCOUNT] = ERROR_UNVERIFIED_ACCOUNT;
-SERVER_ERRNO_TO_ERROR[ERRNO_INVALID_VERIFICATION_CODE] = ERROR_INVALID_VERIFICATION_CODE;
-SERVER_ERRNO_TO_ERROR[ERRNO_INVALID_BODY_JSON] = ERROR_INVALID_BODY_JSON;
-SERVER_ERRNO_TO_ERROR[ERRNO_INVALID_BODY_INVALID_PARAMS] = ERROR_INVALID_BODY_PARAMS;
-SERVER_ERRNO_TO_ERROR[ERRNO_INVALID_BODY_MISSING_PARAMS] = ERROR_INVALID_BODY_MISSING_PARAMS;
-SERVER_ERRNO_TO_ERROR[ERRNO_INVALID_REQUEST_SIGNATURE] = ERROR_INVALID_REQUEST_SIGNATURE;
-SERVER_ERRNO_TO_ERROR[ERRNO_INVALID_AUTH_TOKEN] = ERROR_INVALID_AUTH_TOKEN;
-SERVER_ERRNO_TO_ERROR[ERRNO_ENDPOINT_NOT_SUPPORTED] = ERROR_ENDPOINT_NOT_SUPPORTED;
-SERVER_ERRNO_TO_ERROR[ERRNO_MISSING_CONTENT_LENGTH_HEADER] = ERROR_MISSING_CONTENT_LENGTH_HEADER;
-SERVER_ERRNO_TO_ERROR[ERRNO_REQUEST_BODY_TOO_LARGE] = ERROR_REQUEST_BODY_TOO_LARGE;
-SERVER_ERRNO_TO_ERROR[ERRNO_TOO_MANY_REQUESTS_VERIFICATION_CODE] = ERROR_TOO_MANY_REQUESTS_VERIFICAITON_CODE;
-SERVER_ERRNO_TO_ERROR[ERRNO_TOO_MANY_REQUESTS_MSISDN] = ERROR_TOO_MANY_REQUESTS_MSISDN;;
-SERVER_ERRNO_TO_ERROR[ERRNO_TOO_MANY_REQUESTS_VERIFICATION_METHOD] = ERROR_TOO_MANY_REQUESTS_VERIFICATION_METHOD;;
-SERVER_ERRNO_TO_ERROR[ERRNO_TOO_MANY_REQUESTS_UNSPECIFIED] = ERROR_TOO_MANY_REQUESTS_UNSPECIFIED;;
-SERVER_ERRNO_TO_ERROR[ERRNO_SERVICE_TEMPORARILY_UNAVAILABLE] = ERROR_SERVICE_TEMPORARILY_UNAVAILABLE;
-SERVER_ERRNO_TO_ERROR[ERRNO_UNKNOWN_ERROR] = ERROR_UNKNOWN;
-
-// Allow this file to be imported via Components.utils.import().
-this.EXPORTED_SYMBOLS = Object.keys(this);
deleted file mode 100644
--- a/services/mobileid/MobileIdentityCredentialsStore.jsm
+++ /dev/null
@@ -1,257 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-this.EXPORTED_SYMBOLS = ["MobileIdentityCredentialsStore"];
-
-const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
-
-Cu.import("resource://gre/modules/IndexedDBHelper.jsm");
-Cu.import("resource://gre/modules/MobileIdentityCommon.jsm");
-Cu.import("resource://gre/modules/Promise.jsm");
-
-const CREDENTIALS_DB_NAME     = "mobile-id-credentials";
-const CREDENTIALS_DB_VERSION  = 1;
-const CREDENTIALS_STORE_NAME  = "credentials-store";
-
-this.MobileIdentityCredentialsStore = function() {
-};
-
-this.MobileIdentityCredentialsStore.prototype = {
-
-  __proto__: IndexedDBHelper.prototype,
-
-  init: function() {
-    log.debug("MobileIdentityCredentialsStore init");
-    this.initDBHelper(CREDENTIALS_DB_NAME,
-                      CREDENTIALS_DB_VERSION,
-                      [CREDENTIALS_STORE_NAME]);
-  },
-
-  upgradeSchema: function(aTransaction, aDb, aOldVersion, aNewVersion) {
-    log.debug("upgradeSchema");
-    /**
-     * We will be storing objects like:
-     *  {
-     *    msisdn: <string> (key),
-     *    iccId: <string> (index, optional),
-     *    deviceIccIds: <array>,
-     *    origin: <array> (index),
-     *    msisdnSessionToken: <string>,
-     *  }
-     */
-    let objectStore = aDb.createObjectStore(CREDENTIALS_STORE_NAME, {
-      keyPath: "msisdn"
-    });
-
-    objectStore.createIndex("iccId", "iccId", { unique: true });
-    objectStore.createIndex("origin", "origin", { unique: true, multiEntry: true });
-  },
-
-  add: function(aIccId, aMsisdn, aOrigin, aSessionToken, aDeviceIccIds) {
-    log.debug("put " + aIccId + ", " + aMsisdn + ", " + aOrigin + ", " +
-              aSessionToken + ", " + aDeviceIccIds);
-    if (!aOrigin || !aSessionToken) {
-      return Promise.reject(ERROR_INTERNAL_DB_ERROR);
-    }
-
-    let deferred = Promise.defer();
-
-    // We first try get an existing record for the given MSISDN.
-    this.newTxn(
-      "readwrite",
-      CREDENTIALS_STORE_NAME,
-      (aTxn, aStore) => {
-        let range = IDBKeyRange.only(aMsisdn);
-        let cursorReq = aStore.openCursor(range);
-        cursorReq.onsuccess = function(aEvent) {
-          let cursor = aEvent.target.result;
-          let record;
-          // If we already have a record of this MSISDN, we add the origin to
-          // the list of allowed origins.
-          if (cursor && cursor.value) {
-            record = cursor.value;
-            if (record.origin.indexOf(aOrigin) == -1) {
-              record.origin.push(aOrigin);
-            }
-            cursor.update(record);
-          } else {
-            // Otherwise, we store a new record.
-            record = {
-              iccId: aIccId,
-              msisdn: aMsisdn,
-              origin: [aOrigin],
-              sessionToken: aSessionToken,
-              deviceIccIds: aDeviceIccIds
-            };
-            aStore.add(record);
-          }
-          deferred.resolve();
-        };
-        cursorReq.onerror = function(aEvent) {
-          log.error(aEvent.target.error);
-          deferred.reject(ERROR_INTERNAL_DB_ERROR);
-        };
-      }, null, deferred.reject);
-
-    return deferred.promise;
-  },
-
-  getByMsisdn: function(aMsisdn) {
-    log.debug("getByMsisdn " + aMsisdn);
-    if (!aMsisdn) {
-      return Promise.resolve(null);
-    }
-
-    let deferred = Promise.defer();
-    this.newTxn(
-      "readonly",
-      CREDENTIALS_STORE_NAME,
-      (aTxn, aStore) => {
-        aStore.get(aMsisdn).onsuccess = function(aEvent) {
-          aTxn.result = aEvent.target.result;
-        };
-      },
-      function(result) {
-        deferred.resolve(result);
-      },
-      deferred.reject
-    );
-    return deferred.promise;
-  },
-
-  getByIndex: function(aIndex, aValue) {
-    log.debug("getByIndex " + aIndex + ", " + aValue);
-    if (!aValue || !aIndex) {
-      return Promise.resolve(null);
-    }
-
-    let deferred = Promise.defer();
-    this.newTxn(
-      "readonly",
-      CREDENTIALS_STORE_NAME,
-      (aTxn, aStore) => {
-        let index = aStore.index(aIndex);
-        index.get(aValue).onsuccess = function(aEvent) {
-          aTxn.result = aEvent.target.result;
-        };
-      },
-      function(result) {
-        deferred.resolve(result);
-      },
-      deferred.reject
-    );
-    return deferred.promise;
-  },
-
-  getByOrigin: function(aOrigin) {
-    return this.getByIndex("origin", aOrigin);
-  },
-
-  getByIccId: function(aIccId) {
-    return this.getByIndex("iccId", aIccId);
-  },
-
-  delete: function(aMsisdn) {
-    log.debug("delete " + aMsisdn);
-    if (!aMsisdn) {
-      return Promise.resolve();
-    }
-
-    let deferred = Promise.defer();
-    this.newTxn(
-      "readwrite",
-      CREDENTIALS_STORE_NAME,
-      (aTxn, aStore) => {
-        aStore.delete(aMsisdn);
-      },
-      deferred.resolve,
-      deferred.reject
-    );
-    return deferred.promise;
-  },
-
-  removeValue: function(aMsisdn, aKey, aValue) {
-    log.debug("Removing " + aKey + " with value " + aValue);
-    if (!aMsisdn || !aKey) {
-      return Promise.reject();
-    }
-
-    let deferred = Promise.defer();
-    this.newTxn(
-      "readwrite",
-      CREDENTIALS_STORE_NAME,
-      (aTxn, aStore) => {
-        let range = IDBKeyRange.only(aMsisdn);
-        let cursorReq = aStore.openCursor(range);
-        cursorReq.onsuccess = function(aEvent) {
-          let cursor = aEvent.target.result;
-          let record;
-          if (!cursor || !cursor.value) {
-            return Promise.resolve();
-          }
-          record = cursor.value;
-          if (!record[aKey]) {
-            return Promise.reject();
-          }
-          if (aValue) {
-            let index = record[aKey].indexOf(aValue);
-            if (index != -1) {
-              record[aKey].splice(index, 1);
-            }
-          } else {
-            record[aKey] = undefined;
-          }
-          log.debug("Removal done ${}", record);
-          cursor.update(record);
-          deferred.resolve();
-        };
-        cursorReq.onerror = function(aEvent) {
-          log.error(aEvent.target.error);
-          deferred.reject(ERROR_INTERNAL_DB_ERROR);
-        };
-      }, null, deferred.reject);
-
-    return deferred.promise;
-  },
-
-  removeOrigin: function(aMsisdn, aOrigin) {
-    log.debug("removeOrigin " + aMsisdn + " " + aOrigin);
-    return this.removeValue(aMsisdn, "origin", aOrigin);
-  },
-
-  setDeviceIccIds: function(aMsisdn, aDeviceIccIds) {
-    log.debug("Setting icc ids " + aDeviceIccIds + " for " + aMsisdn);
-    if (!aMsisdn) {
-      return Promise.reject();
-    }
-
-    let deferred = Promise.defer();
-    this.newTxn(
-      "readwrite",
-      CREDENTIALS_STORE_NAME,
-      (aTxn, aStore) => {
-        let range = IDBKeyRange.only(aMsisdn);
-        let cursorReq = aStore.openCursor(range);
-        cursorReq.onsuccess = function(aEvent) {
-          let cursor = aEvent.target.result;
-          let record;
-          if (!cursor || !cursor.value) {
-            return Promise.resolve();
-          }
-          record = cursor.value;
-          record.deviceIccIds = aDeviceIccIds;
-          cursor.update(record);
-          deferred.resolve();
-        };
-        cursorReq.onerror = function(aEvent) {
-          log.error(aEvent.target.error);
-          deferred.reject(ERROR_INTERNAL_DB_ERROR);
-        };
-      }, null, deferred.reject);
-
-    return deferred.promise;
-  }
-};
deleted file mode 100644
--- a/services/mobileid/MobileIdentityManager.jsm
+++ /dev/null
@@ -1,1085 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-this.EXPORTED_SYMBOLS = ["MobileIdentityManager"];
-
-const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
-
-Cu.import("resource://gre/modules/AppConstants.jsm");
-Cu.import("resource://gre/modules/MobileIdentityCommon.jsm");
-Cu.import("resource://gre/modules/MobileIdentityUIGlueCommon.jsm");
-Cu.import("resource://gre/modules/Promise.jsm");
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "MobileIdentityCredentialsStore",
-  "resource://gre/modules/MobileIdentityCredentialsStore.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "MobileIdentityClient",
-  "resource://gre/modules/MobileIdentityClient.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "MobileIdentitySmsMtVerificationFlow",
-  "resource://gre/modules/MobileIdentitySmsMtVerificationFlow.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "MobileIdentitySmsMoMtVerificationFlow",
-  "resource://gre/modules/MobileIdentitySmsMoMtVerificationFlow.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "PhoneNumberUtils",
-  "resource://gre/modules/PhoneNumberUtils.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "jwcrypto",
-  "resource://gre/modules/identity/jwcrypto.jsm");
-
-XPCOMUtils.defineLazyServiceGetter(this, "uuidgen",
-                                   "@mozilla.org/uuid-generator;1",
-                                   "nsIUUIDGenerator");
-
-XPCOMUtils.defineLazyServiceGetter(this, "ppmm",
-                                   "@mozilla.org/parentprocessmessagemanager;1",
-                                   "nsIMessageListenerManager");
-
-XPCOMUtils.defineLazyServiceGetter(this, "permissionManager",
-                                   "@mozilla.org/permissionmanager;1",
-                                   "nsIPermissionManager");
-
-XPCOMUtils.defineLazyServiceGetter(this, "securityManager",
-                                   "@mozilla.org/scriptsecuritymanager;1",
-                                   "nsIScriptSecurityManager");
-
-XPCOMUtils.defineLazyServiceGetter(this, "appsService",
-                                   "@mozilla.org/AppsService;1",
-                                   "nsIAppsService");
-
-if (AppConstants.MOZ_B2G_RIL) {
-  XPCOMUtils.defineLazyServiceGetter(this, "Ril",
-                                     "@mozilla.org/ril;1",
-                                     "nsIRadioInterfaceLayer");
-
-  XPCOMUtils.defineLazyServiceGetter(this, "IccService",
-                                     "@mozilla.org/icc/iccservice;1",
-                                     "nsIIccService");
-
-  XPCOMUtils.defineLazyServiceGetter(this, "MobileConnectionService",
-                                     "@mozilla.org/mobileconnection/mobileconnectionservice;1",
-                                     "nsIMobileConnectionService");
-}
-
-
-this.MobileIdentityManager = {
-
-  init: function() {
-    log.debug("MobileIdentityManager init");
-    Services.obs.addObserver(this, "xpcom-shutdown", false);
-    ppmm.addMessageListener(GET_ASSERTION_IPC_MSG, this);
-    this.messageManagers = {};
-    this.keyPairs = {};
-    this.certificates = {};
-  },
-
-  receiveMessage: function(aMessage) {
-    log.debug("Received " + aMessage.name);
-
-    if (aMessage.name !== GET_ASSERTION_IPC_MSG) {
-      return;
-    }
-
-    let msg = aMessage.json;
-
-    // We save the message target message manager so we can later dispatch
-    // back messages without broadcasting to all child processes.
-    let promiseId = msg.promiseId;
-    this.messageManagers[promiseId] = aMessage.target;
-
-    this.getMobileIdAssertion(aMessage.principal, promiseId, msg.options);
-  },
-
-  observe: function(subject, topic, data) {
-    if (topic != "xpcom-shutdown") {
-      return;
-    }
-
-    ppmm.removeMessageListener(GET_ASSERTION_IPC_MSG, this);
-    Services.obs.removeObserver(this, "xpcom-shutdown");
-    this.messageManagers = null;
-  },
-
-  /*********************************************************
-   * Getters
-   ********************************************************/
-  get iccInfo() {
-    if (this._iccInfo) {
-      return this._iccInfo;
-    }
-    if (AppConstants.MOZ_B2G_RIL) {
-      let self = this;
-      let iccListener = {
-        notifyStkCommand: function() {},
-
-        notifyStkSessionEnd: function() {},
-
-        notifyCardStateChanged: function() {},
-
-        notifyIccInfoChanged: function() {
-          // If we receive a notification about an ICC info change, we clear
-          // the ICC related caches so they can be rebuilt with the new changes.
-
-          log.debug("ICC info changed observed. Clearing caches");
-
-          // We don't need to keep listening for changes until we rebuild the
-          // cache again.
-          for (let i = 0; i < self._iccInfo.length; i++) {
-            let icc = self.iccService.getIccByServiceId(i);
-            if (icc) {
-              icc.unregisterListener(iccListener);
-            }
-          }
-
-          self._iccInfo = null;
-          self._iccIds = null;
-        }
-      };
-
-      // _iccInfo is a local cache containing the information about the SIM cards
-      // that is interesting for the Mobile ID flow.
-      // The index of this array does not necesarily need to match the real
-      // identifier of the SIM card ("clientId" or "serviceId" in RIL language).
-      this._iccInfo = [];
-
-      for (let i = 0; i < this.ril.numRadioInterfaces; i++) {
-        let icc = this.iccService.getIccByServiceId(i);
-        if (!icc) {
-          log.warn("Tried to get the Icc instance for an invalid service ID " + i);
-          continue;
-        }
-
-        let info = icc.iccInfo;
-        if (!info || !info.iccid ||
-            !info.mcc || !info.mcc.length ||
-            !info.mnc || !info.mnc.length) {
-          log.warn("Absent or invalid ICC info");
-          continue;
-        }
-
-        // GSM SIMs may have MSISDN while CDMA SIMs may have MDN
-        let phoneNumber = null;
-        try {
-          if (info.iccType === "sim" || info.iccType === "usim") {
-            let gsmInfo = info.QueryInterface(Ci.nsIGsmIccInfo);
-            phoneNumber = gsmInfo.msisdn;
-          } else if (info.iccType === "ruim" || info.iccType === "csim") {
-            let cdmaInfo = info.QueryInterface(Ci.nsICdmaIccInfo);
-            phoneNumber = cdmaInfo.mdn;
-          }
-        } catch (e) {
-          log.error("Failed to retrieve phoneNumber: " + e);
-        }
-
-        let connection = this.mobileConnectionService.getItemByServiceId(i);
-        let voice = connection && connection.voice;
-        let data = connection && connection.data;
-        let operator = null;
-        if (voice &&
-            voice.network &&
-            voice.network.shortName &&
-            voice.network.shortName.length) {
-          operator = voice.network.shortName;
-        } else if (data &&
-                   data.network &&
-                   data.network.shortName &&
-                   data.network.shortName.length) {
-          operator = data.network.shortName;
-        }
-
-        this._iccInfo.push({
-          // Because it is possible that the _iccInfo array index doesn't match
-          // the real client ID, we need to store this value for later usage.
-          clientId: i,
-          iccId: info.iccid,
-          mcc: info.mcc,
-          mnc: info.mnc,
-          msisdn: phoneNumber,
-          operator: operator,
-          roaming: voice && voice.roaming
-        });
-
-        // We need to subscribe to ICC change notifications so we can refresh
-        // the cache if any change is observed.
-        icc.registerListener(iccListener);
-      }
-
-      return this._iccInfo;
-    } else {
-      return null;
-    }
-  },
-
-  get iccIds() {
-    if (AppConstants.MOZ_B2G_RIL) {
-      if (this._iccIds) {
-        return this._iccIds;
-      }
-
-      this._iccIds = [];
-      if (!this.iccInfo) {
-        return this._iccIds;
-      }
-
-      for (let i = 0; i < this.iccInfo.length; i++) {
-        this._iccIds.push(this.iccInfo[i].iccId);
-      }
-
-      return this._iccIds;
-    } else {
-      return null;
-    }
-  },
-
-  get credStore() {
-    if (!this._credStore) {
-      this._credStore = new MobileIdentityCredentialsStore();
-      this._credStore.init();
-    }
-    return this._credStore;
-  },
-
-  get ui() {
-    if (!this._ui) {
-      this._ui = Cc["@mozilla.org/services/mobileid-ui-glue;1"]
-                   .createInstance(Ci.nsIMobileIdentityUIGlue);
-      this._ui.oncancel = this.onUICancel.bind(this);
-      this._ui.onresendcode = this.onUIResendCode.bind(this);
-    }
-    return this._ui;
-  },
-
-  get client() {
-    if (!this._client) {
-      this._client = new MobileIdentityClient();
-    }
-    return this._client;
-  },
-
-  get isMultiSim() {
-    return this.iccInfo && this.iccInfo.length > 1;
-  },
-
-  getVerificationOptionsForIcc: function(aServiceId) {
-    log.debug("getVerificationOptionsForIcc " + aServiceId);
-    log.debug("iccInfo ${}", this.iccInfo[aServiceId]);
-    // First of all we need to check if we already have existing credentials
-    // for the given SIM information (ICC ID or MSISDN). If we have no valid
-    // credentials, we have to check with the server which options do we have
-    // to verify the associated phone number.
-    return this.credStore.getByIccId(this.iccInfo[aServiceId].iccId)
-    .then(
-      (creds) => {
-        if (creds) {
-          return creds;
-        }
-        return this.credStore.getByMsisdn(this.iccInfo[aServiceId].msisdn);
-      }
-    )
-    .then(
-      (creds) => {
-        if (creds) {
-          this.iccInfo[aServiceId].credentials = creds;
-          return;
-        }
-        // We have no credentials for this SIM, so we need to ask the server
-        // which options do we have to verify the phone number.
-        // But we need to be online...
-        if (Services.io.offline) {
-          return Promise.reject(ERROR_OFFLINE);
-        }
-        return this.client.discover(this.iccInfo[aServiceId].msisdn,
-                                    this.iccInfo[aServiceId].mcc,
-                                    this.iccInfo[aServiceId].mnc,
-                                    this.iccInfo[aServiceId].roaming);
-      }
-    )
-    .then(
-      (result) => {
-        // If we already have credentials for this ICC and no discover request
-        // is done, we just bail out.
-        if (!result || !result.verificationMethods) {
-          return;
-        }
-        log.debug("Discover result ${}", result);
-        this.iccInfo[aServiceId].verificationMethods = result.verificationMethods;
-        this.iccInfo[aServiceId].verificationDetails = result.verificationDetails;
-        this.iccInfo[aServiceId].canDoSilentVerification =
-          (result.verificationMethods.indexOf(SMS_MO_MT) != -1);
-        return;
-      }
-    );
-  },
-
-  getVerificationOptions: function() {
-    log.debug("getVerificationOptions");
-    // We try to get if we already have credentials for any of the inserted
-    // SIM cards if any is available and we try to get the possible
-    // verification mechanisms for these SIM cards.
-    // All this information will be stored in iccInfo.
-    if (!this.iccInfo || !this.iccInfo.length) {
-      let deferred = Promise.defer();
-      deferred.resolve(null);
-      return deferred.promise;
-    }
-
-    let promises = [];
-    for (let i = 0; i < this.iccInfo.length; i++) {
-      promises.push(this.getVerificationOptionsForIcc(i));
-    }
-    return Promise.all(promises);
-  },
-
-  getKeyPair: function(aSessionToken) {
-    if (this.keyPairs[aSessionToken] &&
-        this.keyPairs[aSessionToken].validUntil > this.client.hawk.now()) {
-      return Promise.resolve(this.keyPairs[aSessionToken].keyPair);
-    }
-
-    let validUntil = this.client.hawk.now() + KEY_LIFETIME;
-    let deferred = Promise.defer();
-    jwcrypto.generateKeyPair("DS160", (error, kp) => {
-      if (error) {
-        return deferred.reject(error);
-      }
-      this.keyPairs[aSessionToken] = {
-        keyPair: kp,
-        validUntil: validUntil
-      };
-      delete this.certificates[aSessionToken];
-      deferred.resolve(kp);
-    });
-
-    return deferred.promise;
-  },
-
-  getCertificate: function(aSessionToken, aPublicKey) {
-    log.debug("getCertificate");
-    if (this.certificates[aSessionToken] &&
-        this.certificates[aSessionToken].validUntil > this.client.hawk.now()) {
-      return Promise.resolve(this.certificates[aSessionToken].cert);
-    }
-
-    if (Services.io.offline) {
-      return Promise.reject(ERROR_OFFLINE);
-    }
-
-    let validUntil = this.client.hawk.now() + KEY_LIFETIME;
-    let deferred = Promise.defer();
-    this.client.sign(aSessionToken, CERTIFICATE_LIFETIME,
-                     aPublicKey)
-    .then(
-      (signedCert) => {
-        log.debug("Got signed certificate");
-        this.certificates[aSessionToken] = {
-          cert: signedCert.cert,
-          validUntil: validUntil
-        };
-        deferred.resolve(signedCert.cert);
-      },
-      deferred.reject
-    );
-    return deferred.promise;
-  },
-
-  /*********************************************************
-   * Setters (for test only purposes)
-   ********************************************************/
-  set ui(aUi) {
-    this._ui = aUi;
-  },
-
-  set credStore(aCredStore) {
-    this._credStore = aCredStore;
-  },
-
-  set client(aClient) {
-    this._client = aClient;
-  },
-
-  set iccInfo(aIccInfo) {
-    this._iccInfo = aIccInfo;
-  },
-
-  /*********************************************************
-   * UI callbacks
-   ********************************************************/
-
-  onUICancel: function() {
-    log.debug("UI cancel");
-    if (this.activeVerificationFlow) {
-      this.rejectVerification();
-    }
-  },
-
-  onUIResendCode: function() {
-    log.debug("UI resend code");
-    if (!this.activeVerificationFlow) {
-      return;
-    }
-    this.doVerification();
-  },
-
-  /*********************************************************
-   * Result helpers
-   *********************************************************/
-  success: function(aPromiseId, aResult) {
-    let mm = this.messageManagers[aPromiseId];
-    mm.sendAsyncMessage("MobileId:GetAssertion:Return:OK", {
-      promiseId: aPromiseId,
-      result: aResult
-    });
-  },
-
-  error: function(aPromiseId, aError) {
-    let mm = this.messageManagers[aPromiseId];
-    mm.sendAsyncMessage("MobileId:GetAssertion:Return:KO", {
-      promiseId: aPromiseId,
-      error: aError
-    });
-  },
-
-  /*********************************************************
-   * Permissions helper
-   ********************************************************/
-
-  addPermission: function(aPrincipal) {
-    permissionManager.addFromPrincipal(aPrincipal, MOBILEID_PERM,
-                                       Ci.nsIPermissionManager.ALLOW_ACTION);
-  },
-
-  /*********************************************************
-   * Phone number verification
-   ********************************************************/
-
-  rejectVerification: function(aReason) {
-    if (!this.activeVerificationDeferred) {
-      return;
-    }
-    this.activeVerificationDeferred.reject(aReason);
-    this.activeVerificationDeferred = null;
-    this.cleanupVerification(true /* unregister */);
-  },
-
-  resolveVerification: function(aResult) {
-    if (!this.activeVerificationDeferred) {
-      return;
-    }
-    this.activeVerificationDeferred.resolve(aResult);
-    this.activeVerificationDeferred = null;
-    this.cleanupVerification();
-  },
-
-  cleanupVerification: function(aUnregister = false) {
-    if (!this.activeVerificationFlow) {
-      return;
-    }
-    this.activeVerificationFlow.cleanup(aUnregister);
-    this.activeVerificationFlow = null;
-  },
-
-  doVerification: function() {
-    this.activeVerificationFlow.doVerification()
-    .then(
-      (verificationResult) => {
-        log.debug("onVerificationResult ");
-        if (!verificationResult || !verificationResult.sessionToken ||
-            !verificationResult.msisdn) {
-          return this.rejectVerification(
-            ERROR_INTERNAL_INVALID_VERIFICATION_RESULT
-          );
-        }
-        this.resolveVerification(verificationResult);
-      }
-    )
-    .then(
-      null,
-      reason => {
-        // Verification timeout.
-        log.warn("doVerification " + reason);
-      }
-    );
-  },
-
-  _verificationFlow: function(aToVerify, aOrigin) {
-    log.debug("toVerify ${}", aToVerify);
-
-    // We create the corresponding verification flow and save its instance
-    // in case that we need to cancel it or retrigger it because the user
-    // requested its cancelation or a resend of the verification code.
-    if (aToVerify.verificationMethod.indexOf(SMS_MT) != -1 &&
-        aToVerify.msisdn &&
-        aToVerify.verificationDetails &&
-        aToVerify.verificationDetails.mtSender) {
-      this.activeVerificationFlow = new MobileIdentitySmsMtVerificationFlow({
-          origin: aOrigin,
-          msisdn: aToVerify.msisdn,
-          mcc: aToVerify.mcc,
-          mnc: aToVerify.mnc,
-          iccId: aToVerify.iccId,
-          external: aToVerify.serviceId === undefined,
-          mtSender: aToVerify.verificationDetails.mtSender
-        },
-        this.ui,
-        this.client
-      );
-    } else if (AppConstants.MOZ_B2G_RIL &&
-               aToVerify.verificationMethod.indexOf(SMS_MO_MT) != -1 &&
-               aToVerify.serviceId &&
-               aToVerify.verificationDetails &&
-               aToVerify.verificationDetails.moVerifier &&
-               aToVerify.verificationDetails.mtSender) {
-      this.activeVerificationFlow = new MobileIdentitySmsMoMtVerificationFlow({
-          origin: aOrigin,
-          serviceId: aToVerify.serviceId,
-          iccId: aToVerify.iccId,
-          mtSender: aToVerify.verificationDetails.mtSender,
-          moVerifier: aToVerify.verificationDetails.moVerifier
-        },
-        this.ui,
-        this.client
-      );
-    } else {
-      return Promise.reject(ERROR_INTERNAL_CANNOT_VERIFY_SELECTION);
-    }
-
-    if (!this.activeVerificationFlow) {
-      return Promise.reject(ERROR_INTERNAL_CANNOT_CREATE_VERIFICATION_FLOW);
-    }
-
-    this.activeVerificationDeferred = Promise.defer();
-    this.doVerification();
-    return this.activeVerificationDeferred.promise;
-  },
-
-  verificationFlow: function(aUserSelection, aOrigin) {
-    log.debug("verificationFlow ${}", aUserSelection);
-
-    if (!aUserSelection) {
-      return Promise.reject(ERROR_INTERNAL_INVALID_USER_SELECTION);
-    }
-
-    let serviceId = aUserSelection.serviceId || undefined;
-    // We check if the user entered phone number corresponds with any of the
-    // inserted SIMs known phone numbers.
-    if (aUserSelection.msisdn && this.iccInfo) {
-      for (let i = 0; i < this.iccInfo.length; i++) {
-        if (aUserSelection.msisdn == this.iccInfo[i].msisdn) {
-          serviceId = i;
-          break;
-        }
-      }
-    }
-
-    let toVerify = {};
-
-    if (serviceId !== undefined) {
-      log.debug("iccInfo ${}", this.iccInfo[serviceId]);
-      toVerify.serviceId = serviceId;
-      toVerify.iccId = this.iccInfo[serviceId].iccId;
-      toVerify.msisdn = this.iccInfo[serviceId].msisdn;
-      toVerify.mcc = this.iccInfo[serviceId].mcc;
-      toVerify.mnc = this.iccInfo[serviceId].mnc;
-      toVerify.verificationMethod =
-        this.iccInfo[serviceId].verificationMethods[0];
-      toVerify.verificationDetails =
-        this.iccInfo[serviceId].verificationDetails[toVerify.verificationMethod];
-      return this._verificationFlow(toVerify, aOrigin);
-    } else {
-      toVerify.msisdn = aUserSelection.msisdn;
-      toVerify.mcc = aUserSelection.mcc;
-      return this.client.discover(aUserSelection.msisdn,
-                                  aUserSelection.mcc)
-      .then(
-        (discoverResult) => {
-          if (!discoverResult || !discoverResult.verificationMethods) {
-            return Promise.reject(ERROR_INTERNAL_UNEXPECTED);
-          }
-          log.debug("discoverResult ${}", discoverResult);
-          toVerify.verificationMethod = discoverResult.verificationMethods[0];
-          toVerify.verificationDetails =
-            discoverResult.verificationDetails[toVerify.verificationMethod];
-          return this._verificationFlow(toVerify, aOrigin);
-        }
-      );
-    }
-  },
-
-
-  /*********************************************************
-   * UI prompt functions.
-   ********************************************************/
-
-  // The phone number prompt will be used to confirm that the user wants to
-  // verify and share a known phone number and to allow her to introduce an
-  // external phone or to select between phone numbers or SIM cards (if the
-  // phones are not known) in a multi-SIM scenario.
-  // This prompt will be considered as the permission prompt and its choice
-  // will be remembered per origin by default.
-  prompt: function prompt(aPrincipal, aManifestURL, aPhoneInfo) {
-    log.debug("prompt ${principal} ${manifest} ${phoneInfo}", {
-      principal: aPrincipal,
-      manifest: aManifestURL,
-      phoneInfo: aPhoneInfo
-    });
-
-    let phoneInfoArray = [];
-
-    if (aPhoneInfo) {
-      phoneInfoArray.push(aPhoneInfo);
-    }
-
-    if (this.iccInfo) {
-      for (let i = 0; i < this.iccInfo.length; i++) {
-        // If we don't know the msisdn, there is no previous credentials and
-        // a silent verification is not possible or if the msisdn is the one
-        // that is already chosen, we don't list this SIM as an option.
-        if ((!this.iccInfo[i].msisdn && !this.iccInfo[i].credentials &&
-            !this.iccInfo[i].canDoSilentVerification) ||
-            ((aPhoneInfo) &&
-             (this.iccInfo[i].msisdn == aPhoneInfo.msisdn ||
-              this.iccInfo[i].iccId == aPhoneInfo.iccId))) {
-          continue;
-        }
-
-        let phoneInfo = new MobileIdentityUIGluePhoneInfo(
-          this.iccInfo[i].msisdn,
-          this.iccInfo[i].operator,
-          i,                      // service ID
-          this.iccInfo[i].iccId,  // iccId
-          false                   // primary
-        );
-        phoneInfoArray.push(phoneInfo);
-      }
-    }
-
-    return this.ui.startFlow(aManifestURL, phoneInfoArray)
-    .then(
-      (result) => {
-        log.debug("startFlow result ${} ", result);
-        if (!result ||
-            (!result.phoneNumber && (result.serviceId === undefined))) {
-          return Promise.reject(ERROR_INTERNAL_INVALID_PROMPT_RESULT);
-        }
-
-        let msisdn;
-        let mcc;
-
-        // If the user selected one of the existing SIM cards we have to check
-        // that we either have the MSISDN for that SIM, we have already existing
-        // credentials or we can do a silent verification that does not require
-        // us to have the MSISDN in advance.
-        // result.serviceId can be "0".
-        if (result.serviceId !== undefined &&
-            result.serviceId !== null) {
-          let icc = this.iccInfo[result.serviceId];
-          log.debug("icc ${}", icc);
-          if (!icc || !icc.msisdn && !icc.canDoSilentVerification &&
-              !icc.credentials) {
-            return Promise.reject(ERROR_INTERNAL_CANNOT_VERIFY_SELECTION);
-          }
-          msisdn = icc.msisdn;
-          mcc = icc.mcc;
-        } else {
-          msisdn = result.prefix ? result.prefix + result.phoneNumber
-                                 : result.phoneNumber;
-          mcc = result.mcc;
-        }
-
-        // We need to check that the selected phone number is valid and
-        // if it is not notify the UI about the error and allow the user to
-        // retry.
-        if (msisdn && mcc &&
-            !PhoneNumberUtils.parseWithMCC(msisdn, mcc)) {
-          this.ui.error(ERROR_INVALID_PHONE_NUMBER);
-          return this.prompt(aPrincipal, aManifestURL, aPhoneInfo);
-        }
-
-        log.debug("Selected msisdn (if any): " + msisdn + " - " + mcc);
-
-        // The user gave permission for the requester origin, so we store it.
-        this.addPermission(aPrincipal);
-
-        return {
-          msisdn: msisdn,
-          mcc: mcc,
-          serviceId: result.serviceId
-        };
-      }
-    );
-  },
-
-  promptAndVerify: function(aPrincipal, aManifestURL, aCreds) {
-    log.debug("promptAndVerify " + aPrincipal + ", " + aManifestURL +
-              ", ${}", aCreds);
-    let userSelection;
-
-    if (Services.io.offline) {
-      return Promise.reject(ERROR_OFFLINE);
-    }
-
-    // Before prompting the user we need to check with the server the
-    // phone number verification methods that are possible with the
-    // SIMs inserted in the device.
-    return this.getVerificationOptions()
-    .then(
-      () => {
-        // If we have an exisiting credentials, we add its associated
-        // phone number information to the list of choices to present
-        // to the user within the selection prompt.
-        let phoneInfo;
-        if (aCreds) {
-          phoneInfo = new MobileIdentityUIGluePhoneInfo(
-            aCreds.msisdn,
-            null,           // operator
-            undefined,      // service ID
-            aCreds.iccId,   // iccId
-            true            // primary
-          );
-        }
-        return this.prompt(aPrincipal, aManifestURL, phoneInfo);
-      }
-    )
-    .then(
-      (promptResult) => {
-        log.debug("promptResult ${}", promptResult);
-        // If we had credentials and the user didn't change her
-        // selection we return them. Otherwise, we need to verify
-        // the new number.
-        if (promptResult.msisdn && aCreds &&
-            promptResult.msisdn == aCreds.msisdn) {
-          return aCreds;
-        }
-
-        // We might already have credentials for the user selected icc. In
-        // that case, we update the credentials store with the new origin and
-        // return the credentials.
-        if (promptResult.serviceId) {
-          let creds = this.iccInfo[promptResult.serviceId].credentials;
-          if (creds) {
-            this.credStore.add(creds.iccId, creds.msisdn, aPrincipal.originNoSuffix,
-                               creds.sessionToken, this.iccIds);
-            return creds;
-          }
-        }
-
-        // Or we might already have credentials for the selected phone
-        // number and so we do the same: update the credentials store with the
-        // new origin and return the credentials.
-        return this.credStore.getByMsisdn(promptResult.msisdn)
-        .then(
-          (creds) => {
-            if (creds) {
-              this.credStore.add(creds.iccId, creds.msisdn, aPrincipal.originNoSuffix,
-                                 creds.sessionToken, this.iccIds);
-              return creds;
-            }
-            // Otherwise, we need to verify the new number selected by the
-            // user.
-            return this.verificationFlow(promptResult, aPrincipal.originNoSuffix);
-          }
-        );
-      }
-    );
-  },
-
-  /*********************************************************
-   * Credentials check
-   *********************************************************/
-
-  checkNewCredentials: function(aOldCreds, aNewCreds, aOrigin) {
-    // If there were previous credentials and the user changed her
-    // choice, we need to remove the origin from the old credentials.
-    if (aNewCreds.msisdn != aOldCreds.msisdn) {
-      return this.credStore.removeOrigin(aOldCreds.msisdn,
-                                         aOrigin)
-      .then(
-        () => {
-          return aNewCreds;
-        }
-      );
-    } else {
-      // Otherwise, we update the status of the SIM cards in the device
-      // so we know that the user decided not to take the chance to change
-      // her selection. We won't bother her again until a new SIM card
-      // change is detected.
-      return this.credStore.setDeviceIccIds(aOldCreds.msisdn, this.iccIds)
-      .then(
-        () => {
-          return aOldCreds;
-        }
-      );
-    }
-  },
-
-  /*********************************************************
-   * Assertion generation
-   ********************************************************/
-
-  generateAssertion: function(aCredentials, aOrigin) {
-    if (!aCredentials.sessionToken) {
-      return Promise.reject(ERROR_INTERNAL_INVALID_TOKEN);
-    }
-
-    let deferred = Promise.defer();
-
-    this.getKeyPair(aCredentials.sessionToken)
-    .then(
-      (keyPair) => {
-        log.debug("keyPair " + keyPair.serializedPublicKey);
-        let options = {
-          duration: ASSERTION_LIFETIME,
-          now: this.client.hawk.now(),
-          localtimeOffsetMsec: this.client.hawk.localtimeOffsetMsec
-        };
-
-        this.getCertificate(aCredentials.sessionToken,
-                            keyPair.serializedPublicKey)
-        .then(
-          (signedCert) => {
-            log.debug("generateAssertion " + signedCert);
-            jwcrypto.generateAssertion(signedCert, keyPair,
-                                       aOrigin, options,
-                                       (error, assertion) => {
-              if (error) {
-                log.error("Error generating assertion " + err);
-                deferred.reject(error);
-                return;
-              }
-              this.credStore.add(aCredentials.iccId,
-                                 aCredentials.msisdn,
-                                 aOrigin,
-                                 aCredentials.sessionToken,
-                                 this.iccIds)
-              .then(
-                () => {
-                  deferred.resolve(assertion);
-                }
-              );
-            });
-          }, deferred.reject
-        );
-      }
-    );
-
-    return deferred.promise;
-  },
-
-  getMobileIdAssertion: function(aPrincipal, aPromiseId, aOptions) {
-    log.debug("getMobileIdAssertion ${}", aPrincipal);
-
-    let principal = aPrincipal;
-    let manifestURL = appsService.getManifestURLByLocalId(aPrincipal.appId);
-
-    let permission = permissionManager.testPermissionFromPrincipal(
-      principal,
-      MOBILEID_PERM
-    );
-
-    if (permission == Ci.nsIPermissionManager.DENY_ACTION ||
-        permission == Ci.nsIPermissionManager.UNKNOWN_ACTION) {
-      this.error(aPromiseId, ERROR_PERMISSION_DENIED);
-      return;
-    }
-
-    let _creds;
-
-    // First of all we look if we already have credentials for this origin.
-    // If we don't have credentials it means that it is the first time that
-    // the caller requested an assertion.
-    this.credStore.getByOrigin(aPrincipal.originNoSuffix)
-    .then(
-      (creds) => {
-        log.debug("creds ${creds} - ${origin}", { creds: creds,
-                                                  origin: aPrincipal.originNoSuffix });
-        if (!creds || !creds.sessionToken) {
-          log.debug("No credentials");
-          return;
-        }
-
-        _creds = creds;
-
-        // Even if we already have credentials for this origin, the consumer
-        // of the API might want to force the identity selection dialog.
-        if (aOptions.forceSelection || aOptions.refreshCredentials) {
-          return this.promptAndVerify(principal, manifestURL, creds)
-          .then(
-            (newCreds) => {
-              return this.checkNewCredentials(creds, newCreds,
-                                              principal.originNoSuffix);
-            }
-          );
-        }
-
-        // SIM change scenario.
-
-        // It is possible that the SIM cards inserted in the device at the
-        // moment of the previous verification where we obtained the credentials
-        // has changed. In that case, we need to let the user knowabout this
-        // situation. Otherwise, we just return the credentials.
-        log.debug("Looking for SIM changes. Credentials ICCS ${creds} " +
-                  "Device ICCS ${device}", { creds: creds.deviceIccIds,
-                                             device: this.iccIds });
-        let simChanged = (creds.deviceIccIds == null && this.iccIds != null) ||
-                         (creds.deviceIccIds != null && this.iccIds == null);
-
-        if (!simChanged &&
-            creds.deviceIccIds != null &&
-            this.iccIds != null) {
-          simChanged = creds.deviceIccIds.length != this.iccIds.length;
-        }
-
-        if (!simChanged &&
-            creds.deviceIccIds != null &&
-            this.iccIds != null) {
-          let intersection = creds.deviceIccIds.filter((n) => {
-            return this.iccIds.indexOf(n) != -1;
-          });
-          simChanged = intersection.length != creds.deviceIccIds.length ||
-                       intersection.length != this.iccIds.length;
-        }
-
-        if (!simChanged) {
-          return creds;
-        }
-
-        // At this point we know that the SIM associated with the credentials
-        // is not present in the device any more or a new SIM has been detected,
-        // so we need to ask the user what to do.
-        return this.promptAndVerify(principal, manifestURL, creds)
-        .then(
-          (newCreds) => {
-            return this.checkNewCredentials(creds, newCreds,
-                                            principal.originNoSuffix);
-          }
-        );
-      }
-    )
-    .then(
-      (creds) => {
-        // Even if we have credentails it is possible that the user has
-        // removed the permission to share its mobile id with this origin, so
-        // we check the permission and if it is not granted, we ask the user
-        // before generating and sharing the assertion.
-        // If we've just prompted the user in the previous step, the permission
-        // is already granted and stored so we just progress the credentials.
-        // But we have to refresh the cached permission before checking.
-        if (creds) {
-          permission = permissionManager.testPermissionFromPrincipal(
-            principal,
-            MOBILEID_PERM
-          );
-          if (permission == Ci.nsIPermissionManager.ALLOW_ACTION) {
-            return creds;
-          }
-          return this.promptAndVerify(principal, manifestURL, creds);
-        }
-        return this.promptAndVerify(principal, manifestURL);
-      }
-    )
-    .then(
-      (creds) => {
-        if (creds) {
-          return this.generateAssertion(creds, principal.originNoSuffix);
-        }
-        return Promise.reject(ERROR_INTERNAL_CANNOT_GENERATE_ASSERTION);
-      }
-    )
-    .then(
-      (assertion) => {
-        if (!assertion) {
-          return Promise.reject(ERROR_INTERNAL_CANNOT_GENERATE_ASSERTION);
-        }
-
-        // Get the verified phone number from the assertion.
-        let segments = assertion.split(".");
-        if (!segments) {
-          return Promise.reject(ERROR_INVALID_ASSERTION);
-        }
-
-        let payloadBuffer = ChromeUtils.base64URLDecode(segments[1], {
-          // `IdentityCryptoService` pads output.
-          padding: "require",
-        });
-        let textDecoder = new TextDecoder("utf-8");
-        let decodedPayload = JSON.parse(textDecoder.decode(payloadBuffer));
-
-        if (!decodedPayload || !decodedPayload.verifiedMSISDN) {
-          return Promise.reject(ERROR_INVALID_ASSERTION);
-        }
-
-        this.ui.verified(decodedPayload.verifiedMSISDN);
-
-        this.success(aPromiseId, assertion);
-      }
-    )
-    .then(
-      null,
-      (error) => {
-        log.error("getMobileIdAssertion rejected with ${}", error);
-
-        // If we got an invalid token error means that the credentials that
-        // we have are not valid anymore and so we need to refresh them. We
-        // do that removing the stored credentials and starting over. We also
-        // make sure that we do this only once.
-        if (error === ERROR_INVALID_AUTH_TOKEN &&
-            !aOptions.refreshCredentials) {
-          log.debug("Need to get new credentials");
-          aOptions.refreshCredentials = true;
-          _creds && this.credStore.delete(_creds.msisdn);
-          this.getMobileIdAssertion(aPrincipal, aPromiseId, aOptions);
-          return;
-        }
-
-        // Notify the error to the UI.
-        this.ui.error(error);
-
-        this.error(aPromiseId, error);
-      }
-    );
-  },
-
-};
-
-if (AppConstants.MOZ_B2G_RIL) {
-  // We have these getters to allow mocking RIL stuff from the tests.
-  Object.defineProperties(MobileIdentityManager, {
-    "ril": {
-      configurable: true,
-      enumerable: true,
-      get() {
-        if (this._ril) {
-          return this._ril;
-        }
-        return Ril;
-      }
-    },
-    "iccService": {
-      configurable: true,
-      enumerable: true,
-      get() {
-        if (this._iccService) {
-          return this._iccService;
-        }
-        return IccService;
-      }
-    },
-    "mobileConnectionService": {
-      configurable: true,
-      enumerable: true,
-      get() {
-        if (this._mobileConnectionService) {
-          return this._mobileConnectionService;
-        }
-        return MobileConnectionService;
-      }
-    }
-  });
-}
-
-MobileIdentityManager.init();
deleted file mode 100644
--- a/services/mobileid/MobileIdentitySmsMoMtVerificationFlow.jsm
+++ /dev/null
@@ -1,79 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-this.EXPORTED_SYMBOLS = ["MobileIdentitySmsMoMtVerificationFlow"];
-
-const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
-
-Cu.import("resource://gre/modules/MobileIdentityCommon.jsm");
-Cu.import("resource://gre/modules/MobileIdentitySmsVerificationFlow.jsm");
-Cu.import("resource://gre/modules/Promise.jsm");
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-
-XPCOMUtils.defineLazyServiceGetter(this, "smsService",
-                                   "@mozilla.org/sms/smsservice;1",
-                                   "nsISmsService");
-
-// In order to send messages through nsISmsService, we need to implement
-// nsIMobileMessageCallback, as the WebSMS API implementation is not usable
-// from JS.
-function SilentSmsRequest(aDeferred) {
-  this.deferred = aDeferred;
-}
-SilentSmsRequest.prototype = {
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsIMobileMessageCallback]),
-
-  classID: Components.ID("{ff46f1a8-e040-4ff4-98a7-d5a5b86a2c3e}"),
-
-  notifyMessageSent: function notifyMessageSent(aMessage) {
-    log.debug("Silent message successfully sent");
-    this.deferred.resolve(aMessage);
-  },
-
-  notifySendMessageFailed: function notifySendMessageFailed(aError) {
-    log.error("Error sending silent message " + aError);
-    this.deferred.reject(aError);
-  }
-};
-
-this.MobileIdentitySmsMoMtVerificationFlow = function(aVerificationOptions,
-                                                      aUI,
-                                                      aClient) {
-
-  log.debug("MobileIdentitySmsMoMtVerificationFlow ${}", aVerificationOptions);
-
-  MobileIdentitySmsVerificationFlow.call(this,
-                                         aVerificationOptions,
-                                         aUI,
-                                         aClient,
-                                         this.smsVerifyStrategy);
-};
-
-this.MobileIdentitySmsMoMtVerificationFlow.prototype = {
-
-  __proto__: MobileIdentitySmsVerificationFlow.prototype,
-
-  smsVerifyStrategy: function() {
-    // In the MO+MT flow we need to send an SMS to the given moVerifier number
-    // so the server can find out our phone number to send an SMS back with a
-    // verification code.
-    let deferred = Promise.defer();
-    let silentSmsRequest = new SilentSmsRequest(deferred);
-
-    // The MO SMS body that the server expects contains the API endpoint for
-    // the MO verify request and the HAWK ID parameter derived via HKDF from
-    // the session token. These parameters should go unnamed and space limited.
-    let body = SMS_MO_MT_VERIFY + " " +
-               this.client._deriveHawkCredentials(this.sessionToken).id;
-    smsService.send(this.verificationOptions.serviceId,
-                    this.verificationOptions.moVerifier,
-                    body,
-                    true, // silent
-                    silentSmsRequest);
-    log.debug("Sending " + body + " to " + this.verificationOptions.moVerifier);
-    return deferred.promise;
-  }
-};
deleted file mode 100644
--- a/services/mobileid/MobileIdentitySmsMtVerificationFlow.jsm
+++ /dev/null
@@ -1,40 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-this.EXPORTED_SYMBOLS = ["MobileIdentitySmsMtVerificationFlow"];
-
-const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
-
-Cu.import("resource://gre/modules/MobileIdentityCommon.jsm");
-Cu.import("resource://gre/modules/MobileIdentitySmsVerificationFlow.jsm");
-Cu.import("resource://gre/modules/Promise.jsm");
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-
-this.MobileIdentitySmsMtVerificationFlow = function(aVerificationOptions,
-                                                    aUI,
-                                                    aClient) {
-
-  log.debug("MobileIdentitySmsVerificationFlow ${}", aVerificationOptions);
-
-  MobileIdentitySmsVerificationFlow.call(this,
-                                         aVerificationOptions,
-                                         aUI,
-                                         aClient,
-                                         this.smsVerifyStrategy);
-};
-
-this.MobileIdentitySmsMtVerificationFlow.prototype = {
-
-  __proto__: MobileIdentitySmsVerificationFlow.prototype,
-
-  smsVerifyStrategy: function() {
-    return this.client.smsMtVerify(this.sessionToken,
-                                   this.verificationOptions.msisdn,
-                                   this.verificationOptions.mcc,
-                                   this.verificationOptions.mnc,
-                                   this.verificationOptions.external);
-  }
-};
deleted file mode 100644
--- a/services/mobileid/MobileIdentitySmsVerificationFlow.jsm
+++ /dev/null
@@ -1,109 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-this.EXPORTED_SYMBOLS = ["MobileIdentitySmsVerificationFlow"];
-
-const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
-
-Cu.import("resource://gre/modules/AppConstants.jsm");
-Cu.import("resource://gre/modules/MobileIdentityCommon.jsm");
-Cu.import("resource://gre/modules/MobileIdentityVerificationFlow.jsm");
-Cu.import("resource://gre/modules/Promise.jsm");
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-
-if (AppConstants.MOZ_B2G_RIL) {
-  XPCOMUtils.defineLazyServiceGetter(this, "smsService",
-                                     "@mozilla.org/sms/smsservice;1",
-                                     "nsISmsService");
-}
-
-this.MobileIdentitySmsVerificationFlow = function(aVerificationOptions,
-                                                  aUI,
-                                                  aClient,
-                                                  aVerifyStrategy) {
-
-  // SMS MT or SMS MO+MT specific verify strategy.
-  this.smsVerifyStrategy = aVerifyStrategy;
-
-  log.debug("aVerificationOptions ${}", aVerificationOptions);
-  MobileIdentityVerificationFlow.call(this, aVerificationOptions, aUI, aClient,
-                                      this._verifyStrategy, this._cleanupStrategy);
-};
-
-this.MobileIdentitySmsVerificationFlow.prototype = {
-
-  __proto__: MobileIdentityVerificationFlow.prototype,
-
-  observedSilentNumber: null,
-
-  onSilentSms: null,
-
-  _verifyStrategy: function() {
-    if (!this.smsVerifyStrategy) {
-      return Promise.reject(ERROR_INTERNAL_UNEXPECTED);
-    }
-
-    // Even if the user selection is given to us as a possible external phone
-    // number, it is also possible that the phone number introduced by the
-    // user belongs to one of the SIMs inserted in the device which MSISDN
-    // is unknown for us, so we always observe for incoming messages coming
-    // from the given mtSender.
-
-    if (AppConstants.MOZ_B2G_RIL) {
-      this.observedSilentNumber = this.verificationOptions.mtSender;
-      try {
-        smsService.addSilentNumber(this.observedSilentNumber);
-      } catch (e) {
-        log.warn("We are already listening for that number");
-      }
-
-      this.onSilentSms = (function(aSubject, aTopic, aData) {
-        log.debug("Got silent message " + aSubject.sender + " - " + aSubject.body);
-        // We might have observed a notification of an incoming silent message
-        // for other number. In that case, we just bail out.
-        if (aSubject.sender != this.observedSilentNumber) {
-          return;
-        }
-
-        // We got the SMS containing the verification code.
-
-        // If the phone number we are trying to verify is or can be an external
-        // phone number (meaning that it doesn't belong to any of the inserted
-        // SIMs) we will be receiving an human readable SMS containing a short
-        // verification code. In this case we need to parse the SMS body to
-        // extract the verification code.
-        // Otherwise, we just use the whole SMS body as it should contain a long
-        // verification code.
-        let verificationCode = aSubject.body;
-        if (this.verificationOptions.external) {
-          // We just take the numerical characters from the body.
-          verificationCode = aSubject.body.replace(/[^0-9]/g,'');
-        }
-
-        log.debug("Verification code: " + verificationCode);
-
-        this.verificationCodeDeferred.resolve(verificationCode);
-      }).bind(this);
-
-      Services.obs.addObserver(this.onSilentSms,
-                               SILENT_SMS_RECEIVED_TOPIC,
-                               false);
-      log.debug("Observing messages from " + this.observedSilentNumber);
-    }
-
-    return this.smsVerifyStrategy();
-  },
-
-  _cleanupStrategy: function() {
-    if (AppConstants.MOZ_B2G_RIL) {
-      smsService.removeSilentNumber(this.observedSilentNumber);
-      Services.obs.removeObserver(this.onSilentSms,
-                                  SILENT_SMS_RECEIVED_TOPIC);
-      this.observedSilentNumber = null;
-      this.onSilentSms = null;
-    }
-  }
-};
deleted file mode 100644
--- a/services/mobileid/MobileIdentityUIGlueCommon.jsm
+++ /dev/null
@@ -1,32 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-this.EXPORTED_SYMBOLS = ["MobileIdentityUIGluePhoneInfo",
-                         "MobileIdentityUIGluePromptResult"];
-
-this.MobileIdentityUIGluePhoneInfo = function (aMsisdn, aOperator, aServiceId,
-                                               aIccId, aPrimary) {
-  this.msisdn = aMsisdn;
-  this.operator = aOperator;
-  this.serviceId = aServiceId;
-  this.iccId = aIccId;
-  // A phone number is considered "external" when it doesn't or we don't know
-  // if it does belong to any of the device SIM cards.
-  this.external = !!aIccId;
-  this.primary = aPrimary;
-}
-
-this.MobileIdentityUIGluePhoneInfo.prototype = {};
-
-this.MobileIdentityUIGluePromptResult = function (aPhoneNumber, aPrefix, aMcc,
-                                                  aServiceId) {
-  this.phoneNumber = aPhoneNumber;
-  this.prefix = aPrefix;
-  this.mcc = aMcc;
-  this.serviceId = aServiceId;
-}
-
-this.MobileIdentityUIGluePromptResult.prototype = {};
deleted file mode 100644
--- a/services/mobileid/MobileIdentityVerificationFlow.jsm
+++ /dev/null
@@ -1,215 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-this.EXPORTED_SYMBOLS = ["MobileIdentityVerificationFlow"];
-
-const { utils: Cu, classes: Cc, interfaces: Ci } = Components;
-
-Cu.import("resource://gre/modules/MobileIdentityCommon.jsm");
-Cu.import("resource://gre/modules/Promise.jsm");
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-
-this.MobileIdentityVerificationFlow = function(aVerificationOptions,
-                                               aUI,
-                                               aClient,
-                                               aVerifyStrategy,
-                                               aCleanupStrategy) {
-  this.verificationOptions = aVerificationOptions;
-  this.ui = aUI;
-  this.client = aClient;
-  this.retries = VERIFICATIONCODE_RETRIES;
-  this.verifyStrategy = aVerifyStrategy;
-  this.cleanupStrategy = aCleanupStrategy;
-};
-
-MobileIdentityVerificationFlow.prototype = {
-
-  doVerification: function() {
-    log.debug("Start verification flow");
-    return this.register()
-    .then(
-      (registerResult) => {
-        log.debug("Register result ${}", registerResult);
-        if (!registerResult || !registerResult.msisdnSessionToken) {
-          return Promise.reject(ERROR_INTERNAL_UNEXPECTED);
-        }
-        this.sessionToken = registerResult.msisdnSessionToken;
-        // We save the timestamp of the start of the verification timeout to be
-        // able to provide to the UI the remaining time on each retry.
-        if (!this.timer) {
-          log.debug("Creating verification code timer");
-          this.timerCreation = Date.now();
-          this.timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
-          this.timer.initWithCallback(this.onVerificationCodeTimeout.bind(this),
-                                      VERIFICATIONCODE_TIMEOUT,
-                                      this.timer.TYPE_ONE_SHOT);
-        }
-
-        if (!this.verifyStrategy) {
-          return Promise.reject(ERROR_INTERNAL_INVALID_VERIFICATION_FLOW);
-        }
-
-        return this.verifyStrategy()
-        .then(() => {
-          return this._doVerification();
-        }, (reason) => {
-          this.verificationCodeDeferred.reject(reason);
-        });
-      }
-    )
-  },
-
-  _doVerification: function() {
-    log.debug("_doVerification");
-
-    this.verificationCodeDeferred = Promise.defer();
-
-    // If the verification flow can be for an external phone number,
-    // we need to ask the user for the verification code.
-    // In that case we don't do a notification about the verification
-    // process being done until the user enters the verification code
-    // in the UI.
-    if (this.verificationOptions.external) {
-      let timeLeft = 0;
-      if (this.timer) {
-        timeLeft = this.timerCreation + VERIFICATIONCODE_TIMEOUT -
-                   Date.now();
-      }
-      this.ui.verificationCodePrompt(this.retries,
-                                     VERIFICATIONCODE_TIMEOUT / 1000,
-                                     timeLeft / 1000)
-      .then(
-        (verificationCode) => {
-          if (!verificationCode) {
-            return this.verificationCodeDeferred.reject(
-              ERROR_INTERNAL_INVALID_PROMPT_RESULT);
-          }
-          // If the user got the verification code that means that the
-          // introduced phone number didn't belong to any of the inserted
-          // SIMs.
-          this.ui.verify();
-          this.verificationCodeDeferred.resolve(verificationCode);
-        }
-      );
-    } else {
-      this.ui.verify();
-    }
-
-    return this.verificationCodeDeferred.promise.then(
-      this.onVerificationCode.bind(this)
-    );
-  },
-
-  // When we receive a verification code from the UI, we check it against
-  // the server. If the verification code is incorrect, we decrease the
-  // number of retries left and allow the user to try again. If there is no
-  // possible retry left, we notify about this error so the UI can allow the
-  // user to request the resend of a new verification code.
-  onVerificationCode: function(aVerificationCode) {
-    log.debug("onVerificationCode " + aVerificationCode);
-    if (!aVerificationCode) {
-      this.ui.error(ERROR_INVALID_VERIFICATION_CODE);
-      return this._doVerification();
-    }
-
-    // Before checking the verification code against the server we set the
-    // "verifying" flag to queue timeout expiration events received before
-    // the server request is completed. If the server request is positive
-    // we will discard the timeout event, otherwise we will progress the
-    // event to the UI to allow the user to retry.
-    this.verifying = true;
-
-    return this.verifyCode(aVerificationCode)
-    .then(
-      (result) => {
-        if (!result) {
-          return Promise.reject(INTERNAL_UNEXPECTED);
-        }
-        // The code was correct!
-        // At this point the phone number is verified.
-        // We return the given verification options with the session token
-        // to be stored in the credentials store. With this data we will be
-        // asking the server to give us a certificate to generate assertions.
-        this.verificationOptions.sessionToken = this.sessionToken;
-        this.verificationOptions.msisdn = result.msisdn ||
-                                          this.verificationOptions.msisdn;
-        return this.verificationOptions;
-      },
-      (error) => {
-        log.error("Verification code error " + error);
-        this.retries--;
-        log.error("Retries left " + this.retries);
-        if (!this.retries) {
-          this.ui.error(ERROR_NO_RETRIES_LEFT);
-          this.timer.cancel();
-          this.timer = null;
-          return Promise.reject(ERROR_NO_RETRIES_LEFT);
-        }
-        this.ui.error(ERROR_INVALID_VERIFICATION_CODE);
-        this.verifying = false;
-        if (this.queuedTimeout) {
-          this.onVerificationCodeTimeout();
-        }
-        return this._doVerification();
-      }
-    );
-  },
-
-  onVerificationCodeTimeout: function() {
-    // It is possible that we get the timeout when we are checking a
-    // verification code with the server. In that case, we queue the
-    // timeout to be triggered after we receive the reply from the server
-    // if needed.
-    if (this.verifying) {
-      this.queuedTimeout = true;
-      return;
-    }
-
-    // When the verification process times out we do a clean up, reject
-    // the corresponding promise and notify the UI about the timeout.
-    if (this.verificationCodeDeferred) {
-      this.verificationCodeDeferred.reject(ERROR_VERIFICATION_CODE_TIMEOUT);
-    }
-    this.ui.error(ERROR_VERIFICATION_CODE_TIMEOUT);
-  },
-
-  register: function() {
-    return this.client.register();
-  },
-
-  verifyCode: function(aVerificationCode) {
-    return this.client.verifyCode(this.sessionToken, aVerificationCode);
-  },
-
-  unregister: function() {
-    return this.client.unregister(this.sessionToken);
-  },
-
-  cleanup: function(aUnregister = false) {
-    log.debug("Verification flow cleanup");
-
-    this.queuedTimeout = false;
-    this.retries = VERIFICATIONCODE_RETRIES;
-
-    if (this.timer) {
-      this.timer.cancel();
-      this.timer = null;
-    }
-
-    if (aUnregister) {
-      this.unregister().
-      then(
-        () => {
-          this.sessionToken = null;
-        }
-      );
-    }
-
-    if (this.cleanupStrategy) {
-      this.cleanupStrategy();
-    }
-  }
-};
deleted file mode 100644
--- a/services/mobileid/interfaces/moz.build
+++ /dev/null
@@ -1,11 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-XPIDL_SOURCES += [
-    'nsIMobileIdentityUIGlue.idl'
-]
-
-XPIDL_MODULE = 'services_mobileidentity'
deleted file mode 100644
--- a/services/mobileid/interfaces/nsIMobileIdentityUIGlue.idl
+++ /dev/null
@@ -1,77 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "nsISupports.idl"
-
-[scriptable, uuid(6c4c5758-e041-4e0d-98da-67bb552f8018)]
-interface nsIMobileIdentityUIGlue : nsISupports
-{
-  /**
-  * Request the creation of a Mobile ID UI flow.
-  *
-  * The permission prompt starts the verification flow asking the user
-  * for permission to share her phone number and allowing her to choose
-  * an already known phone number, a SIM which phone number is unknown
-  * (even in a multi-SIM scenario) or an external phone number.
-  * Selecting a phone number implies giving permission to share it with the
-  * API caller, so the UI should be clear about this.
-  *
-  * @manifestURL manifest URL of the mobile ID requester.
-  * @iccInfo array of objects containing the information about the
-  *          SIM cards available in the device and that can be used for the
-  *          phone number verification and share process.
-  *
-  * Returns a Promise. An instance of nsIMobileIdentityUIGluePromptResult will
-  * be returned as result of the Promise or a single string containing an error
-  * in case of rejection.
-  */
-  jsval startFlow(in DOMString manifestURL, in jsval iccInfo);
-
-  /**
-   * Will prompt the user to enter a code used to verify a phone number.
-   * This will only be called if an external phone number is selected in
-   * startFlow().
-   *
-   * @retries number of retries left to validate a verification code.
-   * @timeout the verification code expires after the timeout fires. This is
-   *          the total life time of the verification code.
-   * @timeLeft we might call verificationCodePrompt more than once for the
-   *           same verification flow (i.e. when the verification code entered
-   *           by the user is incorrect) so we give to the UI the amount of
-   *           time left before the verification code expires.
-   *
-   * Returns a Promise. The value of the resolved promise will be the
-   * verification code introduced through the UI or an error in case of
-   * rejection of the promise.
-   */
-  jsval verificationCodePrompt(in short retries,
-                               in long timeout,
-                               in long timeLeft);
-
-  /**
-   * Notify the UI about the start of the verification process.
-   */
-  void verify();
-
-  /**
-   * Notify the UI about an error in the verification process.
-   */
-  void error(in DOMString error);
-
-  /**
-   * Notify the UI about the succesful phone number verification.
-   */
-  void verified(in DOMString verifiedPhoneNumber);
-
-  /**
-   * Callback to be called when the user cancels the verification flow via UI.
-   */
-  attribute jsval oncancel;
-
-  /**
-   * Callback to be called when the user requests a resend of a verification
-   * code.
-   */
-  attribute jsval onresendcode;
-};
deleted file mode 100644
--- a/services/mobileid/moz.build
+++ /dev/null
@@ -1,21 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-DIRS += ['interfaces']
-
-XPCSHELL_TESTS_MANIFESTS += ['tests/xpcshell/xpcshell.ini']
-
-EXTRA_JS_MODULES += [
-    'MobileIdentityClient.jsm',
-    'MobileIdentityCommon.jsm',
-    'MobileIdentityCredentialsStore.jsm',
-    'MobileIdentityManager.jsm',
-    'MobileIdentitySmsMoMtVerificationFlow.jsm',
-    'MobileIdentitySmsMtVerificationFlow.jsm',
-    'MobileIdentitySmsVerificationFlow.jsm',
-    'MobileIdentityUIGlueCommon.jsm',
-    'MobileIdentityVerificationFlow.jsm'
-]
deleted file mode 100644
--- a/services/mobileid/tests/xpcshell/head.js
+++ /dev/null
@@ -1,439 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-var {classes: Cc, interfaces: Ci, results: Cr, utils: Cu} = Components;
-
-var Cm = Components.manager;
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-
-(function initMobileIdTestingInfrastructure() {
-  do_get_profile();
-
-  const PREF_FORCE_HTTPS = "services.mobileid.forcehttps";
-  Services.prefs.setBoolPref(PREF_FORCE_HTTPS, false);
-  Services.prefs.setCharPref("services.mobileid.loglevel", "Debug");
-  Services.prefs.setCharPref("services.mobileid.server.uri",
-                             "https://dummyurl.com");
-}).call(this);
-
-const DEBUG = false;
-
-const GET_ASSERTION_IPC_MSG = "MobileId:GetAssertion";
-const GET_ASSERTION_RETURN_OK = "MobileId:GetAssertion:Return:OK";
-const GET_ASSERTION_RETURN_KO = "MobileId:GetAssertion:Return:KO";
-
-// === Globals ===
-
-const ORIGIN = "app://afakeorigin";
-const APP_ID = 1;
-const PRINCIPAL = {
-  origin: ORIGIN,
-  appId: APP_ID
-};
-const PHONE_NUMBER = "+34666555444";
-const ANOTHER_PHONE_NUMBER = "+44123123123";
-const VERIFICATION_CODE = "123456";
-const SESSION_TOKEN = "aSessionToken";
-const ICC_ID = "aIccId";
-const ANOTHER_ICC_ID = "anotherIccId";
-const MNC = "aMnc";
-const ANOTHER_MNC = "anotherMnc";
-const MCC = "aMcc";
-const ANOTHER_MCC = "anotherMcc";
-const OPERATOR = "aOperator";
-const ANOTHER_OPERATOR = "anotherOperator";
-const ICC_INFO = {
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsIGsmIccInfo,
-                                         Ci.nsIIccInfo]),
-  iccType: "usim",
-  iccid: ICC_ID,
-  mcc: MCC,
-  mnc: MNC,
-  msisdn: PHONE_NUMBER,
-  operator: OPERATOR
-};
-const ANOTHER_ICC_INFO = {
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsIGsmIccInfo,
-                                         Ci.nsIIccInfo]),
-  iccType: "usim",
-  iccid: ANOTHER_ICC_ID,
-  mcc: ANOTHER_MCC,
-  mnc: ANOTHER_MNC,
-  msisdn: ANOTHER_PHONE_NUMBER,
-  operator: ANOTHER_OPERATOR
-};
-const INVALID_ICC_INFO = {
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsIGsmIccInfo,
-                                         Ci.nsIIccInfo]),
-  iccType: "usim",
-  iccid: null,
-  mcc: "",
-  mnc: "",
-  msisdn: "",
-  operator: ""
-};
-const RADIO_INTERFACE = {
-  voice: {
-    network: {
-      shortName: OPERATOR
-    },
-    roaming: false
-  },
-  data: {
-    network: {
-      shortName: OPERATOR
-    }
-  }
-};
-const ANOTHER_RADIO_INTERFACE = {
-  voice: {
-    network: {
-      shortName: ANOTHER_OPERATOR
-    },
-    roaming: false
-  },
-  data: {
-    network: {
-      shortName: ANOTHER_OPERATOR
-    }
-  }
-};
-
-const INVALID_RADIO_INTERFACE = {
-  voice: {
-    network: {
-      shortName: ""
-    },
-    roaming: undefined
-  },
-  data: {
-    network: {
-      shortName: ""
-    }
-  }
-};
-
-const CERTIFICATE = "eyJhbGciOiJEUzI1NiJ9.eyJsYXN0QXV0aEF0IjoxNDA0NDY5NzkyODc3LCJ2ZXJpZmllZE1TSVNETiI6IiszMTYxNzgxNTc1OCIsInB1YmxpYy1rZXkiOnsiYWxnb3JpdGhtIjoiRFMiLCJ5IjoiNGE5YzkzNDY3MWZhNzQ3YmM2ZjMyNjE0YTg1MzUyZjY5NDcwMDdhNTRkMDAxMDY4OWU5ZjJjZjc0ZGUwYTEwZTRlYjlmNDk1ZGFmZTA0NGVjZmVlNDlkN2YwOGU4ODQyMDJiOTE5OGRhNWZhZWE5MGUzZjRmNzE1YzZjNGY4Yjc3MGYxZTU4YWZhNDM0NzVhYmFiN2VlZGE1MmUyNjk2YzFmNTljNzMzYjFlYzBhNGNkOTM1YWIxYzkyNzAxYjNiYTA5ZDRhM2E2MzNjNTJmZjE2NGYxMWY3OTg1YzlmZjY3ZThmZDFlYzA2NDU3MTdkMjBiNDE4YmM5M2YzYzVkNCIsInAiOiJmZjYwMDQ4M2RiNmFiZmM1YjQ1ZWFiNzg1OTRiMzUzM2Q1NTBkOWYxYmYyYTk5MmE3YThkYWE2ZGMzNGY4MDQ1YWQ0ZTZlMGM0MjlkMzM0ZWVlYWFlZmQ3ZTIzZDQ4MTBiZTAwZTRjYzE0OTJjYmEzMjViYTgxZmYyZDVhNWIzMDVhOGQxN2ViM2JmNGEwNmEzNDlkMzkyZTAwZDMyOTc0NGE1MTc5MzgwMzQ0ZTgyYTE4YzQ3OTMzNDM4Zjg5MWUyMmFlZWY4MTJkNjljOGY3NWUzMjZjYjcwZWEwMDBjM2Y3NzZkZmRiZDYwNDYzOGMyZWY3MTdmYzI2ZDAyZTE3IiwicSI6ImUyMWUwNGY5MTFkMWVkNzk5MTAwOGVjYWFiM2JmNzc1OTg0MzA5YzMiLCJnIjoiYzUyYTRhMGZmM2I3ZTYxZmRmMTg2N2NlODQxMzgzNjlhNjE1NGY0YWZhOTI5NjZlM2M4MjdlMjVjZmE2Y2Y1MDhiOTBlNWRlNDE5ZTEzMzdlMDdhMmU5ZTJhM2NkNWRlYTcwNGQxNzVmOGViZjZhZjM5N2Q2OWUxMTBiOTZhZmIxN2M3YTAzMjU5MzI5ZTQ4MjliMGQwM2JiYzc4OTZiMTViNGFkZTUzZTEzMDg1OGNjMzRkOTYyNjlhYTg5MDQxZjQwOTEzNmM3MjQyYTM4ODk1YzlkNWJjY2FkNGYzODlhZjFkN2E0YmQxMzk4YmQwNzJkZmZhODk2MjMzMzk3YSJ9LCJwcmluY2lwYWwiOiIwMzgxOTgyYS0xZTgzLTI1NjYtNjgzZS05MDRmNDA0NGM1MGRAbXNpc2RuLWRldi5zdGFnZS5tb3phd3MubmV0IiwiaWF0IjoxNDA0NDY5NzgyODc3LCJleHAiOjE0MDQ0OTEzOTI4NzcsImlzcyI6Im1zaXNkbi1kZXYuc3RhZ2UubW96YXdzLm5ldCJ9."
-
-// === Helpers ===
-
-function addPermission(aAction) {
-  let uri = Cc["@mozilla.org/network/io-service;1"]
-              .getService(Ci.nsIIOService)
-              .newURI(ORIGIN, null, null);
-  let attrs = {appId: APP_ID};
-  let _principal = Cc["@mozilla.org/scriptsecuritymanager;1"]
-                     .getService(Ci.nsIScriptSecurityManager)
-                     .createCodebasePrincipal(uri, attrs);
-  let pm = Cc["@mozilla.org/permissionmanager;1"]
-             .getService(Ci.nsIPermissionManager);
-  pm.addFromPrincipal(_principal, MOBILEID_PERM, aAction);
-}
-
-function removePermission() {
-  let uri = Cc["@mozilla.org/network/io-service;1"]
-              .getService(Ci.nsIIOService)
-              .newURI(ORIGIN, null, null);
-  let attrs = {appId: APP_ID};
-  let _principal = Cc["@mozilla.org/scriptsecuritymanager;1"]
-                     .getService(Ci.nsIScriptSecurityManager)
-                     .createCodebasePrincipal(uri, attrs);
-  let pm = Cc["@mozilla.org/permissionmanager;1"]
-             .getService(Ci.nsIPermissionManager);
-  pm.removeFromPrincipal(_principal, MOBILEID_PERM);
-}
-
-// === Mocks ===
-
-var Mock = function(aOptions) {
-  if (!aOptions) {
-    aOptions = {};
-  }
-  this._options = aOptions;
-  this._spied = {};
-};
-
-Mock.prototype = {
-  _: function(aMethod) {
-    DEBUG && do_print("_ " + aMethod + JSON.stringify(this._spied));
-    let self = this;
-    return {
-      callsLength: function(aNumberOfCalls) {
-        if (aNumberOfCalls == 0) {
-          do_check_eq(self._spied[aMethod], undefined);
-          return;
-        }
-        do_check_eq(self._spied[aMethod].length, aNumberOfCalls);
-      },
-      call: function(aCallNumber) {
-        return {
-          arg: function(aArgNumber, aValue) {
-            let _arg = self._spied[aMethod][aCallNumber - 1][aArgNumber - 1];
-            if (Array.isArray(aValue)) {
-              do_check_eq(_arg.length, aValue.length)
-              for (let i = 0; i < _arg.length; i++) {
-                do_check_eq(_arg[i], aValue[i]);
-              }
-              return;
-            }
-
-            if (typeof aValue === 'object') {
-              do_check_eq(JSON.stringify(_arg), JSON.stringify(aValue));
-              return;
-            }
-
-            do_check_eq(_arg, aValue);
-          }
-        }
-      }
-    }
-  },
-
-  _spy: function(aMethod, aArgs) {
-    DEBUG && do_print(aMethod + " - " + JSON.stringify(aArgs));
-    if (!this._spied[aMethod]) {
-      this._spied[aMethod] = [];
-    }
-    this._spied[aMethod].push(aArgs);
-  },
-
-  getSpiedCalls: function(aMethod) {
-    return this._spied[aMethod];
-  }
-};
-
-// UI Glue mock up.
-var MockUi = function(aOptions) {
-  Mock.call(this, aOptions);
-};
-
-MockUi.prototype = {
-  __proto__: Mock.prototype,
-
-  _startFlowResult: {
-    phoneNumber: PHONE_NUMBER,
-    mcc: MNC
-  },
-
-  _verifyCodePromptResult: {
-    verificationCode: VERIFICATION_CODE
-  },
-
-  startFlow: function() {
-    this._spy("startFlow", arguments);
-    return Promise.resolve(this._options.startFlowResult ||
-                           this._startFlowResult);
-  },
-
-  verificationCodePrompt: function() {
-    this._spy("verifyCodePrompt", arguments);
-    return Promise.resolve(this._options.verificationCodePromptResult ||
-                           this._verifyCodePromptResult);
-  },
-
-  verify: function() {
-    this._spy("verify", arguments);
-  },
-
-  error: function() {
-    this._spy("error", arguments);
-  },
-
-  verified: function() {
-    this._spy("verified", arguments);
-  },
-
-  set oncancel(aCallback) {
-  },
-
-  set onresendcode(aCallback) {
-  }
-};
-
-// Credentials store mock up.
-var MockCredStore = function(aOptions) {
-  Mock.call(this, aOptions);
-};
-
-MockCredStore.prototype = {
-  __proto__: Mock.prototype,
-
-  _getByOriginResult: null,
-
-  _getByMsisdnResult: null,
-
-  _getByIccIdResult: null,
-
-  getByOrigin: function() {
-    this._spy("getByOrigin", arguments);
-    let result = this._getByOriginResult;
-    if (this._options.getByOriginResult) {
-      if (Array.isArray(this._options.getByOriginResult)) {
-        result = this._options.getByOriginResult.length ?
-                 this._options.getByOriginResult.shift() : null;
-      } else {
-        result = this._options.getByOriginResult;
-      }
-    }
-    return Promise.resolve(result);
-  },
-
-  getByMsisdn: function() {
-    this._spy("getByMsisdn", arguments);
-    return Promise.resolve(this._options.getByMsisdnResult ||
-                           this._getByMsisdnResult);
-  },
-
-  getByIccId: function() {
-    this._spy("getByIccId", arguments);
-    return Promise.resolve(this._options.getByIccIdResult ||
-                           this._getByIccIdResult);
-  },
-
-  add: function() {
-    this._spy("add", arguments);
-    return Promise.resolve();
-  },
-
-  setDeviceIccIds: function() {
-    this._spy("setDeviceIccIds", arguments);
-    return Promise.resolve();
-  },
-
-  removeOrigin: function() {
-    this._spy("removeOrigin", arguments);
-    return Promise.resolve();
-  },
-
-  delete: function() {
-    this._spy("delete", arguments);
-    return Promise.resolve();
-  }
-};
-
-// Client mock up.
-var MockClient = function(aOptions) {
-  Mock.call(this, aOptions);
-};
-
-MockClient.prototype = {
-
-  __proto__: Mock.prototype,
-
-  _discoverResult: {
-    verificationMethods: ["sms/mt"],
-    verificationDetails: {
-      "sms/mt": {
-        mtSender: "123",
-        url: "https://msisdn.accounts.firefox.com/v1/msisdn/sms/mt/verify"
-      }
-    }
-  },
-
-  _registerResult: {
-    msisdnSessionToken: SESSION_TOKEN
-  },
-
-  _smsMtVerifyResult: {},
-
-  _verifyCodeResult: {
-    msisdn: PHONE_NUMBER
-  },
-
-  _signResult: {
-    cert: CERTIFICATE
-  },
-
-  hawk: {
-    now: function() {
-      return Date.now();
-    }
-  },
-
-  discover: function() {
-    this._spy("discover", arguments);
-    return Promise.resolve(this._options.discoverResult ||
-                           this._discoverResult);
-  },
-
-  register: function() {
-    this._spy("register", arguments);
-    return Promise.resolve(this._options.registerResult ||
-                           this._registerResult);
-  },
-
-  smsMtVerify: function() {
-    this._spy("smsMtVerify", arguments);
-    return Promise.resolve(this._options.smsMtVerifyResult ||
-                           this._smsMtVerifyResult);
-  },
-
-  verifyCode: function() {
-    this._spy("verifyCode", arguments);
-    if (this._options.verifyCodeError) {
-      let error = Array.isArray(this._options.verifyCodeError) ?
-                  this._options.verifyCodeError.shift() :
-                  this._options.verifyCodeError;
-      if (!this._options.verifyCodeError.length) {
-        this._options.verifyCodeError = null;
-      }
-      return Promise.reject(error);
-    }
-    return Promise.resolve(this._options.verifyCodeResult ||
-                           this._verifyCodeResult);
-  },
-
-  sign: function() {
-    this._spy("sign", arguments);
-    if (this._options.signError) {
-      let error = Array.isArray(this._options.signError) ?
-                  this._options.signError.shift() :
-                  this._options.signError;
-      return Promise.reject(error);
-    }
-    return Promise.resolve(this._options.signResult || this._signResult);
-  }
-};
-
-// Override MobileIdentityUIGlue.
-const kMobileIdentityUIGlueUUID = "{05df0566-ca8a-4ec7-bc76-78626ebfbe9a}";
-const kMobileIdentityUIGlueContractID =
-  "@mozilla.org/services/mobileid-ui-glue;1";
-
-// Save original factory.
-/*const kMobileIdentityUIGlueFactory =
-  Cm.getClassObject(Cc[kMobileIdentityUIGlueContractID], Ci.nsIFactory);*/
-
-var fakeMobileIdentityUIGlueFactory = {
-  createInstance: function(aOuter, aIid) {
-    return MobileIdentityUIGlue.QueryInterface(aIid);
-  }
-};
-
-// MobileIdentityUIGlue fake component.
-var MobileIdentityUIGlue = {
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsIMobileIdentityUIGlue]),
-
-};
-
-(function registerFakeMobileIdentityUIGlue() {
-  Cm.QueryInterface(Ci.nsIComponentRegistrar)
-    .registerFactory(Components.ID(kMobileIdentityUIGlueUUID),
-                     "MobileIdentityUIGlue",
-                     kMobileIdentityUIGlueContractID,
-                     fakeMobileIdentityUIGlueFactory);
-})();
-
-// The tests rely on having an app registered. Otherwise, it will throw.
-// Override XULAppInfo.
-Cu.import("resource://testing-common/AppInfo.jsm", this);
-updateAppInfo({
-  name: "MobileIdTest",
-  ID: "{230de50e-4cd1-11dc-8314-0800200b9a66}",
-  version: "1",
-  platformVersion: "",
-});
deleted file mode 100644
--- a/services/mobileid/tests/xpcshell/test_mobileid_client.js
+++ /dev/null
@@ -1,247 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-Cu.import("resource://services-common/utils.js");
-Cu.import("resource://testing-common/httpd.js");
-Cu.import("resource://gre/modules/MobileIdentityClient.jsm");
-
-/* Setup */
-
-var client;
-var server = new HttpServer();
-
-function httpd_setup(handlers, port = -1) {
-  for (let path in handlers) {
-    server.registerPathHandler(path, handlers[path]);
-  }
-
-  try {
-    server.start(port);
-  } catch (ex) {
-    dump("ERROR starting server on port " + port + ".  Already a process listening?");
-    do_throw(ex);
-  }
-
-  // Set the base URI for convenience.
-  let i = server.identity;
-  server.baseURI = i.primaryScheme + "://" + i.primaryHost + ":" + i.primaryPort;
-
-  return server;
-}
-
-function writeResp(response, msg) {
-  if (typeof msg === "object") {
-    msg = JSON.stringify(msg);
-  }
-  response.bodyOutputStream.write(msg, msg.length);
-}
-
-function getBody(request) {
-  let body = CommonUtils.readBytesFromInputStream(request.bodyInputStream);
-  return JSON.parse(body);
-}
-
-function run_test() {
-  httpd_setup({
-    "/discover": function(request, response) {
-      let body = getBody(request);
-      response.setStatusLine(null, 200, "Ok");
-      writeResp(response, {
-        msisdn: body.msisdn,
-        mcc: body.mcc,
-        mnc: body.mnc,
-        roaming: body.roaming
-      });
-    },
-    "/register": function(request, response) {
-      response.setStatusLine(null, 204);
-    },
-    "/sms/mt/verify": function(request, response) {
-      let body = getBody(request);
-      response.setStatusLine(null, 200, "Ok");
-      writeResp(response, {
-        msisdn: body.msisdn,
-        mcc: body.mcc,
-        mnc: body.mnc,
-        shortVerificationCode: body.shortVerificationCode
-      });
-    },
-    "/sms/verify_code": function(request, response) {
-      let body = getBody(request);
-      response.setStatusLine(null, 200, "Ok");
-      writeResp(response, {
-        code: body.code
-      });
-    },
-    "/certificate/sign": function(request, response) {
-      let body = getBody(request);
-      response.setStatusLine(null, 200, "Ok");
-      writeResp(response, {
-        duration: body.duration,
-        publicKey: body.publicKey
-      });
-    },
-    "/unregister": function(request, response) {
-      response.setStatusLine(null, 500);
-    }
-  });
-
-
-  client = new MobileIdentityClient(server.baseURI);
-
-  run_next_test();
-}
-
-/* Tests */
-
-add_test(function test_discover() {
-  do_print("= Test /discover =");
-
-  do_test_pending();
-
-  let msisdn = "msisdn";
-  let mcc = "mcc";
-  let mnc = "mnc";
-  let roaming = true;
-
-  client.discover(msisdn, mcc, mnc, roaming).then(
-    (response) => {
-      // The request should succeed and a response should be given.
-      // We simply check that the parameters given with the request are
-      // successfully progressed to the server.
-      do_check_eq(response.msisdn, msisdn);
-      do_check_eq(response.mcc, mcc);
-      do_check_eq(response.mnc, mnc);
-      do_check_eq(response.roaming, roaming);
-      do_test_finished();
-      run_next_test();
-    },
-    (error) => {
-      do_throw("Should not throw error when handling a 200 response");
-      do_test_finished();
-      run_next_test();
-    }
-  );
-});
-
-add_test(function test_sms_mt_verify() {
-  do_print("= Test /sms/mt/verify =");
-
-  do_test_pending();
-
-  let msisdn = "msisdn";
-  let mcc = "mcc";
-  let mnc = "mnc";
-  let shortCode = true;
-
-  client.smsMtVerify("aToken", msisdn, mcc, mnc, shortCode).then(
-    (response) => {
-      // The request should succeed and a response should be given.
-      // We simply check that the parameters given with the request are
-      // successfully progressed to the server.
-      do_check_eq(response.msisdn, msisdn);
-      do_check_eq(response.mcc, mcc);
-      do_check_eq(response.mnc, mnc);
-      do_check_eq(response.shortVerificationCode, shortCode);
-      do_test_finished();
-      run_next_test();
-    },
-    (error) => {
-      do_throw("Should not throw error when handling a 200 response");
-      do_test_finished();
-      run_next_test();
-    }
-  );
-});
-
-add_test(function test_verify_code() {
-  do_print("= Test /sms/verify_code =");
-
-  do_test_pending();
-
-  let code = "code";
-
-  client.verifyCode("aToken", code).then(
-    (response) => {
-      // The request should succeed and a response should be given.
-      // We simply check that the parameters given with the request are
-      // successfully progressed to the server.
-      do_check_eq(response.code, code);
-      do_test_finished();
-      run_next_test();
-    },
-    (error) => {
-      do_throw("Should not throw error when handling a 200 response");
-      do_test_finished();
-      run_next_test();
-    }
-  );
-});
-
-add_test(function test_certificate_sign() {
-  do_print("= Test /certificate/sign =");
-
-  do_test_pending();
-
-  let duration = "duration";
-  let publicKey = "publicKey";
-
-  client.sign("aToken", duration, publicKey).then(
-    (response) => {
-      // The request should succeed and a response should be given.
-      // We simply check that the parameters given with the request are
-      // successfully progressed to the server.
-      do_check_eq(response.duration, duration);
-      do_check_eq(response.publicKey, publicKey);
-      do_test_finished();
-      run_next_test();
-    },
-    (error) => {
-      do_throw("Should not throw error when handling a 200 response");
-      do_test_finished();
-      run_next_test();
-    }
-  );
-});
-
-add_test(function test_204_response() {
-  do_print("= Test /register and 204 No Content response =");
-
-  do_test_pending();
-
-  client.register().then(
-    (response) => {
-      // The request should succeed but no response body should be returned.
-      do_check_eq(response, undefined);
-      do_test_finished();
-      run_next_test();
-    },
-    (error) => {
-      do_throw("Should not throw error when handling a 204 response");
-      do_test_finished();
-      run_next_test();
-    }
-  );
-});
-
-add_test(function test_500_response() {
-  do_print("= Test /unregister and 500 response =");
-
-  do_test_pending();
-
-  client.unregister("aToken").then(
-    (response) => {
-      // The request shouldn't succeed.
-      do_throw("We are supposed to get an error");
-      do_test_finished();
-      run_next_test();
-    },
-    (error) => {
-      do_check_eq(error, "UNKNOWN");
-      do_test_finished();
-      run_next_test();
-    }
-  );
-});
deleted file mode 100644
--- a/services/mobileid/tests/xpcshell/test_mobileid_manager.js
+++ /dev/null
@@ -1,1227 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-Cu.import("resource://gre/modules/Promise.jsm");
-Cu.import("resource://gre/modules/MobileIdentityManager.jsm");
-Cu.import("resource://gre/modules/MobileIdentityCommon.jsm");
-
-// Save original credential store instance.
-const kMobileIdentityCredStore = MobileIdentityManager.credStore;
-// Save original client instance.
-const kMobileIdentityClient = MobileIdentityManager.client;
-
-// === Global cleanup ===
-function cleanup() {
-  MobileIdentityManager.credStore = kMobileIdentityCredStore;
-  MobileIdentityManager.client = kMobileIdentityClient;
-  MobileIdentityManager.ui = null;
-  MobileIdentityManager._iccInfo = [];
-  removePermission(ORIGIN);
-}
-
-// Unregister mocks and restore original code.
-do_register_cleanup(cleanup);
-// === Tests ===
-function run_test() {
-  run_next_test();
-}
-
-add_test(function() {
-  do_print("= Initial state =");
-  do_check_neq(MobileIdentityManager, undefined);
-  run_next_test();
-});
-
-add_test(function() {
-  do_print("= No credentials - No ICC - User MSISDN - External - OK result =");
-
-  do_register_cleanup(cleanup);
-
-  do_test_pending();
-
-  let ui = new MockUi();
-  MobileIdentityManager.ui = ui;
-  let credStore = new MockCredStore();
-  MobileIdentityManager.credStore = credStore;
-  let client = new MockClient();
-  MobileIdentityManager.client = client;
-  MobileIdentityManager._iccInfo = [];
-
-  let promiseId = Date.now();
-  let mm = {
-    sendAsyncMessage: function(aMsg, aData) {
-      do_print("sendAsyncMessage " + aMsg + " - " + JSON.stringify(aData));
-
-      // Check result.
-      do_check_eq(aMsg, GET_ASSERTION_RETURN_OK);
-      do_check_eq(typeof aData, "object");
-      do_check_eq(aData.promiseId, promiseId);
-
-      // Check spied calls.
-
-      // MockCredStore.
-      credStore._("getByOrigin").callsLength(1);
-      credStore._("getByOrigin").call(1).arg(1, ORIGIN);
-      credStore._("getByMsisdn").callsLength(1);
-      credStore._("getByMsisdn").call(1).arg(1, PHONE_NUMBER);
-      credStore._("add").callsLength(1);
-      credStore._("add").call(1).arg(1, undefined);
-      credStore._("add").call(1).arg(2, PHONE_NUMBER);
-      credStore._("add").call(1).arg(3, ORIGIN);
-      credStore._("add").call(1).arg(4, SESSION_TOKEN);
-      credStore._("add").call(1).arg(5, []);
-
-
-      // MockUI.
-      ui._("startFlow").callsLength(1);
-      ui._("startFlow").call(1).arg(1, "");
-      ui._("startFlow").call(1).arg(2, []);
-      ui._("verifyCodePrompt").callsLength(1);
-      ui._("verifyCodePrompt").call(1).arg(1, 3);
-      ui._("verify").callsLength(1);
-
-      // MockClient.
-      client._("discover").callsLength(1);
-      client._("discover").call(1).arg(1, PHONE_NUMBER);
-      client._("register").callsLength(1);
-      client._("smsMtVerify").callsLength(1);
-      client._("smsMtVerify").call(1).arg(1, SESSION_TOKEN);
-      client._("smsMtVerify").call(1).arg(2, PHONE_NUMBER);
-      client._("smsMtVerify").call(1).arg(3, MNC);
-      client._("smsMtVerify").call(1).arg(4, undefined);
-      client._("smsMtVerify").call(1).arg(5, true);
-      client._("verifyCode").callsLength(1);
-      client._("verifyCode").call(1).arg(1, SESSION_TOKEN);
-      client._("verifyCode").call(1).arg(2, {
-        verificationCode: VERIFICATION_CODE
-      });
-      client._("sign").callsLength(1);
-      client._("sign").call(1).arg(1, SESSION_TOKEN);
-      client._("sign").call(1).arg(2, CERTIFICATE_LIFETIME);
-
-      do_test_finished();
-      run_next_test();
-    }
-  };
-
-  addPermission(Ci.nsIPermissionManager.ALLOW_ACTION);
-
-  MobileIdentityManager.receiveMessage({
-    name: GET_ASSERTION_IPC_MSG,
-    principal: PRINCIPAL,
-    target: mm,
-    json: {
-      promiseId: promiseId
-    }
-  });
-});
-
-add_test(function() {
-  do_print("= No credentials - No icc - User MSISDN - External - KO -" +
-           " ERROR_INTERNAL_CANNOT_VERIFY_SELECTION =");
-
-  do_register_cleanup(cleanup);
-
-  do_test_pending();
-
-  let _sessionToken = Date.now();
-
-  let ui = new MockUi();
-  MobileIdentityManager.ui = ui;
-  let credStore = new MockCredStore();
-  MobileIdentityManager.credStore = credStore;
-  let client = new MockClient({
-    discoverResult: {
-      verificationMethods: ["other"],
-      verificationDetails: {
-        "other": {}
-      }
-    },
-    registerResult: {
-      msisdnSessionToken: _sessionToken
-    }
-  });
-  MobileIdentityManager.client = client;
-
-  let promiseId = Date.now();
-  let mm = {
-    sendAsyncMessage: function(aMsg, aData) {
-      do_print("sendAsyncMessage " + aMsg + " - " + JSON.stringify(aData));
-
-      // Check result.
-      do_check_eq(aMsg, GET_ASSERTION_RETURN_KO);
-      do_check_eq(typeof aData, "object");
-      do_check_eq(aData.promiseId, promiseId);
-      do_check_eq(aData.error, ERROR_INTERNAL_CANNOT_VERIFY_SELECTION);
-
-      // Check spied calls.
-
-      // MockCredStore.
-      credStore._("getByOrigin").callsLength(1);
-      credStore._("getByOrigin").call(1).arg(1, ORIGIN);
-      credStore._("getByMsisdn").callsLength(1);
-      credStore._("getByMsisdn").call(1).arg(1, PHONE_NUMBER);
-      credStore._("add").callsLength(0);
-
-      // MockUI.
-      ui._("startFlow").callsLength(1);
-      ui._("startFlow").call(1).arg(1, "");
-      ui._("startFlow").call(1).arg(2, []);
-      ui._("verifyCodePrompt").callsLength(0);
-      ui._("verify").callsLength(0);
-      ui._("error").callsLength(1);
-      ui._("error").call(1).arg(1, ERROR_INTERNAL_CANNOT_VERIFY_SELECTION);
-
-      // MockClient.
-      client._("discover").callsLength(1);
-      client._("discover").call(1).arg(1, PHONE_NUMBER);
-      client._("register").callsLength(0);
-      client._("smsMtVerify").callsLength(0);
-      client._("verifyCode").callsLength(0);
-      client._("sign").callsLength(0);
-
-      do_test_finished();
-      run_next_test();
-    }
-  };
-
-  MobileIdentityManager.receiveMessage({
-    name: GET_ASSERTION_IPC_MSG,
-    principal: PRINCIPAL,
-    target: mm,
-    json: {
-      promiseId: promiseId
-    }
-  });
-});
-
-add_test(function() {
-  do_print("= No credentials - No icc - User MSISDN - External - KO -" +
-           " INTERNAL_INVALID_PROMPT_RESULT =");
-
-  do_register_cleanup(cleanup);
-
-  do_test_pending();
-
-  let _sessionToken = Date.now();
-
-  let ui = new MockUi({
-    startFlowResult: {}
-  });
-  MobileIdentityManager.ui = ui;
-  let credStore = new MockCredStore();
-  MobileIdentityManager.credStore = credStore;
-  let client = new MockClient();
-  MobileIdentityManager.client = client;
-
-  let promiseId = Date.now();
-  let mm = {
-    sendAsyncMessage: function(aMsg, aData) {
-      do_print("sendAsyncMessage " + aMsg + " - " + JSON.stringify(aData));
-
-      // Check result.
-      do_check_eq(aMsg, GET_ASSERTION_RETURN_KO);
-      do_check_eq(typeof aData, "object");
-      do_check_eq(aData.promiseId, promiseId);
-      do_check_eq(aData.error, ERROR_INTERNAL_INVALID_PROMPT_RESULT);
-
-      // Check spied calls.
-
-      // MockCredStore.
-      credStore._("getByOrigin").callsLength(1);
-      credStore._("getByOrigin").call(1).arg(1, ORIGIN);
-      credStore._("getByMsisdn").callsLength(0);
-      credStore._("add").callsLength(0);
-
-      // MockUI.
-      ui._("startFlow").callsLength(1);
-      ui._("startFlow").call(1).arg(1, "");
-      ui._("startFlow").call(1).arg(2, []);
-      ui._("verifyCodePrompt").callsLength(0);
-      ui._("verify").callsLength(0);
-      ui._("error").callsLength(1);
-      ui._("error").call(1).arg(1, ERROR_INTERNAL_INVALID_PROMPT_RESULT);
-
-      // MockClient.
-      client._("discover").callsLength(0);
-      client._("register").callsLength(0);
-      client._("smsMtVerify").callsLength(0);
-      client._("verifyCode").callsLength(0);
-      client._("sign").callsLength(0);
-
-      do_test_finished();
-      run_next_test();
-    }
-  };
-
-  MobileIdentityManager.receiveMessage({
-    name: GET_ASSERTION_IPC_MSG,
-    principal: PRINCIPAL,
-    target: mm,
-    json: {
-      promiseId: promiseId
-    }
-  });
-});
-
-add_test(function() {
-  do_print("= No credentials - No icc - User MSISDN - External - KO -" +
-           " ERROR_INVALID_ASSERTION =");
-
-  do_register_cleanup(cleanup);
-
-  do_test_pending();
-
-  let _sessionToken = Date.now();
-
-  let ui = new MockUi();
-  MobileIdentityManager.ui = ui;
-  let credStore = new MockCredStore();
-  MobileIdentityManager.credStore = credStore;
-  let client = new MockClient({
-    signResult: {
-      cert: "aInvalidCert"
-    },
-    registerResult: {
-      msisdnSessionToken: _sessionToken
-    }
-  });
-  MobileIdentityManager.client = client;
-
-  let promiseId = Date.now();
-  let mm = {
-    sendAsyncMessage: function(aMsg, aData) {
-      do_print("sendAsyncMessage " + aMsg + " - " + JSON.stringify(aData));
-
-      // Check result.
-      do_check_eq(aMsg, GET_ASSERTION_RETURN_KO);
-      do_check_eq(typeof aData, "object");
-      do_check_eq(aData.promiseId, promiseId);
-      do_check_eq(aData.error, ERROR_INVALID_ASSERTION);
-
-      // Check spied calls.
-
-      // MockCredStore.
-      credStore._("getByOrigin").callsLength(1);
-      credStore._("getByOrigin").call(1).arg(1, ORIGIN);
-      credStore._("getByMsisdn").callsLength(1);
-      credStore._("getByMsisdn").call(1).arg(1, PHONE_NUMBER);
-      credStore._("add").callsLength(1);
-
-      // MockUI.
-      ui._("startFlow").callsLength(1);
-      ui._("startFlow").call(1).arg(1, "");
-      ui._("startFlow").call(1).arg(2, []);
-      ui._("verifyCodePrompt").callsLength(1);
-      ui._("verifyCodePrompt").call(1).arg(1, 3);
-      ui._("verify").callsLength(1);
-      ui._("error").callsLength(1);
-      ui._("error").call(1).arg(1, ERROR_INVALID_ASSERTION);
-
-      // MockClient.
-      client._("discover").callsLength(1);
-      client._("discover").call(1).arg(1, PHONE_NUMBER);
-      client._("register").callsLength(1);
-      client._("smsMtVerify").callsLength(1);
-      client._("smsMtVerify").call(1).arg(1, _sessionToken);
-      client._("smsMtVerify").call(1).arg(2, PHONE_NUMBER);
-      client._("smsMtVerify").call(1).arg(3, MNC);
-      client._("smsMtVerify").call(1).arg(4, undefined);
-      client._("smsMtVerify").call(1).arg(5, true);
-      client._("verifyCode").callsLength(1);
-      client._("verifyCode").call(1).arg(1, _sessionToken);
-      client._("verifyCode").call(1).arg(2, {
-        verificationCode: VERIFICATION_CODE
-      });
-      client._("sign").callsLength(1);
-      client._("sign").call(1).arg(1, _sessionToken);
-      client._("sign").call(1).arg(2, CERTIFICATE_LIFETIME);
-
-      do_test_finished();
-      run_next_test();
-    }
-  };
-
-  MobileIdentityManager.receiveMessage({
-    name: GET_ASSERTION_IPC_MSG,
-    principal: PRINCIPAL,
-    target: mm,
-    json: {
-      promiseId: promiseId
-    }
-  });
-});
-
-add_test(function() {
-  do_print("= Existing credentials - No Icc - Permission - OK result =");
-
-  do_register_cleanup(cleanup);
-
-  do_test_pending();
-
-  let ui = new MockUi();
-  MobileIdentityManager.ui = ui;
-  let credStore = new MockCredStore({
-    getByOriginResult: {
-      sessionToken: SESSION_TOKEN,
-      msisdn: PHONE_NUMBER,
-      origin: ORIGIN,
-      deviceIccIds: null
-    }
-  });
-  MobileIdentityManager.credStore = credStore;
-  let client = new MockClient();
-  MobileIdentityManager.client = client;
-
-  let promiseId = Date.now();
-  let mm = {
-    sendAsyncMessage: function(aMsg, aData) {
-      do_print("sendAsyncMessage " + aMsg + " - " + JSON.stringify(aData));
-
-      // Check result.
-      do_check_eq(aMsg, GET_ASSERTION_RETURN_OK);
-      do_check_eq(typeof aData, "object");
-      do_check_eq(aData.promiseId, promiseId);
-
-      // Check spied calls.
-
-      // MockCredStore.
-      credStore._("getByOrigin").callsLength(1);
-      credStore._("getByOrigin").call(1).arg(1, ORIGIN);
-
-      removePermission(ORIGIN);
-
-      do_test_finished();
-      run_next_test();
-    }
-  };
-
-  addPermission(Ci.nsIPermissionManager.ALLOW_ACTION);
-
-  MobileIdentityManager.receiveMessage({
-    name: GET_ASSERTION_IPC_MSG,
-    principal: PRINCIPAL,
-    target: mm,
-    json: {
-      promiseId: promiseId,
-      options: {}
-    }
-  });
-});
-
-add_test(function() {
-  do_print("= Existing credentials - No Icc - Prompt permission - OK result =");
-
-  do_register_cleanup(cleanup);
-
-  do_test_pending();
-
-  let ui = new MockUi();
-  MobileIdentityManager.ui = ui;
-  let credStore = new MockCredStore({
-    getByOriginResult: {
-      sessionToken: SESSION_TOKEN,
-      msisdn: PHONE_NUMBER,
-      origin: ORIGIN,
-      deviceIccIds: null
-    }
-  });
-  MobileIdentityManager.credStore = credStore;
-  let client = new MockClient();
-  MobileIdentityManager.client = client;
-
-  let promiseId = Date.now();
-  let mm = {
-    sendAsyncMessage: function(aMsg, aData) {
-      do_print("sendAsyncMessage " + aMsg + " - " + JSON.stringify(aData));
-
-      // Check result.
-      do_check_eq(aMsg, GET_ASSERTION_RETURN_OK);
-      do_check_eq(typeof aData, "object");
-      do_check_eq(aData.promiseId, promiseId);
-
-      // Check spied calls.
-
-      // MockCredStore.
-      credStore._("getByOrigin").callsLength(1);
-      credStore._("getByOrigin").call(1).arg(1, ORIGIN);
-
-      // MockUI.
-      ui._("startFlow").callsLength(1);
-
-      removePermission(ORIGIN);
-
-      do_test_finished();
-      run_next_test();
-    }
-  };
-
-  addPermission(Ci.nsIPermissionManager.PROMPT_ACTION);
-
-  MobileIdentityManager.receiveMessage({
-    name: GET_ASSERTION_IPC_MSG,
-    principal: PRINCIPAL,
-    target: mm,
-    json: {
-      promiseId: promiseId,
-      options: {}
-    }
-  });
-});
-
-add_test(function() {
-  do_print("= Existing credentials - No Icc - Permission denied - KO result =");
-
-  do_register_cleanup(cleanup);
-
-  do_test_pending();
-
-  let ui = new MockUi();
-  MobileIdentityManager.ui = ui;
-  let credStore = new MockCredStore({
-    getByOriginResult: {
-      sessionToken: SESSION_TOKEN,
-      msisdn: PHONE_NUMBER,
-      origin: ORIGIN,
-      deviceIccIds: null
-    }
-  });
-  MobileIdentityManager.credStore = credStore;
-  let client = new MockClient();
-  MobileIdentityManager.client = client;
-
-  let promiseId = Date.now();
-  let mm = {
-    sendAsyncMessage: function(aMsg, aData) {
-      do_print("sendAsyncMessage " + aMsg + " - " + JSON.stringify(aData));
-
-      // Check result.
-      do_check_eq(aMsg, GET_ASSERTION_RETURN_KO);
-      do_check_eq(typeof aData, "object");
-      do_check_eq(aData.promiseId, promiseId);
-      do_check_eq(aData.error, ERROR_PERMISSION_DENIED);
-
-      // Check spied calls.
-
-      // MockCredStore.
-      credStore._("getByOrigin").callsLength(0);
-
-      // MockUI.
-      ui._("startFlow").callsLength(0);
-      ui._("error").callsLength(0);
-
-      do_test_finished();
-      run_next_test();
-    }
-  };
-
-  removePermission(ORIGIN);
-
-  MobileIdentityManager.receiveMessage({
-    name: GET_ASSERTION_IPC_MSG,
-    principal: PRINCIPAL,
-    target: mm,
-    json: {
-      promiseId: promiseId,
-      options: {}
-    }
-  });
-});
-
-add_test(function() {
-  do_print("= Existing credentials - No Icc - SIM change/Same choice - " +
-           "OK result =");
-
-  do_register_cleanup(cleanup);
-
-  do_test_pending();
-
-  let ui = new MockUi();
-  MobileIdentityManager.ui = ui;
-  let credStore = new MockCredStore({
-    getByOriginResult: {
-      sessionToken: SESSION_TOKEN,
-      msisdn: PHONE_NUMBER,
-      origin: ORIGIN,
-      deviceIccIds: [ICC_ID]
-    }
-  });
-  MobileIdentityManager.credStore = credStore;
-  let client = new MockClient();
-  MobileIdentityManager.client = client;
-
-  MobileIdentityManager._iccInfo = [];
-
-  let promiseId = Date.now();
-  let mm = {
-    sendAsyncMessage: function(aMsg, aData) {
-      do_print("sendAsyncMessage " + aMsg + " - " + JSON.stringify(aData));
-
-      // Check result.
-      do_check_eq(aMsg, GET_ASSERTION_RETURN_OK);
-      do_check_eq(typeof aData, "object");
-      do_check_eq(aData.promiseId, promiseId);
-
-      // Check spied calls.
-
-      // MockCredStore.
-      credStore._("getByOrigin").callsLength(1);
-      credStore._("getByOrigin").call(1).arg(1, ORIGIN);
-      credStore._("add").callsLength(1);
-      credStore._("add").call(1).arg(1, undefined);
-      credStore._("add").call(1).arg(2, PHONE_NUMBER);
-      credStore._("add").call(1).arg(3, ORIGIN);
-      credStore._("add").call(1).arg(4, SESSION_TOKEN);
-      credStore._("add").call(1).arg(5, []);
-      credStore._("setDeviceIccIds").callsLength(1);
-      credStore._("setDeviceIccIds").call(1).arg(1, PHONE_NUMBER);
-      credStore._("setDeviceIccIds").call(1).arg(2, []);
-
-      // MockUI.
-      ui._("startFlow").callsLength(1);
-      ui._("verifyCodePrompt").callsLength(0);
-      ui._("verify").callsLength(0);
-
-      // MockClient.
-      client._("discover").callsLength(0);
-      client._("register").callsLength(0);
-      client._("smsMtVerify").callsLength(0);
-      client._("verifyCode").callsLength(0);
-      client._("sign").callsLength(0);
-
-      do_test_finished();
-      run_next_test();
-    }
-  };
-
-  addPermission(Ci.nsIPermissionManager.ALLOW_ACTION);
-
-  MobileIdentityManager.receiveMessage({
-    name: GET_ASSERTION_IPC_MSG,
-    principal: PRINCIPAL,
-    target: mm,
-    json: {
-      promiseId: promiseId,
-      options: {}
-    }
-  });
-});
-
-add_test(function() {
-  do_print("= Existing credentials - No Icc - SIM change/Different choice - " +
-           "OK result =");
-
-  do_register_cleanup(cleanup);
-
-  do_test_pending();
-
-  let _sessionToken = Date.now();
-
-  let existingCredentials = {
-    sessionToken: SESSION_TOKEN,
-    msisdn: PHONE_NUMBER,
-    origin: ORIGIN,
-    deviceIccIds: [ICC_ID]
-  };
-
-  let ui = new MockUi({
-    startFlowResult: {
-      phoneNumber: ANOTHER_PHONE_NUMBER
-    }
-  });
-  MobileIdentityManager.ui = ui;
-  let credStore = new MockCredStore({
-    getByOriginResult: existingCredentials
-  });
-  MobileIdentityManager.credStore = credStore;
-  let client = new MockClient({
-    verifyCodeResult: ANOTHER_PHONE_NUMBER,
-    registerResult: {
-      msisdnSessionToken: _sessionToken
-    }
-  });
-  MobileIdentityManager.client = client;
-
-  MobileIdentityManager._iccInfo = [];
-
-  let promiseId = Date.now();
-  let mm = {
-    sendAsyncMessage: function(aMsg, aData) {
-      do_print("sendAsyncMessage " + aMsg + " - " + JSON.stringify(aData));
-
-      // Check result.
-      do_check_eq(aMsg, GET_ASSERTION_RETURN_OK);
-      do_check_eq(typeof aData, "object");
-      do_check_eq(aData.promiseId, promiseId);
-
-      // Check spied calls.
-
-      // MockCredStore.
-      credStore._("getByOrigin").callsLength(1);
-      credStore._("getByOrigin").call(1).arg(1, ORIGIN);
-      credStore._("getByMsisdn").callsLength(1);
-      credStore._("getByMsisdn").call(1).arg(1, ANOTHER_PHONE_NUMBER);
-      credStore._("add").callsLength(1);
-      credStore._("add").call(1).arg(1, undefined);
-      credStore._("add").call(1).arg(2, ANOTHER_PHONE_NUMBER);
-      credStore._("add").call(1).arg(3, ORIGIN);
-      credStore._("add").call(1).arg(4, _sessionToken);
-      credStore._("add").call(1).arg(5, []);
-      credStore._("setDeviceIccIds").callsLength(0);
-      credStore._("removeOrigin").callsLength(1);
-      credStore._("removeOrigin").call(1).arg(1, PHONE_NUMBER);
-      credStore._("removeOrigin").call(1).arg(2, ORIGIN);
-
-      // MockUI.
-      ui._("startFlow").callsLength(1);
-      ui._("verifyCodePrompt").callsLength(1);
-      ui._("verify").callsLength(1);
-
-      // MockClient.
-      client._("discover").callsLength(1);
-      client._("register").callsLength(1);
-      client._("smsMtVerify").callsLength(1);
-      client._("verifyCode").callsLength(1);
-      client._("sign").callsLength(1);
-
-      do_test_finished();
-      run_next_test();
-    }
-  };
-
-  MobileIdentityManager.receiveMessage({
-    name: GET_ASSERTION_IPC_MSG,
-    principal: PRINCIPAL,
-    target: mm,
-    json: {
-      promiseId: promiseId,
-      options: {}
-    }
-  });
-});
-
-add_test(function() {
-  do_print("= Existing credentials - No Icc - forceSelection/same - " +
-           "OK result =");
-
-  do_register_cleanup(cleanup);
-
-  do_test_pending();
-
-  let _sessionToken = Date.now();
-
-  let existingCredentials = {
-    sessionToken: _sessionToken,
-    msisdn: PHONE_NUMBER,
-    origin: ORIGIN,
-    deviceIccIds: []
-  };
-
-  let ui = new MockUi({
-    startFlowResult: {
-      phoneNumber: PHONE_NUMBER
-    }
-  });
-  MobileIdentityManager.ui = ui;
-  let credStore = new MockCredStore({
-    getByOriginResult: existingCredentials
-  });
-  MobileIdentityManager.credStore = credStore;
-  let client = new MockClient();
-  MobileIdentityManager.client = client;
-
-  let promiseId = Date.now();
-  let mm = {
-    sendAsyncMessage: function(aMsg, aData) {
-      do_print("sendAsyncMessage " + aMsg + " - " + JSON.stringify(aData));
-
-      // Check result.
-      do_check_eq(aMsg, GET_ASSERTION_RETURN_OK);
-      do_check_eq(typeof aData, "object");
-      do_check_eq(aData.promiseId, promiseId);
-
-      // Check spied calls.
-
-      // MockCredStore.
-      credStore._("getByOrigin").callsLength(1);
-      credStore._("getByOrigin").call(1).arg(1, ORIGIN);
-      credStore._("getByMsisdn").callsLength(0);
-      credStore._("add").callsLength(1);
-      credStore._("add").call(1).arg(1, undefined);
-      credStore._("add").call(1).arg(2, PHONE_NUMBER);
-      credStore._("add").call(1).arg(3, ORIGIN);
-      credStore._("add").call(1).arg(4, _sessionToken);
-      credStore._("add").call(1).arg(5, []);
-      credStore._("setDeviceIccIds").callsLength(1);
-      credStore._("removeOrigin").callsLength(0);
-
-      // MockUI.
-      ui._("startFlow").callsLength(1);
-      ui._("verifyCodePrompt").callsLength(0);
-      ui._("verify").callsLength(0);
-
-      // MockClient.
-      client._("discover").callsLength(0);
-      client._("register").callsLength(0);
-      client._("smsMtVerify").callsLength(0);
-      client._("verifyCode").callsLength(0);
-      client._("sign").callsLength(1);
-
-      do_test_finished();
-      run_next_test();
-    }
-  };
-
-  MobileIdentityManager.receiveMessage({
-    name: GET_ASSERTION_IPC_MSG,
-    principal: PRINCIPAL,
-    target: mm,
-    json: {
-      promiseId: promiseId,
-      options: {
-        forceSelection: true
-      }
-    }
-  });
-});
-add_test(function() {
-  do_print("= Existing credentials - No Icc - forceSelection/different - " +
-           "OK result =");
-
-  do_register_cleanup(cleanup);
-
-  do_test_pending();
-
-  let _sessionToken = Date.now();
-
-  let existingCredentials = {
-    sessionToken: SESSION_TOKEN,
-    msisdn: PHONE_NUMBER,
-    origin: ORIGIN,
-    deviceIccIds: []
-  };
-
-  let ui = new MockUi({
-    startFlowResult: {
-      phoneNumber: ANOTHER_PHONE_NUMBER
-    }
-  });
-  MobileIdentityManager.ui = ui;
-  let credStore = new MockCredStore({
-    getByOriginResult: existingCredentials
-  });
-  MobileIdentityManager.credStore = credStore;
-  let client = new MockClient({
-    verifyCodeResult: ANOTHER_PHONE_NUMBER,
-    registerResult: {
-      msisdnSessionToken: _sessionToken
-    }
-  });
-  MobileIdentityManager.client = client;
-
-  let promiseId = Date.now();
-  let mm = {
-    sendAsyncMessage: function(aMsg, aData) {
-      do_print("sendAsyncMessage " + aMsg + " - " + JSON.stringify(aData));
-
-      // Check result.
-      do_check_eq(aMsg, GET_ASSERTION_RETURN_OK);
-      do_check_eq(typeof aData, "object");
-      do_check_eq(aData.promiseId, promiseId);
-
-      // Check spied calls.
-
-      // MockCredStore.
-      credStore._("getByOrigin").callsLength(1);
-      credStore._("getByOrigin").call(1).arg(1, ORIGIN);
-      credStore._("getByMsisdn").callsLength(1);
-      credStore._("getByMsisdn").call(1).arg(1, ANOTHER_PHONE_NUMBER);
-      credStore._("add").callsLength(1);
-      credStore._("add").call(1).arg(1, undefined);
-      credStore._("add").call(1).arg(2, ANOTHER_PHONE_NUMBER);
-      credStore._("add").call(1).arg(3, ORIGIN);
-      credStore._("add").call(1).arg(4, _sessionToken);
-      credStore._("add").call(1).arg(5, []);
-      credStore._("setDeviceIccIds").callsLength(0);
-      credStore._("removeOrigin").callsLength(1);
-      credStore._("removeOrigin").call(1).arg(1, PHONE_NUMBER);
-      credStore._("removeOrigin").call(1).arg(2, ORIGIN);
-
-      // MockUI.
-      ui._("startFlow").callsLength(1);
-      ui._("verifyCodePrompt").callsLength(1);
-      ui._("verify").callsLength(1);
-
-      // MockClient.
-      client._("discover").callsLength(1);
-      client._("register").callsLength(1);
-      client._("smsMtVerify").callsLength(1);
-      client._("verifyCode").callsLength(1);
-      client._("sign").callsLength(1);
-
-      do_test_finished();
-      run_next_test();
-    }
-  };
-
-  MobileIdentityManager.receiveMessage({
-    name: GET_ASSERTION_IPC_MSG,
-    principal: PRINCIPAL,
-    target: mm,
-    json: {
-      promiseId: promiseId,
-      options: {
-        forceSelection: true
-      }
-    }
-  });
-});
-
-add_test(function() {
-  do_print("= Existing credentials - No Icc - INVALID_AUTH_TOKEN - OK =");
-
-  do_register_cleanup(cleanup);
-
-  do_test_pending();
-
-  let _sessionToken = Date.now();
-
-  let existingCredentials = {
-    sessionToken: _sessionToken,
-    msisdn: PHONE_NUMBER,
-    origin: ORIGIN,
-    deviceIccIds: []
-  };
-
-  let ui = new MockUi({
-    startFlowResult: {
-      phoneNumber: PHONE_NUMBER
-    }
-  });
-  MobileIdentityManager.ui = ui;
-  let credStore = new MockCredStore({
-    getByOriginResult: [existingCredentials, null]
-  });
-  MobileIdentityManager.credStore = credStore;
-  let client = new MockClient({
-    signError: [ERROR_INVALID_AUTH_TOKEN],
-    verifyCodeResult: PHONE_NUMBER,
-    registerResult: {
-      msisdnSessionToken: SESSION_TOKEN
-    }
-  });
-  MobileIdentityManager.client = client;
-
-  let promiseId = Date.now();
-  let mm = {
-    sendAsyncMessage: function(aMsg, aData) {
-      do_print("sendAsyncMessage " + aMsg + " - " + JSON.stringify(aData));
-
-      // Check result.
-      do_check_eq(aMsg, GET_ASSERTION_RETURN_OK);
-      do_check_eq(typeof aData, "object");
-      do_check_eq(aData.promiseId, promiseId);
-
-      // Check spied calls.
-
-      // MockCredStore.
-      credStore._("getByOrigin").callsLength(2);
-      credStore._("getByOrigin").call(1).arg(1, ORIGIN);
-      credStore._("getByOrigin").call(2).arg(1, ORIGIN);
-      credStore._("getByMsisdn").callsLength(1);
-      credStore._("getByMsisdn").call(1).arg(1, PHONE_NUMBER);
-      credStore._("add").callsLength(1);
-      credStore._("add").call(1).arg(1, undefined);
-      credStore._("add").call(1).arg(2, PHONE_NUMBER);
-      credStore._("add").call(1).arg(3, ORIGIN);
-      credStore._("add").call(1).arg(4, SESSION_TOKEN);
-      credStore._("add").call(1).arg(5, []);
-      credStore._("setDeviceIccIds").callsLength(0);
-      credStore._("delete").callsLength(1);
-      credStore._("delete").call(1).arg(1, PHONE_NUMBER);
-
-      // MockUI.
-      ui._("startFlow").callsLength(1);
-      ui._("verifyCodePrompt").callsLength(1);
-      ui._("verify").callsLength(1);
-
-      // MockClient.
-      client._("discover").callsLength(1);
-      client._("register").callsLength(1);
-      client._("smsMtVerify").callsLength(1);
-      client._("verifyCode").callsLength(1);
-      client._("sign").callsLength(1);
-
-      do_test_finished();
-      run_next_test();
-    }
-  };
-
-  addPermission(Ci.nsIPermissionManager.ALLOW_ACTION);
-
-  MobileIdentityManager.receiveMessage({
-    name: GET_ASSERTION_IPC_MSG,
-    principal: PRINCIPAL,
-    target: mm,
-    json: {
-      promiseId: promiseId,
-      options: {}
-    }
-  });
-});
-
-add_test(function() {
-  do_print("= ICC info change =");
-
-  do_register_cleanup(cleanup);
-
-  do_test_pending();
-
-  let _sessionToken = Date.now();
-
-  MobileIdentityManager._iccInfo = null;
-  MobileIdentityManager._iccIds = null;
-
-  MobileIdentityManager._ril = {
-    _interfaces: [RADIO_INTERFACE, ANOTHER_RADIO_INTERFACE],
-    get numRadioInterfaces() {
-      return this._interfaces.length;
-    },
-
-    getRadioInterface: function(aIndex) {
-      return this._interfaces[aIndex];
-    }
-  };
-
-  MobileIdentityManager._mobileConnectionService = {
-    _interfaces: [RADIO_INTERFACE, ANOTHER_RADIO_INTERFACE],
-    getItemByServiceId: function(aIndex) {
-      return this._interfaces[aIndex];
-    }
-  };
-
-  MobileIdentityManager._iccService = {
-    _listeners: [],
-    _iccInfos: [ICC_INFO, ANOTHER_ICC_INFO],
-    getIccByServiceId: function(aClientId) {
-      let self = this;
-      return {
-        get iccInfo() {
-          return self._iccInfos[aClientId];
-        },
-        registerListener: function(aIccListener) {
-          self._listeners.push(aIccListener);
-        },
-        unregisterListener: function() {
-          self._listeners.pop();
-        }
-      };
-    }
-  };
-
-  let ui = new MockUi();
-  ui.startFlow = function() {
-    // At this point we've already built the ICC cache.
-    let mockIccInfo = [ICC_INFO, ANOTHER_ICC_INFO];
-    for (let i = 0; i < mockIccInfo.length; i++) {
-      let mIdIccInfo = MobileIdentityManager._iccInfo[i];
-      do_check_eq(mockIccInfo[i].iccid, mIdIccInfo.iccId);
-      do_check_eq(mockIccInfo[i].mcc, mIdIccInfo.mcc);
-      do_check_eq(mockIccInfo[i].mnc, mIdIccInfo.mnc);
-      do_check_eq(mockIccInfo[i].msisdn, mIdIccInfo.msisdn);
-      do_check_eq(mockIccInfo[i].operator, mIdIccInfo.operator);
-    }
-
-    // We should have listeners for each valid icc.
-    do_check_eq(MobileIdentityManager._iccService._listeners.length, 2);
-
-    // We can mock an ICC change event at this point.
-    MobileIdentityManager._iccService._listeners[0].notifyIccInfoChanged();
-
-    // After the ICC change event the caches should be null.
-    do_check_null(MobileIdentityManager._iccInfo);
-    do_check_null(MobileIdentityManager._iccIds);
-
-    // And we should have unregistered all listeners for ICC change events.
-    do_check_eq(MobileIdentityManager._iccService._listeners.length, 0);
-
-    do_test_finished();
-    run_next_test();
-  };
-  MobileIdentityManager.ui = ui;
-
-  let credStore = new MockCredStore();
-  credStore.getByOrigin = function() {
-    // Initially the ICC caches should be null.
-    do_check_null(MobileIdentityManager._iccInfo);
-    do_check_null(MobileIdentityManager._iccIds);
-    return Promise.resolve(null);
-  };
-  MobileIdentityManager.credStore = credStore;
-
-  let client = new MockClient();
-  MobileIdentityManager.client = client;
-
-  let promiseId = Date.now();
-  let mm = {
-    sendAsyncMessage: function() {}
-  };
-
-  addPermission(Ci.nsIPermissionManager.ALLOW_ACTION);
-
-  MobileIdentityManager.receiveMessage({
-    name: GET_ASSERTION_IPC_MSG,
-    principal: PRINCIPAL,
-    target: mm,
-    json: {
-      promiseId: promiseId,
-      options: {}
-    }
-  });
-});
-
-add_test(function() {
-  do_print("= Invalid ICC Info =");
-
-  do_register_cleanup(cleanup);
-
-  do_test_pending();
-
-  let _sessionToken = Date.now();
-
-  MobileIdentityManager._iccInfo = null;
-  MobileIdentityManager._iccIds = null;
-
-  MobileIdentityManager._ril = {
-    _interfaces: [INVALID_RADIO_INTERFACE],
-    get numRadioInterfaces() {
-      return this._interfaces.length;
-    },
-
-    getRadioInterface: function(aIndex) {
-      return this._interfaces[aIndex];
-    }
-  };
-
-  MobileIdentityManager._mobileConnectionService = {
-    _interfaces: [INVALID_RADIO_INTERFACE],
-    getItemByServiceId: function(aIndex) {
-      return this._interfaces[aIndex];
-    }
-  };
-
-  MobileIdentityManager._iccService = {
-    _listeners: [],
-    _iccInfos: [INVALID_ICC_INFO],
-    getIccByServiceId: function(aClientId) {
-      let self = this;
-      return {
-        get iccInfo() {
-          return self._iccInfos[aClientId];
-        },
-        registerListener: function(aIccListener) {
-          self._listeners.push(aIccListener);
-        },
-        unregisterListener: function() {
-          self._listeners.pop();
-        }
-      };
-    }
-  };
-
-  let ui = new MockUi();
-  ui.startFlow = function() {
-    // At this point we've already built the ICC cache.
-    do_check_eq(MobileIdentityManager._iccInfo.length, 0);
-    do_check_eq(MobileIdentityManager._iccIds.length, 0);
-
-    // We should have listeners for each valid icc.
-    do_check_eq(MobileIdentityManager._iccService._listeners.length, 0);
-
-    do_test_finished();
-    run_next_test();
-  };
-  MobileIdentityManager.ui = ui;
-
-  let credStore = new MockCredStore();
-  credStore.getByOrigin = function() {
-    // Initially the ICC caches should be null.
-    do_check_null(MobileIdentityManager._iccInfo);
-    do_check_null(MobileIdentityManager._iccIds);
-    return Promise.resolve(null);
-  };
-  MobileIdentityManager.credStore = credStore;
-
-  let client = new MockClient();
-  MobileIdentityManager.client = client;
-
-  let promiseId = Date.now();
-  let mm = {
-    sendAsyncMessage: function() {}
-  };
-
-  addPermission(Ci.nsIPermissionManager.ALLOW_ACTION);
-
-  MobileIdentityManager.receiveMessage({
-    name: GET_ASSERTION_IPC_MSG,
-    principal: PRINCIPAL,
-    target: mm,
-    json: {
-      promiseId: promiseId,
-      options: {}
-    }
-  });
-});
-
-add_test(function() {
-  do_print("= Cancel verification flow =");
-
-  do_register_cleanup(cleanup);
-
-  do_test_pending();
-
-  let _sessionToken = Date.now();
-
-  let ui = new MockUi();
-  ui.verificationCodePrompt = function() {
-    MobileIdentityManager.onUICancel();
-  };
-  MobileIdentityManager.ui = ui;
-
-  let credStore = new MockCredStore();
-  MobileIdentityManager.credStore = credStore;
-
-  let client = new MockClient();
-  MobileIdentityManager.client = client;
-
-  let promiseId = Date.now();
-  let mm = {
-    sendAsyncMessage: function(aMsg, aData) {
-      do_print("sendAsyncMessage " + aMsg + " - " + JSON.stringify(aData));
-
-      // Check result.
-      do_check_eq(aMsg, GET_ASSERTION_RETURN_KO);
-      do_check_eq(typeof aData, "object");
-      do_check_eq(aData.promiseId, promiseId);
-      do_check_eq(aData.error, DIALOG_CLOSED_BY_USER);
-
-      do_test_finished();
-      run_next_test();
-    }
-  };
-
-  addPermission(Ci.nsIPermissionManager.ALLOW_ACTION);
-
-  MobileIdentityManager.receiveMessage({
-    name: GET_ASSERTION_IPC_MSG,
-    principal: PRINCIPAL,
-    target: mm,
-    json: {
-      promiseId: promiseId,
-      options: {}
-    }
-  });
-});
-
deleted file mode 100644
--- a/services/mobileid/tests/xpcshell/test_mobileid_verification_flow.js
+++ /dev/null
@@ -1,42 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-Cu.import("resource://gre/modules/MobileIdentityVerificationFlow.jsm");
-
-function verifyStrategy() {
-  return Promise.resolve();
-}
-
-function cleanupStrategy() {
-}
-
-function run_test() {
-  do_print("= Bug 1101444: Invalid verification code shouldn't restart " +
-           "verification flow =");
-
-  let client = new MockClient({
-    // This will emulate two invalid attempts. The third time it will work.
-    verifyCodeError: ["INVALID", "INVALID"]
-  });
-  let ui = new MockUi();
-
-  let verificationFlow = new MobileIdentityVerificationFlow({
-    external: true,
-    sessionToken: SESSION_TOKEN,
-    msisdn: PHONE_NUMBER
-  }, ui, client, verifyStrategy, cleanupStrategy);
-
-  verificationFlow.doVerification().then(() => {
-    // We should only do the registration process once. We only try registering
-    // again when the timeout fires, but not when we enter an invalid
-    // verification code.
-    client._("register").callsLength(1);
-    client._("verifyCode").callsLength(3);
-    // Because we do two invalid attempts, we should show the invalid code error twice.
-    ui._("error").callsLength(2);
-  });
-
-  do_test_finished();
-};
deleted file mode 100644
--- a/services/mobileid/tests/xpcshell/xpcshell.ini
+++ /dev/null
@@ -1,8 +0,0 @@
-[DEFAULT]
-head = head.js
-tail =
-
-[test_mobileid_manager.js]
-skip-if = 1
-[test_mobileid_client.js]
-[test_mobileid_verification_flow.js]
--- a/services/moz.build
+++ b/services/moz.build
@@ -10,13 +10,10 @@ DIRS += [
 ]
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] != 'android':
     DIRS += ['fxaccounts']
 
 if CONFIG['MOZ_SERVICES_SYNC']:
     DIRS += ['sync']
 
-if CONFIG['MOZ_B2G']:
-    DIRS += ['mobileid']
-
 if CONFIG['MOZ_SERVICES_CLOUDSYNC']:
     DIRS += ['cloudsync']
--- a/testing/web-platform/meta/MANIFEST.json
+++ b/testing/web-platform/meta/MANIFEST.json
@@ -37651,16 +37651,22 @@
           }
         ],
         "domparsing/style_attribute_html.html": [
           {
             "path": "domparsing/style_attribute_html.html",
             "url": "/domparsing/style_attribute_html.html"
           }
         ],
+        "editing/other/delete.html": [
+          {
+            "path": "editing/other/delete.html",
+            "url": "/editing/other/delete.html"
+          }
+        ],
         "html/semantics/forms/the-form-element/form-submission-sandbox.html": [
           {
             "path": "html/semantics/forms/the-form-element/form-submission-sandbox.html",
             "url": "/html/semantics/forms/the-form-element/form-submission-sandbox.html"
           }
         ],
         "web-animations/timing-model/animation-effects/phases-and-states.html": [
           {
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/meta/editing/other/delete.html.ini
@@ -0,0 +1,14 @@
+[delete.html]
+  type: testharness
+  [2: "<p><br></p><p><br></p>" 0,0-1,0 delete]
+    expected: FAIL
+
+  [3: "<p><br></p><p><br></p>" 0,0-1,0 forwarddelete]
+    expected: FAIL
+
+  [4: "<p><br></p><p><br></p>" 1,0-0,0 delete]
+    expected: FAIL
+
+  [5: "<p><br></p><p><br></p>" 1,0-0,0 forwarddelete]
+    expected: FAIL
+
--- a/testing/web-platform/tests/editing/README
+++ b/testing/web-platform/tests/editing/README
@@ -1,9 +1,14 @@
-This suite tests conformance to the editing spec written long ago by Aryeh
-Gregor.  Nobody actually implements the spec, but the tests are still useful
-for regression testing.  The files in data/ were generated from a JavaScript
-implementation of the specification using a complex procedure that can't
-actually be replicated right now as-is.  Editing them manually is possible, but
-they're not really meant to be human-readable.  If anyone is interested, it
-would be possible for Aryeh to get the test generation procedure working again.
-Or you could look into the repository history and figure out how to do it
-yourself, if you're brave.
+Most of this directory tests conformance to the editing spec written long ago
+by Aryeh Gregor.  Nobody actually implements the spec, but the tests are still
+useful for regression testing.  The files in data/ were generated from a
+JavaScript implementation of the specification using a complex procedure that
+can't actually be replicated right now as-is.  Editing them manually is
+possible, but they're not really meant to be human-readable.  If anyone is
+interested, it would be possible for Aryeh to get the test generation procedure
+working again.  Or you could look into the repository history and figure out
+how to do it yourself, if you're brave.
+
+There is also a directory other/ that contains additional editor-related tests.
+They aren't necessarily based on any specification, but try to specify sensible
+behavior, and are meant to be helpful with regression testing for existing
+implementations and finding bugs in new implementations.
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/editing/other/delete.html
@@ -0,0 +1,149 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Deletion tests</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div contenteditable></div>
+<script>
+var div = document.querySelector("div");
+
+// Format: [start html, start pos, expected html, expected pos, command]
+// Positions are a sequence of offsets starting from div, e.g., "1,2,0"
+// translates to node = div.childNodes[1].childNodes[2], offset = 0.  For a
+// non-collapsed selection, use a hyphen, like "0,0-1,0".  The selections are
+// created with collapse() followed by extend() to allow reverse selections, so
+// order is significant.
+//
+// Expected values can be arrays, in which case any is acceptable.
+var tests = [
+  ["<p><br></p><p><br></p>", "1,0", "<p><br></p>", "0,0", "delete"],
+  ["<p><br></p><p><br></p>", "0,0", "<p><br></p>", "0,0", "forwarddelete"],
+
+  // Range
+  ["<p><br></p><p><br></p>", "0,0-1,0", "<p><br></p>", "0,0", "delete"],
+  ["<p><br></p><p><br></p>", "0,0-1,0", "<p><br></p>", "0,0", "forwarddelete"],
+  ["<p><br></p><p><br></p>", "1,0-0,0", "<p><br></p>", "0,0", "delete"],
+  ["<p><br></p><p><br></p>", "1,0-0,0", "<p><br></p>", "0,0", "forwarddelete"],
+
+  // Different start values
+  ["<p>x<br></p><p><br></p>", "1,0",
+   // WebKit/Blink like to get rid of the extra <br>
+   ["<p>x<br></p>", "<p>x</p>"],
+   // The selection should really be collapsed inside the text node, but in the
+   // parent is close enough.
+   ["0,0,1", "0,1"], "delete"],
+  ["<p><br><br></p><p><br></p>", "1,0", "<p><br><br></p>", "0,1", "delete"],
+  ["<p><br></p><p><br><br></p>", "1,1",
+   "<p><br></p><p><br></p>", "1,0", "delete"],
+  ["<p><br><br><br></p>", "0,2", "<p><br><br></p>", "0,1", "delete"],
+  ["<p><br></p><p><br><br><br></p>", "1,2",
+   "<p><br></p><p><br><br></p>", "1,1", "delete"],
+  ["<p><br><br></p><p><br><br></p>", "1,1",
+   "<p><br><br></p><p><br></p>", "1,0", "delete"],
+  ["<p><br></p><br>", "1", "<p><br></p>", "0,0", "delete"],
+
+  // The trailing \n in these cases is actually significant, because it was
+  // necessary to trigger an actual Gecko bug (somehow!).
+  ["<p><br></p><p><br></p>\n", "1,0", "<p><br></p>\n", "0,0", "delete"],
+  ["<p><br></p><p><br></p>\n", "0,0", "<p><br></p>\n", "0,0", "forwarddelete"],
+  ["\n<p><tt>x</tt></p><p><tt><br></tt></p><p><tt><br></tt></p>\n", "3,0,0",
+   "\n<p><tt>x</tt></p><p><tt><br></tt></p>\n", "2,0,0", "delete"],
+];
+
+div.focus();
+
+for (var i = 0; i < tests.length; i++) {
+  test(function() {
+    var test = tests[i];
+    div.innerHTML = test[0];
+    setSelection(test[1]);
+
+    document.execCommand(test[4], false, "");
+
+    if (typeof test[2] == "string") {
+      assert_equals(div.innerHTML, test[2], "innerHTML");
+    } else {
+      assert_in_array(div.innerHTML, test[2], "innerHTML");
+    }
+
+    var actualSel = recordSelection();
+    var expectedSel = [];
+    if (typeof test[3] == "string") {
+      test[3] = [test[3]];
+    }
+    for (var j = 0; j < test[3].length; j++) {
+      setSelection(test[3][j]);
+      expectedSel.push(recordSelection());
+    }
+    assertSelectionEquals(actualSel, expectedSel, test[2]);
+  }, i + ": " + format_value(tests[i][0]) + " " + tests[i][1] +
+  " " + tests[i][4]);
+}
+
+function setSelection(selstr) {
+  var parts = selstr.split("-");
+  var collapsePoint = getPointFromArray(parts[0].split(","));
+  getSelection().collapse(collapsePoint[0], collapsePoint[1]);
+
+  if (parts[1]) {
+    var extendPoint = getPointFromArray(parts[1].split(","));
+    getSelection().extend(extendPoint[0], extendPoint[1]);
+  }
+}
+
+function getPointFromArray(offsets) {
+  var retNode = div, retOffset;
+  var offset;
+  while (offset = offsets.shift()) {
+    if (!offsets.length) {
+      retOffset = offset;
+    } else {
+      retNode = retNode.childNodes[offset];
+    }
+  }
+  return [retNode, retOffset];
+}
+
+function recordSelection() {
+  return [getSelection().anchorNode, getSelection().anchorOffset,
+          getSelection().focusNode, getSelection().focusOffset];
+}
+
+function assertSelectionEquals(actual, expected, html) {
+  if (typeof expected == "string") {
+    expected = [expected];
+  }
+  var pass = false;
+  for (var i = 0; i < expected.length; i++) {
+    if (expected[i][0] === actual[0] &&
+        expected[i][1] === actual[1] &&
+        expected[i][2] === actual[2] &&
+        expected[i][3] === actual[3]) {
+      pass = true;
+      break;
+    }
+  }
+
+  assert_true(pass, "Wrong selection, expected " + formatSel(expected) +
+              ", got " + formatSel(actual) +
+              " (in HTML " + format_value(html) + ")");
+}
+
+function formatSel(arr) {
+  if (arr.length == 1) {
+    arr = arr[0];
+  }
+  if (Array.isArray(arr[0])) {
+    var ret = [];
+    for (var i = 0; i < arr.length; i++) {
+      ret.push(formatSel(arr[i]));
+    }
+    return ret.join(" or ");
+  }
+  if (arr[0] == arr[2] && arr[1] == arr[3]) {
+    return "collapsed (" + format_value(arr[0]) + ", " + arr[1] + ")";
+  }
+  return "(" + format_value(arr[0]) + ", " + arr[1] +
+         ")-(" + format_value(arr[2]) + ", " + arr[3] + ")";
+}
+</script>