Bug 1220906 - Part 5: Remove Old Sync setup and JPAKE code. r?rnewman draft
authorNick Alexander <nalexander@mozilla.com>
Tue, 19 Jan 2016 11:31:31 -0800
changeset 323264 ffda6a31c28425939fdee29c39665bf5efe46b2a
parent 323263 5fb01e0014964e70da332cd2ef8de0be74538093
child 323265 ca78b72367312a9c3808cd481651cf80873e63a5
push id9692
push usernalexander@mozilla.com
push dateTue, 19 Jan 2016 22:55:33 +0000
reviewersrnewman
bugs1220906
milestone46.0a1
Bug 1220906 - Part 5: Remove Old Sync setup and JPAKE code. r?rnewman
mobile/android/base/android-services.mozbuild
mobile/android/config/proguard/proguard.cfg
mobile/android/services/src/main/java/org/mozilla/gecko/sync/config/ConfigurationMigrator.java
mobile/android/services/src/main/java/org/mozilla/gecko/sync/config/activities/SelectEnginesActivity.java
mobile/android/services/src/main/java/org/mozilla/gecko/sync/jpake/BigIntegerHelper.java
mobile/android/services/src/main/java/org/mozilla/gecko/sync/jpake/Gx3OrGx4IsZeroOrOneException.java
mobile/android/services/src/main/java/org/mozilla/gecko/sync/jpake/IncorrectZkpException.java
mobile/android/services/src/main/java/org/mozilla/gecko/sync/jpake/JPakeClient.java
mobile/android/services/src/main/java/org/mozilla/gecko/sync/jpake/JPakeCrypto.java
mobile/android/services/src/main/java/org/mozilla/gecko/sync/jpake/JPakeJson.java
mobile/android/services/src/main/java/org/mozilla/gecko/sync/jpake/JPakeNoActivePairingException.java
mobile/android/services/src/main/java/org/mozilla/gecko/sync/jpake/JPakeNumGenerator.java
mobile/android/services/src/main/java/org/mozilla/gecko/sync/jpake/JPakeNumGeneratorRandom.java
mobile/android/services/src/main/java/org/mozilla/gecko/sync/jpake/JPakeParty.java
mobile/android/services/src/main/java/org/mozilla/gecko/sync/jpake/Zkp.java
mobile/android/services/src/main/java/org/mozilla/gecko/sync/jpake/stage/CompleteStage.java
mobile/android/services/src/main/java/org/mozilla/gecko/sync/jpake/stage/ComputeFinalStage.java
mobile/android/services/src/main/java/org/mozilla/gecko/sync/jpake/stage/ComputeKeyVerificationStage.java
mobile/android/services/src/main/java/org/mozilla/gecko/sync/jpake/stage/ComputeStepOneStage.java
mobile/android/services/src/main/java/org/mozilla/gecko/sync/jpake/stage/ComputeStepTwoStage.java
mobile/android/services/src/main/java/org/mozilla/gecko/sync/jpake/stage/DecryptDataStage.java
mobile/android/services/src/main/java/org/mozilla/gecko/sync/jpake/stage/DeleteChannel.java
mobile/android/services/src/main/java/org/mozilla/gecko/sync/jpake/stage/GetChannelStage.java
mobile/android/services/src/main/java/org/mozilla/gecko/sync/jpake/stage/GetRequestStage.java
mobile/android/services/src/main/java/org/mozilla/gecko/sync/jpake/stage/JPakeStage.java
mobile/android/services/src/main/java/org/mozilla/gecko/sync/jpake/stage/PutRequestStage.java
mobile/android/services/src/main/java/org/mozilla/gecko/sync/jpake/stage/VerifyPairingStage.java
mobile/android/services/src/main/java/org/mozilla/gecko/sync/receivers/SyncAccountDeletedReceiver.java
mobile/android/services/src/main/java/org/mozilla/gecko/sync/receivers/SyncAccountDeletedService.java
mobile/android/services/src/main/java/org/mozilla/gecko/sync/receivers/UpgradeReceiver.java
mobile/android/services/src/main/java/org/mozilla/gecko/sync/setup/SyncAuthenticatorService.java
mobile/android/services/src/main/java/org/mozilla/gecko/sync/setup/activities/AccountActivity.java
mobile/android/services/src/main/java/org/mozilla/gecko/sync/setup/activities/RedirectToSetupActivity.java
mobile/android/services/src/main/java/org/mozilla/gecko/sync/setup/activities/SendTabData.java
mobile/android/services/src/main/java/org/mozilla/gecko/sync/setup/activities/SetupFailureActivity.java
mobile/android/services/src/main/java/org/mozilla/gecko/sync/setup/activities/SetupSuccessActivity.java
mobile/android/services/src/main/java/org/mozilla/gecko/sync/setup/activities/SetupSyncActivity.java
mobile/android/services/src/main/java/org/mozilla/gecko/sync/setup/activities/SyncActivity.java
mobile/android/services/src/main/java/org/mozilla/gecko/sync/setup/activities/WebViewActivity.java
mobile/android/services/src/main/java/org/mozilla/gecko/sync/setup/auth/AccountAuthenticator.java
mobile/android/services/src/main/java/org/mozilla/gecko/sync/setup/auth/AuthenticateAccountStage.java
mobile/android/services/src/main/java/org/mozilla/gecko/sync/setup/auth/AuthenticationResult.java
mobile/android/services/src/main/java/org/mozilla/gecko/sync/setup/auth/AuthenticatorStage.java
mobile/android/services/src/main/java/org/mozilla/gecko/sync/setup/auth/EnsureUserExistenceStage.java
mobile/android/services/src/main/java/org/mozilla/gecko/sync/setup/auth/FetchUserNodeStage.java
mobile/android/services/src/main/java/org/mozilla/gecko/sync/syncadapter/SyncAdapter.java
mobile/android/services/src/main/java/org/mozilla/gecko/sync/syncadapter/SyncService.java
mobile/android/tests/background/junit3/background_junit3_sources.mozbuild
mobile/android/tests/background/junit3/instrumentation.ini
mobile/android/tests/background/junit3/src/org/mozilla/gecko/background/sync/TestSendTabData.java
mobile/android/tests/background/junit3/src/org/mozilla/gecko/background/testhelpers/JPakeNumGeneratorFixed.java
mobile/android/tests/background/junit4/src/org/mozilla/android/sync/net/test/TestAccountAuthenticatorStage.java
mobile/android/tests/background/junit4/src/org/mozilla/android/sync/test/TestJPakeSetup.java
mobile/android/tests/background/junit4/src/org/mozilla/gecko/background/testhelpers/JPakeNumGeneratorFixed.java
--- a/mobile/android/base/android-services.mozbuild
+++ b/mobile/android/base/android-services.mozbuild
@@ -866,19 +866,17 @@ sync_java_files = [TOPSRCDIR + '/mobile/
     'fxa/SyncStatusListener.java',
     'sync/AlreadySyncingException.java',
     'sync/BackoffHandler.java',
     'sync/BadRequiredFieldJSONException.java',
     'sync/CollectionKeys.java',
     'sync/CommandProcessor.java',
     'sync/CommandRunner.java',
     'sync/config/AccountPickler.java',
-    'sync/config/activities/SelectEnginesActivity.java',
     'sync/config/ClientRecordTerminator.java',
-    'sync/config/ConfigurationMigrator.java',
     'sync/CredentialException.java',
     'sync/crypto/CryptoException.java',
     'sync/crypto/CryptoInfo.java',
     'sync/crypto/HKDF.java',
     'sync/crypto/HMACVerificationException.java',
     'sync/crypto/KeyBundle.java',
     'sync/crypto/MissingCryptoInputException.java',
     'sync/crypto/NoKeyBundleException.java',
@@ -896,39 +894,16 @@ sync_java_files = [TOPSRCDIR + '/mobile/
     'sync/delegates/NodeAssignmentCallback.java',
     'sync/delegates/WipeServerDelegate.java',
     'sync/EngineSettings.java',
     'sync/ExtendedJSONObject.java',
     'sync/GlobalSession.java',
     'sync/HTTPFailureException.java',
     'sync/InfoCollections.java',
     'sync/InfoCounts.java',
-    'sync/jpake/BigIntegerHelper.java',
-    'sync/jpake/Gx3OrGx4IsZeroOrOneException.java',
-    'sync/jpake/IncorrectZkpException.java',
-    'sync/jpake/JPakeClient.java',
-    'sync/jpake/JPakeCrypto.java',
-    'sync/jpake/JPakeJson.java',
-    'sync/jpake/JPakeNoActivePairingException.java',
-    'sync/jpake/JPakeNumGenerator.java',
-    'sync/jpake/JPakeNumGeneratorRandom.java',
-    'sync/jpake/JPakeParty.java',
-    'sync/jpake/stage/CompleteStage.java',
-    'sync/jpake/stage/ComputeFinalStage.java',
-    'sync/jpake/stage/ComputeKeyVerificationStage.java',
-    'sync/jpake/stage/ComputeStepOneStage.java',
-    'sync/jpake/stage/ComputeStepTwoStage.java',
-    'sync/jpake/stage/DecryptDataStage.java',
-    'sync/jpake/stage/DeleteChannel.java',
-    'sync/jpake/stage/GetChannelStage.java',
-    'sync/jpake/stage/GetRequestStage.java',
-    'sync/jpake/stage/JPakeStage.java',
-    'sync/jpake/stage/PutRequestStage.java',
-    'sync/jpake/stage/VerifyPairingStage.java',
-    'sync/jpake/Zkp.java',
     'sync/JSONRecordFetcher.java',
     'sync/KeyBundleProvider.java',
     'sync/MetaGlobal.java',
     'sync/MetaGlobalException.java',
     'sync/MetaGlobalMissingEnginesException.java',
     'sync/MetaGlobalNotSetException.java',
     'sync/middleware/Crypto5MiddlewareRepository.java',
     'sync/middleware/Crypto5MiddlewareRepositorySession.java',
@@ -964,19 +939,16 @@ sync_java_files = [TOPSRCDIR + '/mobile/
     'sync/net/WBORequestDelegate.java',
     'sync/NoCollectionKeysSetException.java',
     'sync/NodeAuthenticationException.java',
     'sync/NonArrayJSONException.java',
     'sync/NonObjectJSONException.java',
     'sync/NullClusterURLException.java',
     'sync/PersistedMetaGlobal.java',
     'sync/PrefsBackoffHandler.java',
-    'sync/receivers/SyncAccountDeletedReceiver.java',
-    'sync/receivers/SyncAccountDeletedService.java',
-    'sync/receivers/UpgradeReceiver.java',
     'sync/repositories/android/AndroidBrowserBookmarksDataAccessor.java',
     'sync/repositories/android/AndroidBrowserBookmarksRepository.java',
     'sync/repositories/android/AndroidBrowserBookmarksRepositorySession.java',
     'sync/repositories/android/AndroidBrowserHistoryDataAccessor.java',
     'sync/repositories/android/AndroidBrowserHistoryDataExtender.java',
     'sync/repositories/android/AndroidBrowserHistoryRepository.java',
     'sync/repositories/android/AndroidBrowserHistoryRepositorySession.java',
     'sync/repositories/android/AndroidBrowserRepository.java',
@@ -1044,36 +1016,21 @@ sync_java_files = [TOPSRCDIR + '/mobile/
     'sync/repositories/RepositorySessionBundle.java',
     'sync/repositories/Server11Repository.java',
     'sync/repositories/Server11RepositorySession.java',
     'sync/repositories/StoreFailedException.java',
     'sync/repositories/StoreTracker.java',
     'sync/repositories/StoreTrackingRepositorySession.java',
     'sync/Server11PreviousPostFailedException.java',
     'sync/Server11RecordPostFailedException.java',
-    'sync/setup/activities/AccountActivity.java',
     'sync/setup/activities/ActivityUtils.java',
-    'sync/setup/activities/RedirectToSetupActivity.java',
-    'sync/setup/activities/SendTabData.java',
-    'sync/setup/activities/SetupFailureActivity.java',
-    'sync/setup/activities/SetupSuccessActivity.java',
-    'sync/setup/activities/SetupSyncActivity.java',
-    'sync/setup/activities/SyncActivity.java',
     'sync/setup/activities/WebURLFinder.java',
-    'sync/setup/activities/WebViewActivity.java',
-    'sync/setup/auth/AccountAuthenticator.java',
-    'sync/setup/auth/AuthenticateAccountStage.java',
-    'sync/setup/auth/AuthenticationResult.java',
-    'sync/setup/auth/AuthenticatorStage.java',
-    'sync/setup/auth/EnsureUserExistenceStage.java',
-    'sync/setup/auth/FetchUserNodeStage.java',
     'sync/setup/Constants.java',
     'sync/setup/InvalidSyncKeyException.java',
     'sync/setup/SyncAccounts.java',
-    'sync/setup/SyncAuthenticatorService.java',
     'sync/SharedPreferencesClientsDataDelegate.java',
     'sync/SharedPreferencesNodeAssignmentCallback.java',
     'sync/stage/AbstractNonRepositorySyncStage.java',
     'sync/stage/AbstractSessionManagingSyncStage.java',
     'sync/stage/AndroidBrowserBookmarksServerSyncStage.java',
     'sync/stage/AndroidBrowserHistoryServerSyncStage.java',
     'sync/stage/CheckPreconditionsStage.java',
     'sync/stage/CompletedStage.java',
@@ -1087,18 +1044,16 @@ sync_java_files = [TOPSRCDIR + '/mobile/
     'sync/stage/NoSuchStageException.java',
     'sync/stage/NoSyncIDException.java',
     'sync/stage/PasswordsServerSyncStage.java',
     'sync/stage/SafeConstrainedServer11Repository.java',
     'sync/stage/ServerSyncStage.java',
     'sync/stage/SyncClientsEngineStage.java',
     'sync/stage/UploadMetaGlobalStage.java',
     'sync/Sync11Configuration.java',
-    'sync/syncadapter/SyncAdapter.java',
-    'sync/syncadapter/SyncService.java',
     'sync/SyncConfiguration.java',
     'sync/SyncConfigurationException.java',
     'sync/SyncConstants.java',
     'sync/SyncException.java',
     'sync/synchronizer/ConcurrentRecordConsumer.java',
     'sync/synchronizer/RecordConsumer.java',
     'sync/synchronizer/RecordsChannel.java',
     'sync/synchronizer/RecordsChannelDelegate.java',
--- a/mobile/android/config/proguard/proguard.cfg
+++ b/mobile/android/config/proguard/proguard.cfg
@@ -11,18 +11,18 @@
 # Preserve all fundamental application classes.
 -keep public class * extends android.app.Activity
 -keep public class * extends android.app.Application
 -keep public class * extends android.app.Service
 -keep public class * extends android.app.backup.BackupAgentHelper
 -keep public class * extends android.content.BroadcastReceiver
 -keep public class * extends android.content.ContentProvider
 -keep public class * extends android.preference.Preference
--keep public class * extends org.mozilla.gecko.sync.syncadapter.SyncAdapter
--keep class org.mozilla.gecko.sync.syncadapter.SyncAdapter
+-keep public class * extends org.mozilla.gecko.fxa.sync.FxAccountSyncAdapter
+-keep class org.mozilla.gecko.fxa.sync.FxAccountSyncAdapter
 
 -keep public class * extends android.support.v4.app.Fragment
 
 # Preserve all native method names and the names of their classes.
 -keepclasseswithmembernames class * {
     native <methods>;
 }
 
deleted file mode 100644
--- a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/config/ConfigurationMigrator.java
+++ /dev/null
@@ -1,382 +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.sync.config;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import org.mozilla.gecko.background.common.log.Logger;
-import org.mozilla.gecko.sync.SyncConfiguration;
-import org.mozilla.gecko.sync.Utils;
-
-import android.accounts.Account;
-import android.accounts.AccountManager;
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.content.SharedPreferences.Editor;
-
-/**
- * Migrate Sync preferences between versions.
- * <p>
- * The original preferences were un-versioned; we refer to that as "version 0".
- * The original preferences were stored in three places:
- * <ul>
- * <li>most prefs were kept in per-Sync account Android shared prefs;</li>
- * <li>some prefs were kept in per-App Android shared prefs;</li>
- * <li>some client prefs were kept in the (assumed unique) Android Account.</li>
- * </ul>
- * <p>
- * Post version 0, all preferences are stored in per-Sync account Android shared prefs.
- */
-public class ConfigurationMigrator {
-  public static final String LOG_TAG = "ConfigMigrator";
-
-  /**
-   * Copy and rename preferences.
-   *
-   * @param from source.
-   * @param to sink.
-   * @param map map from old preference names to new preference names.
-   * @return the number of preferences migrated.
-   */
-  protected static int copyPreferences(final SharedPreferences from, final Map<String, String> map, final Editor to) {
-    int count = 0;
-
-    // SharedPreferences has no way to get a key/value pair without specifying the value type, so we do this instead.
-    for (Entry<String, ?> entry : from.getAll().entrySet()) {
-      String fromKey = entry.getKey();
-      String toKey = map.get(fromKey);
-      if (toKey == null) {
-        continue;
-      }
-
-      Object value = entry.getValue();
-      if (value instanceof Boolean) {
-         to.putBoolean(toKey, (Boolean) value);
-      } else if (value instanceof Float) {
-         to.putFloat(toKey, (Float) value);
-      } else if (value instanceof Integer) {
-         to.putInt(toKey, (Integer) value);
-      } else if (value instanceof Long) {
-         to.putLong(toKey, (Long) value);
-      } else if (value instanceof String) {
-         to.putString(toKey, (String) value);
-      } else {
-        // Do nothing -- perhaps SharedPreferences accepts types we don't know about.
-      }
-
-      if (Logger.LOG_PERSONAL_INFORMATION) {
-        Logger.debug(LOG_TAG, "Migrated '" + fromKey + "' to '" + toKey + "' (" + value + ").");
-      } else {
-        Logger.debug(LOG_TAG, "Migrated '" + fromKey + "' to '" + toKey + "'.");
-      }
-      count += 1;
-    }
-
-    return count;
-  }
-
-  protected final static String V0_PREF_CLUSTER_URL_IS_STALE = "clusterurlisstale";
-  protected final static String V1_PREF_CLUSTER_URL_IS_STALE = V0_PREF_CLUSTER_URL_IS_STALE;
-  protected final static String V0_PREF_EARLIEST_NEXT_SYNC = "earliestnextsync";
-  protected final static String V1_PREF_EARLIEST_NEXT_SYNC = V0_PREF_EARLIEST_NEXT_SYNC;
-
-  /**
-   * Extract version 0 preferences from per-App Android shared prefs and write to version 1 per-Sync account shared prefs.
-   *
-   * @param from per-App version 0 Android shared prefs.
-   * @param to per-Sync account version 1 shared prefs.
-   * @return the number of preferences migrated.
-   * @throws Exception
-   */
-  protected static int upgradeGlobals0to1(final SharedPreferences from, final SharedPreferences to) throws Exception {
-    Map<String, String> map = new HashMap<String, String>();
-    map.put(V0_PREF_CLUSTER_URL_IS_STALE, V1_PREF_CLUSTER_URL_IS_STALE);
-    map.put(V0_PREF_EARLIEST_NEXT_SYNC, V1_PREF_EARLIEST_NEXT_SYNC);
-
-    Editor editor = to.edit();
-    int count = copyPreferences(from, map, editor);
-    if (count > 0) {
-      editor.commit();
-    }
-    return count;
-  }
-
-  /**
-   * Extract version 1 per-Sync account shared prefs and write to version 0 preferences from per-App Android shared prefs.
-   *
-   * @param from per-Sync account version 1 shared prefs.
-   * @param to per-App version 0 Android shared prefs.
-   * @return the number of preferences migrated.
-   * @throws Exception
-   */
-  protected static int downgradeGlobals1to0(final SharedPreferences from, final SharedPreferences to) throws Exception {
-    Map<String, String> map = new HashMap<String, String>();
-    map.put(V1_PREF_CLUSTER_URL_IS_STALE, V0_PREF_CLUSTER_URL_IS_STALE);
-    map.put(V1_PREF_EARLIEST_NEXT_SYNC, V0_PREF_EARLIEST_NEXT_SYNC);
-
-    Editor editor = to.edit();
-    int count = copyPreferences(from, map, editor);
-    if (count > 0) {
-      editor.commit();
-    }
-    return count;
-  }
-
-  protected static final String V0_PREF_ACCOUNT_GUID = "account.guid";
-  protected static final String V1_PREF_ACCOUNT_GUID = V0_PREF_ACCOUNT_GUID;
-  protected static final String V0_PREF_CLIENT_NAME = "account.clientName";
-  protected static final String V1_PREF_CLIENT_NAME = V0_PREF_CLIENT_NAME;
-  protected static final String V0_PREF_NUM_CLIENTS = "account.numClients";
-  protected static final String V1_PREF_NUM_CLIENTS = V0_PREF_NUM_CLIENTS;
-
-  /**
-   * Extract version 0 per-Android account user data and write to version 1 per-Sync account shared prefs.
-   *
-   * @param accountManager Android account manager.
-   * @param account Android account.
-   * @param to per-Sync account version 1 shared prefs.
-   * @return the number of preferences migrated.
-   * @throws Exception
-   */
-  protected static int upgradeAndroidAccount0to1(final AccountManager accountManager, final Account account, final SharedPreferences to) throws Exception {
-    final String V0_PREF_ACCOUNT_GUID = "account.guid";
-    final String V1_PREF_ACCOUNT_GUID = V0_PREF_ACCOUNT_GUID;
-    final String V0_PREF_CLIENT_NAME = "account.clientName";
-    final String V1_PREF_CLIENT_NAME = V0_PREF_CLIENT_NAME;
-    final String V0_PREF_NUM_CLIENTS = "account.numClients";
-    final String V1_PREF_NUM_CLIENTS = V0_PREF_NUM_CLIENTS;
-
-    String accountGUID = null;
-    String clientName = null;
-    long numClients = -1;
-    try {
-      accountGUID = accountManager.getUserData(account, V0_PREF_ACCOUNT_GUID);
-    } catch (Exception e) {
-      // Do nothing.
-    }
-    try {
-      clientName = accountManager.getUserData(account, V0_PREF_CLIENT_NAME);
-    } catch (Exception e) {
-      // Do nothing.
-    }
-    try {
-      numClients = Long.parseLong(accountManager.getUserData(account, V0_PREF_NUM_CLIENTS));
-    } catch (Exception e) {
-      // Do nothing.
-    }
-
-    final Editor editor = to.edit();
-
-    int count = 0;
-    if (accountGUID != null) {
-      final String fromKey = V0_PREF_ACCOUNT_GUID;
-      final String toKey = V1_PREF_ACCOUNT_GUID;
-      if (Logger.LOG_PERSONAL_INFORMATION) {
-        Logger.debug(LOG_TAG, "Migrated '" + fromKey + "' to '" + toKey + "' (" + accountGUID + ").");
-      } else {
-        Logger.debug(LOG_TAG, "Migrated '" + fromKey + "' to '" + toKey + "'.");
-      }
-      editor.putString(toKey, accountGUID);
-      count += 1;
-    }
-    if (clientName != null) {
-      final String fromKey = V0_PREF_CLIENT_NAME;
-      final String toKey = V1_PREF_CLIENT_NAME;
-      if (Logger.LOG_PERSONAL_INFORMATION) {
-        Logger.debug(LOG_TAG, "Migrated '" + fromKey + "' to '" + toKey + "' (" + clientName + ").");
-      } else {
-        Logger.debug(LOG_TAG, "Migrated '" + fromKey + "' to '" + toKey + "'.");
-      }
-      editor.putString(toKey, clientName);
-      count += 1;
-    }
-    if (numClients > -1) {
-      final String fromKey = V0_PREF_NUM_CLIENTS;
-      final String toKey = V1_PREF_NUM_CLIENTS;
-      if (Logger.LOG_PERSONAL_INFORMATION) {
-        Logger.debug(LOG_TAG, "Migrated '" + fromKey + "' to '" + toKey + "' (" + numClients + ").");
-      } else {
-        Logger.debug(LOG_TAG, "Migrated '" + fromKey + "' to '" + toKey + "'.");
-      }
-      editor.putLong(toKey, numClients);
-      count += 1;
-    }
-
-    if (count > 0) {
-      editor.commit();
-    }
-    return count;
-  }
-
-  /**
-   * Extract version 1 per-Sync account shared prefs and write to version 0 per-Android account user data.
-   *
-   * @param from per-Sync account version 1 shared prefs.
-   * @param accountManager Android account manager.
-   * @param account Android account.
-   * @return the number of preferences migrated.
-   * @throws Exception
-   */
-  protected static int downgradeAndroidAccount1to0(final SharedPreferences from, final AccountManager accountManager, final Account account) throws Exception {
-    final String accountGUID = from.getString(V1_PREF_ACCOUNT_GUID, null);
-    final String clientName = from.getString(V1_PREF_CLIENT_NAME, null);
-    final long numClients = from.getLong(V1_PREF_NUM_CLIENTS, -1L);
-
-    int count = 0;
-    if (accountGUID != null) {
-      Logger.debug(LOG_TAG, "Migrated account GUID.");
-      accountManager.setUserData(account, V0_PREF_ACCOUNT_GUID, accountGUID);
-      count += 1;
-    }
-    if (clientName != null) {
-      Logger.debug(LOG_TAG, "Migrated client name.");
-      accountManager.setUserData(account, V1_PREF_CLIENT_NAME, clientName);
-      count += 1;
-    }
-    if (numClients > -1) {
-      Logger.debug(LOG_TAG, "Migrated clients count.");
-      accountManager.setUserData(account, V1_PREF_NUM_CLIENTS, Long.toString(numClients));
-      count += 1;
-    }
-    return count;
-  }
-
-  /**
-   * Extract version 0 per-Android account user data and write to version 1 per-Sync account shared prefs.
-   *
-   * @param from per-Sync account version 0 shared prefs.
-   * @param to per-Sync account version 1 shared prefs.
-   * @return the number of preferences migrated.
-   * @throws Exception
-   */
-  protected static int upgradeShared0to1(final SharedPreferences from, final SharedPreferences to) {
-    final Map<String, String> map = new HashMap<String, String>();
-    final String[] prefs = new String [] {
-        "syncID",
-        "clusterURL",
-        "enabledEngineNames",
-
-        "metaGlobalLastModified", "metaGlobalServerResponseBody",
-
-        "crypto5KeysLastModified", "crypto5KeysServerResponseBody",
-
-        "serverClientsTimestamp", "serverClientRecordTimestamp",
-
-        "forms.remote", "forms.local", "forms.syncID",
-        "tabs.remote", "tabs.local", "tabs.syncID",
-        "passwords.remote", "passwords.local", "passwords.syncID",
-        "history.remote", "history.local", "history.syncID",
-        "bookmarks.remote", "bookmarks.local", "bookmarks.syncID",
-    };
-    for (String pref : prefs) {
-      map.put(pref, pref);
-    }
-
-    Editor editor = to.edit();
-    int count = copyPreferences(from, map, editor);
-    if (count > 0) {
-      editor.commit();
-    }
-    return count;
-  }
-
-  /**
-   * Extract version 1 per-Sync account shared prefs and write to version 0 per-Android account user data.
-   *
-   * @param from per-Sync account version 1 shared prefs.
-   * @param to per-Sync account version 0 shared prefs.
-   * @return the number of preferences migrated.
-   * @throws Exception
-   */
-  protected static int downgradeShared1to0(final SharedPreferences from, final SharedPreferences to) {
-    // Strictly a copy, no re-naming, no deletions -- so just invert.
-    return upgradeShared0to1(from, to);
-  }
-
-  public static void upgrade0to1(final Context context, final AccountManager accountManager, final Account account,
-      final String product, final String username, final String serverURL, final String profile) throws Exception {
-
-    final String GLOBAL_SHARED_PREFS = "sync.prefs.global";
-
-    final SharedPreferences globalPrefs = context.getSharedPreferences(GLOBAL_SHARED_PREFS, Utils.SHARED_PREFERENCES_MODE);
-    final SharedPreferences accountPrefs = Utils.getSharedPreferences(context, product, username, serverURL, profile, 0);
-    final SharedPreferences newPrefs = Utils.getSharedPreferences(context, product, username, serverURL, profile, 1);
-
-    upgradeGlobals0to1(globalPrefs, newPrefs);
-    upgradeAndroidAccount0to1(accountManager, account, newPrefs);
-    upgradeShared0to1(accountPrefs, newPrefs);
-  }
-
-  public static void downgrade1to0(final Context context, final AccountManager accountManager, final Account account,
-      final String product, final String username, final String serverURL, final String profile) throws Exception {
-
-    final String GLOBAL_SHARED_PREFS = "sync.prefs.global";
-
-    final SharedPreferences globalPrefs = context.getSharedPreferences(GLOBAL_SHARED_PREFS, Utils.SHARED_PREFERENCES_MODE);
-    final SharedPreferences accountPrefs = Utils.getSharedPreferences(context, product, username, serverURL, profile, 0);
-    final SharedPreferences oldPrefs = Utils.getSharedPreferences(context, product, username, serverURL, profile, 1);
-
-    downgradeGlobals1to0(oldPrefs, globalPrefs);
-    downgradeAndroidAccount1to0(oldPrefs, accountManager, account);
-    downgradeShared1to0(oldPrefs, accountPrefs);
-  }
-
-  /**
-   * Migrate, if necessary, existing prefs to a certain version.
-   * <p>
-   * Stores current prefs version in Android shared prefs with root
-   * "sync.prefs.version", which corresponds to the file
-   * "sync.prefs.version.xml".
-   *
-   * @param desiredVersion
-   *          version to finish it.
-   * @param context
-   * @param accountManager
-   * @param account
-   * @param product
-   * @param username
-   * @param serverURL
-   * @param profile
-   * @throws Exception
-   */
-  public static void ensurePrefsAreVersion(final long desiredVersion,
-      final Context context, final AccountManager accountManager, final Account account,
-      final String product, final String username, final String serverURL, final String profile) throws Exception {
-    if (desiredVersion < 0 || desiredVersion > SyncConfiguration.CURRENT_PREFS_VERSION) {
-      throw new IllegalArgumentException("Cannot migrate to unknown version " + desiredVersion + ".");
-    }
-
-    SharedPreferences versionPrefs = context.getSharedPreferences("sync.prefs.version", Utils.SHARED_PREFERENCES_MODE);
-
-    // We default to 0 since clients getting this code for the first time will
-    // not have "sync.prefs.version.xml" *at all*, and upgrading when all old
-    // data is missing is expected to be safe.
-    long currentVersion = versionPrefs.getLong(SyncConfiguration.PREF_PREFS_VERSION, 0);
-    if (currentVersion == desiredVersion) {
-      Logger.info(LOG_TAG, "Current version (" + currentVersion + ") is desired version; no need to migrate.");
-      return;
-    }
-
-    if (currentVersion < 0 || currentVersion > SyncConfiguration.CURRENT_PREFS_VERSION) {
-      throw new IllegalStateException("Cannot migrate from unknown version " + currentVersion + ".");
-    }
-
-    // Now we're down to either version 0 or version 1.
-    if (currentVersion == 0 && desiredVersion == 1) {
-      Logger.info(LOG_TAG, "Upgrading from version 0 to version 1.");
-      upgrade0to1(context, accountManager, account, product, username, serverURL, profile);
-    } else if (currentVersion == 1 && desiredVersion == 0) {
-      Logger.info(LOG_TAG, "Upgrading from version 0 to version 1.");
-      downgrade1to0(context, accountManager, account, product, username, serverURL, profile);
-    } else {
-      Logger.warn(LOG_TAG, "Don't know how to migrate from version " + currentVersion + " to " + desiredVersion + ".");
-    }
-
-    Logger.info(LOG_TAG, "Migrated from version " + currentVersion + " to version " + desiredVersion + ".");
-    versionPrefs.edit().putLong(SyncConfiguration.PREF_PREFS_VERSION, desiredVersion).commit();
-  }
-}
deleted file mode 100644
--- a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/config/activities/SelectEnginesActivity.java
+++ /dev/null
@@ -1,210 +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.sync.config.activities;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
-import org.mozilla.gecko.R;
-import org.mozilla.gecko.background.common.log.Logger;
-import org.mozilla.gecko.sync.SyncConfiguration;
-import org.mozilla.gecko.sync.ThreadPool;
-import org.mozilla.gecko.sync.setup.SyncAccounts;
-import org.mozilla.gecko.sync.syncadapter.SyncAdapter;
-
-import android.accounts.Account;
-import android.accounts.AccountManager;
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.DialogInterface.OnDismissListener;
-import android.content.SharedPreferences;
-import android.os.Bundle;
-import android.widget.ListView;
-import android.widget.Toast;
-
-/**
- * Provides a user-facing interface for selecting engines to sync. This activity
- * can be launched from the Sync Settings preferences screen, and will save the
- * selected engines to the
- * <code>SyncConfiguration.PREF_USER_SELECTED_ENGINES_TO_SYNC</code> pref.
- *
- * On launch, it displays the engines stored in the saved pref if it exists, or
- * <code>SyncConfiguration.enabledEngineNames()</code> if it doesn't, defaulting
- * to <code>SyncConfiguration.validEngineNames()</code> if neither exists.
- *
- * During a sync, the
- * <code>SyncConfiguration.PREF_USER_SELECTED_ENGINES_TO_SYNC</code> pref will
- * be cleared after the engine changes are applied to meta/global.
- */
-
-public class SelectEnginesActivity extends Activity implements
-    DialogInterface.OnClickListener, DialogInterface.OnMultiChoiceClickListener {
-  public final static String LOG_TAG = "SelectEnginesAct";
-
-  protected AccountManager mAccountManager;
-  protected Context mContext;
-
-  // Collections names corresponding to displayed (localized) engine options.
-  final String[] _collectionsNames = new String[] {
-    "bookmarks",
-    "passwords",
-    "history",
-    "tabs"
-  };
-
-  // Engine names localized for display in Sync Settings.
-  protected String[] _options;
-  // Selection state of engines corresponding to _options array.
-  final boolean[] _selections = new boolean[_collectionsNames.length];
-  protected Account account;
-  protected SharedPreferences accountPrefs;
-
-  @Override
-  public void onCreate(Bundle savedInstanceState) {
-    super.onCreate(savedInstanceState);
-    mContext = getApplicationContext();
-    mAccountManager = AccountManager.get(mContext);
-    _options = new String[] {
-        getString(R.string.sync_configure_engines_title_bookmarks),
-        getString(R.string.sync_configure_engines_title_passwords),
-        getString(R.string.sync_configure_engines_title_history),
-        getString(R.string.sync_configure_engines_title_tabs) };
-
-    // Fetch account prefs for configuring engines.
-    ThreadPool.run(new Runnable() {
-      @Override
-      public void run() {
-        Account[] accounts = SyncAccounts.syncAccounts(mContext);
-        if (accounts.length == 0) {
-          Logger.error(LOG_TAG, "Failed to get account!");
-          finish();
-          return;
-        } else {
-          // Only supports one account per type.
-          account = accounts[0];
-          try {
-            if (accountPrefs == null) {
-              accountPrefs = SyncAccounts.blockingPrefsFromDefaultProfileV0(mContext, mAccountManager, account);
-            }
-          } catch (Exception e) {
-            Logger.error(LOG_TAG, "Failed to get sync account info or shared preferences.", e);
-            finish();
-          }
-          setSelectionsInArray(getEnginesToSelect(accountPrefs), _selections);
-        }
-      }
-    });
-  }
-
-  @Override
-  public void onResume() {
-    super.onResume();
-    if (accountPrefs != null) {
-      setSelectionsInArray(getEnginesToSelect(accountPrefs), _selections);
-    }
-    AlertDialog dialog = new AlertDialog.Builder(this)
-        .setTitle(R.string.sync_configure_engines_sync_my_title)
-        .setMultiChoiceItems(_options, _selections, this)
-        .setIcon(R.drawable.icon).setPositiveButton(android.R.string.ok, this)
-        .setNegativeButton(android.R.string.cancel, this).create();
-
-    dialog.setOnDismissListener(new OnDismissListener() {
-      @Override
-      public void onDismiss(DialogInterface dialog) {
-        finish();
-      }
-    });
-
-    dialog.show();
-  }
-
-  private static Set<String> getEnginesFromPrefs(SharedPreferences syncPrefs) {
-    Set<String> engines = SyncConfiguration.getEnabledEngineNames(syncPrefs);
-    if (engines == null) {
-      engines = SyncConfiguration.validEngineNames();
-    }
-    return engines;
-  }
-
-  /**
-   * Fetches the engine names that should be displayed as selected for syncing.
-   * Check first for selected engines set by this activity, then the enabled
-   * engines, and finally default to the set of valid engine names for Android
-   * Sync if neither exists.
-   *
-   * @param syncPrefs
-   *          <code>SharedPreferences</code> of Account being modified.
-   * @return Set<String> of engine names to display as selected. Should never be
-   *         null.
-   */
-  public static Set<String> getEnginesToSelect(SharedPreferences syncPrefs) {
-    Set<String> engines = getEnginesFromPrefs(syncPrefs);
-    Map<String, Boolean> engineSelections = SyncConfiguration.getUserSelectedEngines(syncPrefs);
-    if (engineSelections != null) {
-      for (Entry<String, Boolean> pair : engineSelections.entrySet()) {
-        if (pair.getValue()) {
-          engines.add(pair.getKey());
-        } else {
-          engines.remove(pair.getKey());
-        }
-      }
-    }
-    return engines;
-  }
-
-  public void setSelectionsInArray(Set<String> selected, boolean[] array) {
-    for (int i = 0; i < _collectionsNames.length; i++) {
-      array[i] = selected.contains(_collectionsNames[i]);
-    }
-  }
-
-  @Override
-  public void onClick(DialogInterface dialog, int which) {
-    if (which == DialogInterface.BUTTON_POSITIVE) {
-      Logger.debug(LOG_TAG, "Saving selected engines.");
-      saveSelections();
-      setResult(RESULT_OK);
-      Toast.makeText(this, R.string.sync_notification_savedprefs, Toast.LENGTH_SHORT).show();
-    } else {
-      setResult(RESULT_CANCELED);
-    }
-    finish();
-  }
-
-  @Override
-  public void onClick(DialogInterface dialog, int which, boolean isChecked) {
-    // Display multi-selection clicks in UI.
-    _selections[which] = isChecked;
-    ListView selectionsList = ((AlertDialog) dialog).getListView();
-    selectionsList.setItemChecked(which, isChecked);
-  }
-
-  /**
-   * Persists engine selection state to SharedPreferences if it has changed.
-   *
-   * @return true if changed, false otherwise.
-   */
-  private void saveSelections() {
-    boolean[] origSelections = new boolean[_options.length];
-    setSelectionsInArray(getEnginesFromPrefs(accountPrefs), origSelections);
-
-    Map<String, Boolean> engineSelections = new HashMap<String, Boolean>();
-    for (int i = 0; i < _selections.length; i++) {
-      if (_selections[i] != origSelections[i]) {
-        engineSelections.put(_collectionsNames[i], _selections[i]);
-      }
-    }
-
-    // No GlobalSession.config, so store directly to prefs.
-    SyncConfiguration.storeSelectedEnginesToPrefs(accountPrefs, engineSelections);
-
-    // Request immediate sync.
-    SyncAdapter.requestImmediateSync(account, null);
-  }
-}
deleted file mode 100644
--- a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/jpake/BigIntegerHelper.java
+++ /dev/null
@@ -1,44 +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.sync.jpake;
-
-import java.math.BigInteger;
-
-public class BigIntegerHelper {
-
-  public static byte[] BigIntegerToByteArrayWithoutSign(BigInteger value) {
-    byte[] bytes = value.toByteArray();
-    if (bytes[0] == (byte) 0) {
-      bytes = copyArray(bytes, 1, bytes.length - 1);
-    }
-    return bytes;
-  }
-
-  private static byte[] copyArray(byte[] original, int start, int length) {
-    byte[] copy = new byte[length];
-    System.arraycopy(original, start, copy, 0,
-        Math.min(original.length - start, length));
-    return copy;
-  }
-
-  /**
-   * Convert an array of bytes to a non-negative big integer.
-   */
-  public static BigInteger ByteArrayToBigIntegerWithoutSign(byte[] array) {
-    return new BigInteger(1, array);
-  }
-
-  /**
-   * Convert a big integer into hex string. If the length is not even, add an
-   * '0' character in the beginning to make it even.
-   */
-  public static String toEvenLengthHex(BigInteger value) {
-    String result = value.toString(16);
-    if (result.length() % 2 != 0) {
-      result = "0" + result;
-    }
-    return result;
-  }
-}
deleted file mode 100644
--- a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/jpake/Gx3OrGx4IsZeroOrOneException.java
+++ /dev/null
@@ -1,9 +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.sync.jpake;
-
-public class Gx3OrGx4IsZeroOrOneException extends Exception {
-  private static final long serialVersionUID = 7347530447460039679L;
-}
deleted file mode 100644
--- a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/jpake/IncorrectZkpException.java
+++ /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/. */
-
-package org.mozilla.gecko.sync.jpake;
-
-public class IncorrectZkpException extends Exception {
-
-  /**
-   * Exception thrown when Zero Knowledge Proof does not compute correctly.
-   **/
-  private static final long serialVersionUID = -3289260904620418313L;
-
-}
deleted file mode 100644
--- a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/jpake/JPakeClient.java
+++ /dev/null
@@ -1,433 +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.sync.jpake;
-
-import java.io.UnsupportedEncodingException;
-import java.math.BigInteger;
-import java.util.LinkedList;
-import java.util.Queue;
-
-import org.json.simple.JSONObject;
-import org.mozilla.apache.commons.codec.binary.Base64;
-import org.mozilla.gecko.background.common.log.Logger;
-import org.mozilla.gecko.sync.ExtendedJSONObject;
-import org.mozilla.gecko.sync.ThreadPool;
-import org.mozilla.gecko.sync.Utils;
-import org.mozilla.gecko.sync.crypto.CryptoException;
-import org.mozilla.gecko.sync.crypto.CryptoInfo;
-import org.mozilla.gecko.sync.crypto.KeyBundle;
-import org.mozilla.gecko.sync.crypto.NoKeyBundleException;
-import org.mozilla.gecko.sync.jpake.stage.CompleteStage;
-import org.mozilla.gecko.sync.jpake.stage.ComputeFinalStage;
-import org.mozilla.gecko.sync.jpake.stage.ComputeKeyVerificationStage;
-import org.mozilla.gecko.sync.jpake.stage.ComputeStepOneStage;
-import org.mozilla.gecko.sync.jpake.stage.ComputeStepTwoStage;
-import org.mozilla.gecko.sync.jpake.stage.DecryptDataStage;
-import org.mozilla.gecko.sync.jpake.stage.DeleteChannel;
-import org.mozilla.gecko.sync.jpake.stage.GetChannelStage;
-import org.mozilla.gecko.sync.jpake.stage.GetRequestStage;
-import org.mozilla.gecko.sync.jpake.stage.JPakeStage;
-import org.mozilla.gecko.sync.jpake.stage.PutRequestStage;
-import org.mozilla.gecko.sync.jpake.stage.VerifyPairingStage;
-import org.mozilla.gecko.sync.setup.Constants;
-import org.mozilla.gecko.sync.setup.activities.SetupSyncActivity;
-
-import ch.boye.httpclientandroidlib.entity.StringEntity;
-
-public class JPakeClient {
-
-  private static final String LOG_TAG = "JPakeClient";
-
-  // J-PAKE constants.
-  public static final int REQUEST_TIMEOUT = 60 * 1000;       // 1 min
-  public static final int KEYEXCHANGE_VERSION = 3;
-  public static final String JPAKE_VERIFY_VALUE = "0123456789ABCDEF";
-
-  private static final String JPAKE_SIGNERID_SENDER = "sender";
-  private static final String JPAKE_SIGNERID_RECEIVER = "receiver";
-  private static final int JPAKE_LENGTH_SECRET = 8;
-  private static final int JPAKE_LENGTH_CLIENTID = 256;
-
-  private static final int MAX_TRIES = 10;
-  private static final int MAX_TRIES_FIRST_MSG = 300;
-  private static final int MAX_TRIES_LAST_MSG = 300;
-
-  // J-PAKE session values.
-  public String clientId;
-  public String secret;
-
-  public String myEtag;
-  public String mySignerId;
-  public String theirEtag;
-  public String theirSignerId;
-  public String jpakeServer;
-
-  // J-PAKE state.
-  public boolean paired;
-  public boolean finished;
-
-  // J-PAKE values.
-  public final int jpakePollInterval;
-  public int jpakeMaxTries;
-  public String channel;
-  public volatile String channelUrl;
-
-  // J-PAKE session data.
-  public KeyBundle myKeyBundle;
-  public JSONObject jCreds;
-
-  public ExtendedJSONObject jOutgoing;
-  public ExtendedJSONObject jIncoming;
-
-  public JPakeParty jParty;
-  public final JPakeNumGenerator numGen;
-
-  public int pollTries;
-
-  // UI controller.
-  private final SetupSyncActivity controllerActivity;
-  private Queue<JPakeStage> stages;
-
-  public JPakeClient(SetupSyncActivity activity) {
-    controllerActivity = activity;
-    jpakeServer = "https://setup.services.mozilla.com/";
-    jpakePollInterval = 1 * 1000; // 1 second
-    jpakeMaxTries = MAX_TRIES;
-
-    if (!jpakeServer.endsWith("/")) {
-      jpakeServer += "/";
-    }
-
-    setClientId();
-    numGen = new JPakeNumGeneratorRandom();
-  }
-
-  /**
-   * Set up Sender sequence of stages for J-PAKE. (sender of credentials)
-   *
-   */
-
-  private void prepareSenderStages() {
-    Queue<JPakeStage> jStages = new LinkedList<JPakeStage>();
-    jStages.add(new ComputeStepOneStage());
-    jStages.add(new GetRequestStage());
-    jStages.add(new PutRequestStage());
-    jStages.add(new ComputeStepTwoStage());
-    jStages.add(new GetRequestStage());
-    jStages.add(new PutRequestStage());
-    jStages.add(new ComputeFinalStage());
-    jStages.add(new GetRequestStage());
-    jStages.add(new VerifyPairingStage()); // Calls onPaired if verified.
-
-    stages = jStages;
-  }
-
-  /**
-   * Set up Receiver sequence of stages for J-PAKE. (receiver of credentials)
-   *
-   */
-  private void prepareReceiverStages() {
-    Queue<JPakeStage> jStages = new LinkedList<JPakeStage>();
-    jStages.add(new GetChannelStage());
-    jStages.add(new ComputeStepOneStage());
-    jStages.add(new PutRequestStage());
-    jStages.add(new GetRequestStage());
-    jStages.add(new JPakeStage() {
-      @Override
-      public void execute(JPakeClient jpakeClient) {
-
-        // Notify controller that pairing has started.
-        jpakeClient.onPairingStart();
-
-        // Switch back to smaller time-out.
-        jpakeClient.jpakeMaxTries = JPakeClient.MAX_TRIES;
-        jpakeClient.runNextStage();
-      }
-    });
-    jStages.add(new ComputeStepTwoStage());
-    jStages.add(new PutRequestStage());
-    jStages.add(new GetRequestStage());
-    jStages.add(new ComputeFinalStage());
-    jStages.add(new ComputeKeyVerificationStage());
-    jStages.add(new PutRequestStage());
-    jStages.add(new JPakeStage() {
-
-      @Override
-      public void execute(JPakeClient jpakeClient) {
-        jpakeMaxTries = MAX_TRIES_LAST_MSG;
-        jpakeClient.runNextStage();
-      }
-
-    });
-    jStages.add(new GetRequestStage());
-    jStages.add(new DecryptDataStage());
-    jStages.add(new CompleteStage());
-
-    stages = jStages;
-  }
-
-  /**
-   *
-   * Pairing using PIN provided on other device. Functionality available only
-   * when a Sync account has already been set up.
-   *
-   * @param pin
-   *          12-character string containing PIN entered by the user.
-   */
-  public void pairWithPin(String pin) {
-    mySignerId = JPAKE_SIGNERID_SENDER;
-    theirSignerId = JPAKE_SIGNERID_RECEIVER;
-    jParty = new JPakeParty(mySignerId);
-
-    // Extract secret and server channel.
-    secret = pin.substring(0, JPAKE_LENGTH_SECRET);
-    channel = pin.substring(JPAKE_LENGTH_SECRET);
-    channelUrl = jpakeServer + channel;
-
-    prepareSenderStages();
-    runNextStage();
-  }
-
-  /**
-   *
-   * Initiate pairing and receive data, without having received a PIN. The PIN
-   * will be generated and passed on to the controller to be displayed to the
-   * user.
-   *
-   * Starts J-PAKE protocol.
-   */
-  public void receiveNoPin() {
-    mySignerId = JPAKE_SIGNERID_RECEIVER;
-    theirSignerId = JPAKE_SIGNERID_SENDER;
-    jParty = new JPakeParty(mySignerId);
-
-    // TODO: fetch from prefs
-    jpakeMaxTries = MAX_TRIES_FIRST_MSG;
-
-    createSecret();
-    prepareReceiverStages();
-    runNextStage();
-  }
-
-  /**
-   * Run next stage of J-PAKE.
-   */
-  public void runNextStage() {
-    if (finished || stages.size() == 0) {
-      Logger.debug(LOG_TAG, "All stages complete.");
-      return;
-    }
-    JPakeStage currentStage = null;
-    try{
-      currentStage = stages.remove();
-      Logger.debug(LOG_TAG, "starting stage " + currentStage.toString());
-      currentStage.execute(this);
-    } catch (Exception e) {
-      Logger.error(LOG_TAG, "Exception in stage " + currentStage, e);
-      abort("Stage exception.");
-    }
-  }
-
-  /**
-   * Abort J-PAKE. This can propagate an error from the stages, or result from
-   * UI abort (onPause, user abort)
-   *
-   * @param reason
-   *          Reason for abort.
-   */
-  public void abort(String reason) {
-    finished = true;
-    // We do not need to clean up the channel in the following cases:
-    if (Constants.JPAKE_ERROR_CHANNEL.equals(reason) ||
-        Constants.JPAKE_ERROR_NETWORK.equals(reason) ||
-        Constants.JPAKE_ERROR_NODATA.equals(reason) ||
-        channelUrl == null) {
-      // We may leak a channel if the activity aborts sync while requesting the channel.
-      // The server, however, will delete the channel anyways after a certain time has passed.
-      displayAbort(reason);
-    } else {
-      // Delete channel, then call controller's displayAbort in callback.
-      new DeleteChannel().execute(this, reason);
-    }
-  }
-
-  public void displayAbort(String reason) {
-    controllerActivity.displayAbort(reason);
-  }
-
-  /* Static helper methods used by stages. */
-
-  /**
-   * Run on a different thread from the thread pool.
-   *
-   * @param run
-   *            Runnable to run on separate thread.
-   */
-  public static void runOnThread(Runnable run) {
-    ThreadPool.run(run);
-  }
-
-  /**
-   *
-   * @param secretString
-   *          String to convert to BigInteger
-   * @return BigInteger representation of secretString
-   *
-   * @throws UnsupportedEncodingException
-   */
-  public static BigInteger secretAsBigInteger(String secretString) throws UnsupportedEncodingException {
-    return new BigInteger(secretString.getBytes("UTF-8"));
-  }
-
-  /**
-   * Helper method for doing actual encryption.
-   *
-   * Input: String of JSONObject KeyBundle with keys for encryption
-   *
-   * Output: ExtendedJSONObject with IV, ciphertext, hmac (if sender)
-   *
-   * @throws CryptoException
-   * @throws UnsupportedEncodingException
-   */
-  public static ExtendedJSONObject encryptPayload(String data, KeyBundle keyBundle, boolean makeHmac)
-      throws UnsupportedEncodingException, CryptoException {
-    if (keyBundle == null) {
-      throw new NoKeyBundleException();
-    }
-
-    byte[] cleartextBytes = data.getBytes("UTF-8");
-    CryptoInfo encrypted = CryptoInfo.encrypt(cleartextBytes, keyBundle);
-
-    ExtendedJSONObject payload = new ExtendedJSONObject();
-
-    String message64 = new String(Base64.encodeBase64(encrypted.getMessage()));
-    String iv64 = new String(Base64.encodeBase64(encrypted.getIV()));
-
-    payload.put(Constants.JSON_KEY_CIPHERTEXT, message64);
-    payload.put(Constants.JSON_KEY_IV, iv64);
-    if (makeHmac) {
-      String hmacHex = Utils.byte2Hex(encrypted.getHMAC());
-      payload.put(Constants.JSON_KEY_HMAC, hmacHex);
-    }
-    return payload;
-  }
-
-  /*
-   * Helper for turning a JSON object into a payload.
-   *
-   * @param body JSONObject body to be converted to StringEntity.
-   * @return StringEntity representation of JSONObject.
-   *
-   * @throws UnsupportedEncodingException
-   */
-  public static StringEntity jsonEntity(JSONObject body)
-      throws UnsupportedEncodingException {
-    StringEntity entity = new StringEntity(body.toJSONString(), "UTF-8");
-    entity.setContentType("application/json");
-    return entity;
-  }
-
-  /*
-   * Controller methods.
-   */
-  public void makeAndDisplayPin(String channel) {
-    controllerActivity.displayPin(secret + channel);
-  }
-
-  public void onPairingStart() {
-    Logger.debug(LOG_TAG, "Pairing started.");
-    controllerActivity.onPairingStart();
-  }
-
-  public void onPaired() {
-    Logger.debug(LOG_TAG, "Pairing completed. Starting credential exchange.");
-    controllerActivity.onPaired();
-  }
-
-  public void complete(JSONObject credentials) {
-    controllerActivity.onComplete(credentials);
-  }
-
-  /*
-   * Called from controller, with Sync credentials to be encrypted and sent.
-   */
-  public void sendAndComplete(JSONObject jObj)
-      throws JPakeNoActivePairingException {
-    if (!paired || finished) {
-      Logger.error(LOG_TAG, "Can't send data, no active pairing!");
-      throw new JPakeNoActivePairingException();
-    }
-    stages.clear();
-    stages.add(new PutRequestStage());
-    stages.add(new CompleteStage());
-
-    // Encrypt data to send and set as jOutgoing.
-    String outData = jObj.toJSONString();
-    encryptData(myKeyBundle, outData);
-
-    // Start stages for sending credentials.
-    runNextStage();
-  }
-
-  /* Setup helper functions */
-
-  /*
-   * Generates and sets a clientId for communications with JPAKE setup server.
-   */
-  private void setClientId() {
-    byte[] rBytes = Utils.generateRandomBytes(JPAKE_LENGTH_CLIENTID / 2);
-    StringBuilder id = new StringBuilder();
-
-    for (byte b : rBytes) {
-      String hexString = Integer.toHexString(b);
-      if (hexString.length() == 1) {
-        hexString = "0" + hexString;
-      }
-      int len = hexString.length();
-      id.append(hexString.substring(len - 2, len));
-    }
-    clientId = id.toString();
-  }
-
-  /*
-   * Generates and sets a JPAKE PIN to be displayed to user.
-   */
-  private void createSecret() {
-    // 0-9a-z without 1,l,o,0
-    String key = "23456789abcdefghijkmnpqrstuvwxyz";
-    int keylen = key.length();
-
-    byte[] rBytes = Utils.generateRandomBytes(JPAKE_LENGTH_SECRET);
-    StringBuilder secret = new StringBuilder();
-    for (byte b : rBytes) {
-      secret.append(key.charAt(Math.abs(b) * keylen / 256));
-    }
-    this.secret = secret.toString();
-  }
-
-  /*
-   *
-   * Encrypt payload and package into jOutgoing for sending with a PUT request.
-   *
-   * @param keyBundle Encryption keys derived during J-PAKE.
-   *
-   * @param payload Credentials data to be encrypted.
-   */
-  private void encryptData(KeyBundle keyBundle, String payload) {
-    Logger.debug(LOG_TAG, "Encrypting data.");
-    ExtendedJSONObject jPayload = null;
-    try {
-      jPayload = encryptPayload(payload, keyBundle, true);
-    } catch (UnsupportedEncodingException | CryptoException e) {
-      Logger.error(LOG_TAG, "Failed to encrypt data.", e);
-      abort(Constants.JPAKE_ERROR_INTERNAL);
-      return;
-    }
-    jOutgoing = new ExtendedJSONObject();
-    jOutgoing.put(Constants.JSON_KEY_TYPE, mySignerId + "3");
-    jOutgoing.put(Constants.JSON_KEY_VERSION, KEYEXCHANGE_VERSION);
-    jOutgoing.put(Constants.JSON_KEY_PAYLOAD, jPayload.object);
-  }
-}
deleted file mode 100644
--- a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/jpake/JPakeCrypto.java
+++ /dev/null
@@ -1,264 +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.sync.jpake;
-
-import java.io.UnsupportedEncodingException;
-import java.math.BigInteger;
-import java.security.GeneralSecurityException;
-import java.security.InvalidKeyException;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-
-import javax.crypto.Mac;
-import javax.crypto.spec.SecretKeySpec;
-
-import org.mozilla.gecko.background.common.log.Logger;
-import org.mozilla.gecko.sync.crypto.HKDF;
-import org.mozilla.gecko.sync.crypto.KeyBundle;
-
-public class JPakeCrypto {
-  private static final String LOG_TAG = "JPakeCrypto";
-
-  /*
-   * Primes P and Q, and generator G - from original Mozilla J-PAKE
-   * implementation.
-   */
-  public static final BigInteger P = new BigInteger(
-      "90066455B5CFC38F9CAA4A48B4281F292C260FEEF01FD61037E56258A7795A1C" +
-      "7AD46076982CE6BB956936C6AB4DCFE05E6784586940CA544B9B2140E1EB523F" +
-      "009D20A7E7880E4E5BFA690F1B9004A27811CD9904AF70420EEFD6EA11EF7DA1" +
-      "29F58835FF56B89FAA637BC9AC2EFAAB903402229F491D8D3485261CD068699B" +
-      "6BA58A1DDBBEF6DB51E8FE34E8A78E542D7BA351C21EA8D8F1D29F5D5D159394" +
-      "87E27F4416B0CA632C59EFD1B1EB66511A5A0FBF615B766C5862D0BD8A3FE7A0" +
-      "E0DA0FB2FE1FCB19E8F9996A8EA0FCCDE538175238FC8B0EE6F29AF7F642773E" +
-      "BE8CD5402415A01451A840476B2FCEB0E388D30D4B376C37FE401C2A2C2F941D" +
-      "AD179C540C1C8CE030D460C4D983BE9AB0B20F69144C1AE13F9383EA1C08504F" +
-      "B0BF321503EFE43488310DD8DC77EC5B8349B8BFE97C2C560EA878DE87C11E3D" +
-      "597F1FEA742D73EEC7F37BE43949EF1A0D15C3F3E3FC0A8335617055AC91328E" +
-      "C22B50FC15B941D3D1624CD88BC25F3E941FDDC6200689581BFEC416B4B2CB73",
-      16);
-
-  public static final BigInteger Q = new BigInteger(
-      "CFA0478A54717B08CE64805B76E5B14249A77A4838469DF7F7DC987EFCCFB11D",
-      16);
-
-  public static final BigInteger G = new BigInteger(
-      "5E5CBA992E0A680D885EB903AEA78E4A45A469103D448EDE3B7ACCC54D521E37" +
-      "F84A4BDD5B06B0970CC2D2BBB715F7B82846F9A0C393914C792E6A923E2117AB" +
-      "805276A975AADB5261D91673EA9AAFFEECBFA6183DFCB5D3B7332AA19275AFA1" +
-      "F8EC0B60FB6F66CC23AE4870791D5982AAD1AA9485FD8F4A60126FEB2CF05DB8" +
-      "A7F0F09B3397F3937F2E90B9E5B9C9B6EFEF642BC48351C46FB171B9BFA9EF17" +
-      "A961CE96C7E7A7CC3D3D03DFAD1078BA21DA425198F07D2481622BCE45969D9C" +
-      "4D6063D72AB7A0F08B2F49A7CC6AF335E08C4720E31476B67299E231F8BD90B3" +
-      "9AC3AE3BE0C6B6CACEF8289A2E2873D58E51E029CAFBD55E6841489AB66B5B4B" +
-      "9BA6E2F784660896AFF387D92844CCB8B69475496DE19DA2E58259B090489AC8" +
-      "E62363CDF82CFD8EF2A427ABCD65750B506F56DDE3B988567A88126B914D7828" +
-      "E2B63A6D7ED0747EC59E0E0A23CE7D8A74C1D2C2A7AFB6A29799620F00E11C33" +
-      "787F7DED3B30E1A22D09F1FBDA1ABBBFBF25CAE05A13F812E34563F99410E73B",
-      16);
-
-  /**
-   *
-   * Round 1 of J-PAKE protocol.
-   * Generate x1, x2, and ZKP for other party.
-   */
-  public static void round1(JPakeParty jp, JPakeNumGenerator gen) throws NoSuchAlgorithmException, UnsupportedEncodingException {
-    // Randomly select x1 from [0,q), x2 from [1,q).
-    BigInteger x1 = gen.generateFromRange(Q); // [0, q)
-    BigInteger x2 = jp.x2 = BigInteger.ONE.add(gen.generateFromRange(Q
-        .subtract(BigInteger.ONE))); // [1, q)
-
-    BigInteger gx1 = G.modPow(x1, P);
-    BigInteger gx2 = G.modPow(x2, P);
-
-    jp.gx1 = gx1;
-    jp.gx2 = gx2;
-
-    // Generate and store zero knowledge proofs.
-    jp.zkp1 = createZkp(G, x1, gx1, jp.signerId, gen);
-    jp.zkp2 = createZkp(G, x2, gx2, jp.signerId, gen);
-  }
-
-  /**
-   * Round 2 of J-PAKE protocol.
-   * Generate A and ZKP for A.
-   * Verify ZKP from other party. Does not check for replay ZKP.
-   */
-  public static void round2(BigInteger secretValue, JPakeParty jp, JPakeNumGenerator gen)
-      throws IncorrectZkpException, NoSuchAlgorithmException,
-      Gx3OrGx4IsZeroOrOneException, UnsupportedEncodingException {
-
-    Logger.debug(LOG_TAG, "round2 started.");
-
-    // checkZkp does some additional checks, but we can throw a more informative exception here.
-    if (BigInteger.ZERO.compareTo(jp.gx3) == 0 || BigInteger.ONE.compareTo(jp.gx3) == 0 ||
-        BigInteger.ZERO.compareTo(jp.gx4) == 0 || BigInteger.ONE.compareTo(jp.gx4) == 0) {
-      throw new Gx3OrGx4IsZeroOrOneException();
-    }
-
-    // Check ZKP.
-    checkZkp(G, jp.gx3, jp.zkp3);
-    checkZkp(G, jp.gx4, jp.zkp4);
-
-    // Compute a = g^[(x1+x3+x4)*(x2*secret)].
-    BigInteger y1 = jp.gx3.multiply(jp.gx4).mod(P).multiply(jp.gx1).mod(P);
-    BigInteger y2 = jp.x2.multiply(secretValue).mod(P);
-
-    BigInteger a  = y1.modPow(y2, P);
-    jp.thisZkpA = createZkp(y1, y2, a, jp.signerId, gen);
-    jp.thisA = a;
-
-    Logger.debug(LOG_TAG, "round2 finished.");
-  }
-
-  /**
-   * Final round of J-PAKE protocol.
-   */
-  public static KeyBundle finalRound(BigInteger secretValue, JPakeParty jp)
-      throws IncorrectZkpException, NoSuchAlgorithmException, InvalidKeyException, UnsupportedEncodingException {
-    Logger.debug(LOG_TAG, "Final round started.");
-    BigInteger gb = jp.gx1.multiply(jp.gx2).mod(P).multiply(jp.gx3)
-        .mod(P);
-    checkZkp(gb, jp.otherA, jp.otherZkpA);
-
-    // Calculate shared key g^(x1+x3)*x2*x4*secret, which is equivalent to
-    // (B/g^(x2*x4*s))^x2 = (B*(g^x4)^x2^s^-1)^2.
-    BigInteger k = jp.gx4.modPow(jp.x2.multiply(secretValue).negate().mod(Q), P).multiply(jp.otherA)
-        .modPow(jp.x2, P);
-
-    byte[] enc = new byte[32];
-    byte[] hmac = new byte[32];
-    generateKeyAndHmac(k, enc, hmac);
-
-    Logger.debug(LOG_TAG, "Final round finished; returning key.");
-    return new KeyBundle(enc, hmac);
-  }
-
-  // TODO Replace this function with the one in the  crypto library
-  private static byte[] HMACSHA256(byte[] data, byte[] key) {
-    byte[] result = null;
-    try {
-      Mac hmacSha256;
-      hmacSha256 = Mac.getInstance("HmacSHA256");
-      SecretKeySpec secret_key = new SecretKeySpec(key, "HmacSHA256");
-      hmacSha256.init(secret_key);
-      result = hmacSha256.doFinal(data);
-    } catch (GeneralSecurityException e) {
-      Logger.error(LOG_TAG, "Got exception calculating HMAC.", e);
-    }
-    return result;
-  }
-
-  /* Helper Methods */
-
-  /*
-   * Generate the ZKP b = r - x*h, and g^r, where h = hash(g, g^r, g^x, id). (We
-   * pass in gx to save on an exponentiation of g^x)
-   */
-  private static Zkp createZkp(BigInteger g, BigInteger x, BigInteger gx,
-      String id, JPakeNumGenerator gen) throws NoSuchAlgorithmException, UnsupportedEncodingException {
-    // Generate random r for exponent.
-    BigInteger r = gen.generateFromRange(Q);
-
-    // Calculate g^r for ZKP.
-    BigInteger gr = g.modPow(r, P);
-
-    // Calculate the ZKP b value = (r-x*h) % q.
-    BigInteger h = computeBHash(g, gr, gx, id);
-    Logger.debug(LOG_TAG, "myhash: " + h.toString(16));
-
-    // ZKP value = b = r-x*h
-    BigInteger b = r.subtract(x.multiply(h)).mod(Q);
-
-    return new Zkp(gr, b, id);
-  }
-
-  /*
-   * Verify ZKP.
-   */
-  private static void checkZkp(BigInteger g, BigInteger gx, Zkp zkp)
-      throws IncorrectZkpException, NoSuchAlgorithmException, UnsupportedEncodingException {
-
-    BigInteger h = computeBHash(g, zkp.gr, gx, zkp.id);
-
-    // Check parameters of zkp, and compare to computed hash. These shouldn't
-    // fail.
-    if (gx.compareTo(BigInteger.ONE) < 1) { // g^x > 1.
-      Logger.error(LOG_TAG, "g^x > 1 fails.");
-      throw new IncorrectZkpException();
-    }
-    if (gx.compareTo(P.subtract(BigInteger.ONE)) > -1) { // g^x < p-1
-      Logger.error(LOG_TAG, "g^x < p-1 fails.");
-      throw new IncorrectZkpException();
-    }
-    if (gx.modPow(Q, P).compareTo(BigInteger.ONE) != 0) {
-      Logger.error(LOG_TAG, "g^x^q % p = 1 fails.");
-      throw new IncorrectZkpException();
-    }
-    if (zkp.gr.compareTo(g.modPow(zkp.b, P).multiply(gx.modPow(h, P)).mod(P)) != 0) {
-      // b = r-h*x ==> g^r = g^b*g^x^(h)
-      Logger.debug(LOG_TAG, "gb*g(xh) = " + g.modPow(zkp.b, P).multiply(gx.modPow(h, P)).mod(P).toString(16));
-      Logger.debug(LOG_TAG, "gr = " + zkp.gr.toString(16));
-      Logger.debug(LOG_TAG, "b = " + zkp.b.toString(16));
-      Logger.debug(LOG_TAG, "g^b = " + g.modPow(zkp.b, P).toString(16));
-      Logger.debug(LOG_TAG, "g^(xh) = " + gx.modPow(h, P).toString(16));
-      Logger.debug(LOG_TAG, "gx = " + gx.toString(16));
-      Logger.debug(LOG_TAG, "h = " + h.toString(16));
-      Logger.error(LOG_TAG, "zkp calculation incorrect.");
-      throw new IncorrectZkpException();
-    }
-    Logger.debug(LOG_TAG, "*** ZKP SUCCESS ***");
-  }
-
-  /*
-   * Use SHA-256 to compute a BigInteger hash of g, gr, gx values with
-   * mySignerId to prevent replay. Does not make a twos-complement BigInteger
-   * form hash.
-   */
-  private static BigInteger computeBHash(BigInteger g, BigInteger gr, BigInteger gx,
-      String id) throws NoSuchAlgorithmException, UnsupportedEncodingException {
-    MessageDigest sha = MessageDigest.getInstance("SHA-256");
-    sha.reset();
-
-    /*
-     * Note: you should ensure the items in H(...) have clear boundaries. It
-     * is simple if the other party knows sizes of g, gr, gx and signerID and
-     * hence the boundary is unambiguous. If not, you'd better prepend each
-     * item with its byte length, but I've omitted that here.
-     */
-
-    hashByteArrayWithLength(sha, BigIntegerHelper.BigIntegerToByteArrayWithoutSign(g));
-    hashByteArrayWithLength(sha, BigIntegerHelper.BigIntegerToByteArrayWithoutSign(gr));
-    hashByteArrayWithLength(sha, BigIntegerHelper.BigIntegerToByteArrayWithoutSign(gx));
-    hashByteArrayWithLength(sha, id.getBytes("UTF-8"));
-
-    byte[] hash = sha.digest();
-
-    return BigIntegerHelper.ByteArrayToBigIntegerWithoutSign(hash);
-  }
-
-  /*
-   * Update a hash with a byte array's length and the byte array.
-   */
-  private static void hashByteArrayWithLength(MessageDigest sha, byte[] data) {
-    int length = data.length;
-    byte[] b = new byte[] { (byte) (length >>> 8), (byte) (length & 0xff) };
-    sha.update(b);
-    sha.update(data);
-  }
-
-  /*
-   * Helper function to generate encryption key and HMAC from a byte array.
-   */
-  public static void generateKeyAndHmac(BigInteger k, byte[] encOut, byte[] hmacOut) throws NoSuchAlgorithmException, InvalidKeyException {
-   // Generate HMAC and Encryption keys from synckey.
-    byte[] zerokey = new byte[32];
-    byte[] prk = HMACSHA256(BigIntegerHelper.BigIntegerToByteArrayWithoutSign(k), zerokey);
-
-    byte[] okm = HKDF.hkdfExpand(prk, HKDF.HMAC_INPUT, 32 * 2);
-    System.arraycopy(okm, 0, encOut, 0, 32);
-    System.arraycopy(okm, 32, hmacOut, 0, 32);
-  }
-}
deleted file mode 100644
--- a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/jpake/JPakeJson.java
+++ /dev/null
@@ -1,23 +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.sync.jpake;
-
-import java.math.BigInteger;
-
-import org.mozilla.gecko.sync.ExtendedJSONObject;
-import org.mozilla.gecko.sync.setup.Constants;
-
-public class JPakeJson {
-  /*
-   * Helper function to generate a JSON-encoded ZKP.
-   */
-  public static ExtendedJSONObject makeJZkp(BigInteger gr, BigInteger b, String id) {
-    ExtendedJSONObject result = new ExtendedJSONObject();
-    result.put(Constants.ZKP_KEY_GR, BigIntegerHelper.toEvenLengthHex(gr));
-    result.put(Constants.ZKP_KEY_B, BigIntegerHelper.toEvenLengthHex(b));
-    result.put(Constants.ZKP_KEY_ID, id);
-    return result;
-  }
-}
deleted file mode 100644
--- a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/jpake/JPakeNoActivePairingException.java
+++ /dev/null
@@ -1,11 +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.sync.jpake;
-
-import org.mozilla.gecko.sync.SyncException;
-
-public class JPakeNoActivePairingException extends SyncException {
-  private static final long serialVersionUID = 715366241252256473L;
-}
deleted file mode 100644
--- a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/jpake/JPakeNumGenerator.java
+++ /dev/null
@@ -1,11 +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.sync.jpake;
-
-import java.math.BigInteger;
-
-public interface JPakeNumGenerator {
-  public BigInteger generateFromRange(BigInteger r);
-}
deleted file mode 100644
--- a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/jpake/JPakeNumGeneratorRandom.java
+++ /dev/null
@@ -1,20 +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.sync.jpake;
-
-import java.math.BigInteger;
-
-import org.mozilla.gecko.sync.Utils;
-
-/**
- * Helper Function to generate a uniformly random value in [0, r).
- */
-public class JPakeNumGeneratorRandom implements JPakeNumGenerator {
-
-  @Override
-  public BigInteger generateFromRange(BigInteger r) {
-    return Utils.generateBigIntegerLessThan(r);
-  }
-}
deleted file mode 100644
--- a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/jpake/JPakeParty.java
+++ /dev/null
@@ -1,37 +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.sync.jpake;
-
-import java.math.BigInteger;
-
-public class JPakeParty {
-
-  // Generated values for key exchange.
-  public String       signerId;
-  public BigInteger   gx1;
-  public Zkp          zkp1;
-
-  public BigInteger   x2;
-  public BigInteger   gx2;
-  public Zkp          zkp2;
-
-  public BigInteger   thisA;
-  public Zkp          thisZkpA;
-
-  // Received values during key exchange.
-  public BigInteger   gx3;
-  public Zkp          zkp3;
-
-  public BigInteger   gx4;
-  public Zkp          zkp4;
-
-  public BigInteger   otherA;
-  public Zkp          otherZkpA;
-
-
-  public JPakeParty(String mySignerId) {
-    this.signerId = mySignerId;
-  }
-}
deleted file mode 100644
--- a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/jpake/Zkp.java
+++ /dev/null
@@ -1,19 +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.sync.jpake;
-
-import java.math.BigInteger;
-
-public class Zkp {
-  public BigInteger gr;
-  public BigInteger b;
-  public String id;
-
-  public Zkp(BigInteger gr, BigInteger b, String id) {
-    this.gr = gr;
-    this.b = b;
-    this.id = id;
-  }
-}
deleted file mode 100644
--- a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/jpake/stage/CompleteStage.java
+++ /dev/null
@@ -1,19 +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.sync.jpake.stage;
-
-import org.mozilla.gecko.background.common.log.Logger;
-import org.mozilla.gecko.sync.jpake.JPakeClient;
-
-public class CompleteStage extends JPakeStage {
-
-  @Override
-  public void execute(JPakeClient jClient) {
-    Logger.debug(LOG_TAG, "Exchange complete.");
-    jClient.finished = true;
-    jClient.complete(jClient.jCreds);
-    jClient.runNextStage();
-  }
-}
deleted file mode 100644
--- a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/jpake/stage/ComputeFinalStage.java
+++ /dev/null
@@ -1,94 +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.sync.jpake.stage;
-
-import java.io.UnsupportedEncodingException;
-import java.math.BigInteger;
-import java.security.InvalidKeyException;
-import java.security.NoSuchAlgorithmException;
-
-import org.mozilla.gecko.background.common.log.Logger;
-import org.mozilla.gecko.sync.ExtendedJSONObject;
-import org.mozilla.gecko.sync.NonObjectJSONException;
-import org.mozilla.gecko.sync.jpake.IncorrectZkpException;
-import org.mozilla.gecko.sync.jpake.JPakeClient;
-import org.mozilla.gecko.sync.jpake.JPakeCrypto;
-import org.mozilla.gecko.sync.jpake.Zkp;
-import org.mozilla.gecko.sync.setup.Constants;
-
-public class ComputeFinalStage extends JPakeStage {
-
-  @Override
-  public void execute(JPakeClient jClient) {
-    Logger.debug(LOG_TAG, "Computing final round.");
-
-    // Check incoming message type.
-    if (!jClient.jIncoming.get(Constants.JSON_KEY_TYPE).equals(jClient.theirSignerId + "2")) {
-      Logger.error(LOG_TAG, "Invalid round 2 message: " + jClient.jIncoming.toJSONString());
-      jClient.abort(Constants.JPAKE_ERROR_WRONGMESSAGE);
-      return;
-    }
-
-    // Check incoming message fields.
-    ExtendedJSONObject iPayload;
-    ExtendedJSONObject zkpPayload;
-    try {
-      iPayload = jClient.jIncoming.getObject(Constants.JSON_KEY_PAYLOAD);
-      if (iPayload == null
-          || iPayload.getObject(Constants.ZKP_KEY_ZKP_A) == null) {
-        Logger.error(LOG_TAG,
-            "Invalid round 2 message: " + jClient.jIncoming.toJSONString());
-        jClient.abort(Constants.JPAKE_ERROR_WRONGMESSAGE);
-        return;
-      }
-      zkpPayload = iPayload.getObject(Constants.ZKP_KEY_ZKP_A);
-    } catch (NonObjectJSONException e) {
-      Logger.error(LOG_TAG, "JSON object Exception.", e);
-      jClient.abort(Constants.JPAKE_ERROR_INVALID);
-      return;
-    }
-
-    if (!jClient.theirSignerId.equals(zkpPayload.get(Constants.ZKP_KEY_ID))) {
-      Logger.error(LOG_TAG, "Invalid round 2 message: " + jClient.jIncoming.toJSONString());
-      jClient.abort(Constants.JPAKE_ERROR_WRONGMESSAGE);
-      return;
-    }
-
-    // Extract fields.
-    jClient.jParty.otherA = new BigInteger((String) iPayload.get(Constants.ZKP_KEY_A), 16);
-
-    // Extract ZKP.
-    String gr = (String) zkpPayload.get(Constants.ZKP_KEY_GR);
-    String b  = (String) zkpPayload.get(Constants.ZKP_KEY_B);
-    String id = (String) zkpPayload.get(Constants.ZKP_KEY_ID);
-
-    jClient.jParty.otherZkpA = new Zkp(new BigInteger(gr, 16), new BigInteger(b, 16), id);
-
-    jClient.myKeyBundle = null;
-    try {
-      jClient.myKeyBundle = JPakeCrypto.finalRound(JPakeClient.secretAsBigInteger(jClient.secret), jClient.jParty);
-    } catch (IncorrectZkpException e) {
-      Logger.error(LOG_TAG, "ZKP mismatch");
-      jClient.abort(Constants.JPAKE_ERROR_WRONGMESSAGE);
-      return;
-    } catch (NoSuchAlgorithmException e) {
-      Logger.error(LOG_TAG, "NoSuchAlgorithmException", e);
-      jClient.abort(Constants.JPAKE_ERROR_INTERNAL);
-      return;
-    } catch (InvalidKeyException e) {
-      Logger.error(LOG_TAG, "InvalidKeyException", e);
-      jClient.abort(Constants.JPAKE_ERROR_INTERNAL);
-      return;
-    } catch (UnsupportedEncodingException e) {
-      Logger.error(LOG_TAG, "UnsupportedEncodingException", e);
-      jClient.abort(Constants.JPAKE_ERROR_INTERNAL);
-      return;
-    }
-
-    // Run next stage.
-    jClient.runNextStage();
-  }
-
-}
deleted file mode 100644
--- a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/jpake/stage/ComputeKeyVerificationStage.java
+++ /dev/null
@@ -1,59 +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.sync.jpake.stage;
-
-import java.io.UnsupportedEncodingException;
-
-import org.mozilla.gecko.background.common.log.Logger;
-import org.mozilla.gecko.sync.ExtendedJSONObject;
-import org.mozilla.gecko.sync.crypto.CryptoException;
-import org.mozilla.gecko.sync.crypto.KeyBundle;
-import org.mozilla.gecko.sync.jpake.JPakeClient;
-import org.mozilla.gecko.sync.setup.Constants;
-
-public class ComputeKeyVerificationStage extends JPakeStage {
-
-  @Override
-  public void execute(JPakeClient jClient) {
-    Logger.debug(LOG_TAG, "Computing verification to send.");
-    if (jClient.myKeyBundle == null) {
-      Logger.error(LOG_TAG, "KeyBundle has not been set; aborting.");
-      jClient.abort(Constants.JPAKE_ERROR_INTERNAL);
-      return;
-    }
-    try {
-      jClient.jOutgoing = computeKeyVerification(jClient.myKeyBundle, jClient.mySignerId);
-    } catch (UnsupportedEncodingException e) {
-      Logger.error(LOG_TAG, "Failure in key verification.", e);
-      jClient.abort(Constants.JPAKE_ERROR_INVALID);
-      return;
-    } catch (CryptoException e) {
-      Logger.error(LOG_TAG, "Encryption failure in key verification.", e);
-      jClient.abort(Constants.JPAKE_ERROR_INTERNAL);
-      return;
-    }
-
-    jClient.runNextStage();
-  }
-
-  /*
-   * Helper function to compute a ciphertext, IV, and HMAC from derived
-   * keyBundle for verifying other party.
-   *
-   * (Made 'public' for testing and is a stateless function.)
-   */
-  public ExtendedJSONObject computeKeyVerification(KeyBundle keyBundle, String signerId)
-      throws UnsupportedEncodingException, CryptoException
-  {
-    Logger.debug(LOG_TAG, "Encrypting key verification value.");
-    ExtendedJSONObject jPayload = JPakeClient.encryptPayload(JPakeClient.JPAKE_VERIFY_VALUE, keyBundle, true);
-    ExtendedJSONObject result = new ExtendedJSONObject();
-    result.put(Constants.JSON_KEY_TYPE, signerId + "3");
-    result.put(Constants.JSON_KEY_VERSION, JPakeClient.KEYEXCHANGE_VERSION);
-    result.put(Constants.JSON_KEY_PAYLOAD, jPayload.object);
-    return result;
-  }
-
-}
deleted file mode 100644
--- a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/jpake/stage/ComputeStepOneStage.java
+++ /dev/null
@@ -1,66 +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.sync.jpake.stage;
-
-import java.io.UnsupportedEncodingException;
-import java.security.NoSuchAlgorithmException;
-
-import org.mozilla.gecko.background.common.log.Logger;
-import org.mozilla.gecko.sync.ExtendedJSONObject;
-import org.mozilla.gecko.sync.jpake.BigIntegerHelper;
-import org.mozilla.gecko.sync.jpake.JPakeClient;
-import org.mozilla.gecko.sync.jpake.JPakeCrypto;
-import org.mozilla.gecko.sync.jpake.JPakeJson;
-import org.mozilla.gecko.sync.jpake.JPakeParty;
-import org.mozilla.gecko.sync.jpake.Zkp;
-import org.mozilla.gecko.sync.setup.Constants;
-
-public class ComputeStepOneStage extends JPakeStage {
-
-  @Override
-  public void execute(JPakeClient jClient) {
-    Logger.debug(LOG_TAG, "Computing round 1.");
-
-    JPakeParty jClientParty = jClient.jParty;
-    try {
-      JPakeCrypto.round1(jClientParty, jClient.numGen);
-    } catch (NoSuchAlgorithmException e) {
-      Logger.error(LOG_TAG, "No such algorithm.", e);
-      jClient.abort(Constants.JPAKE_ERROR_INTERNAL);
-      return;
-    } catch (UnsupportedEncodingException e) {
-      Logger.error(LOG_TAG, "Unsupported encoding.", e);
-      jClient.abort(Constants.JPAKE_ERROR_INVALID);
-      return;
-    } catch (Exception e) {
-      Logger.error(LOG_TAG, "Unexpected exception.", e);
-      jClient.abort(Constants.JPAKE_ERROR_INTERNAL);
-      return;
-    }
-
-    // Set outgoing message.
-    ExtendedJSONObject jOne = new ExtendedJSONObject();
-    jOne.put(Constants.ZKP_KEY_GX1,
-        BigIntegerHelper.toEvenLengthHex(jClientParty.gx1));
-    jOne.put(Constants.ZKP_KEY_GX2,
-        BigIntegerHelper.toEvenLengthHex(jClientParty.gx2));
-
-    Zkp zkp1 = jClientParty.zkp1;
-    Zkp zkp2 = jClientParty.zkp2;
-    ExtendedJSONObject jZkp1 = JPakeJson.makeJZkp(zkp1.gr, zkp1.b, jClient.mySignerId);
-    ExtendedJSONObject jZkp2 = JPakeJson.makeJZkp(zkp2.gr, zkp2.b, jClient.mySignerId);
-
-    jOne.put(Constants.ZKP_KEY_ZKP_X1, jZkp1);
-    jOne.put(Constants.ZKP_KEY_ZKP_X2, jZkp2);
-
-    jClient.jOutgoing = new ExtendedJSONObject();
-    jClient.jOutgoing.put(Constants.JSON_KEY_TYPE, jClient.mySignerId + "1");
-    jClient.jOutgoing.put(Constants.JSON_KEY_PAYLOAD, jOne);
-    jClient.jOutgoing.put(Constants.JSON_KEY_VERSION, JPakeClient.KEYEXCHANGE_VERSION);
-    Logger.debug(LOG_TAG, "Sending: " + jClient.jOutgoing.toJSONString());
-
-    jClient.runNextStage();
-  }
-}
deleted file mode 100644
--- a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/jpake/stage/ComputeStepTwoStage.java
+++ /dev/null
@@ -1,125 +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.sync.jpake.stage;
-
-import java.io.UnsupportedEncodingException;
-import java.math.BigInteger;
-import java.security.NoSuchAlgorithmException;
-
-import org.mozilla.gecko.background.common.log.Logger;
-import org.mozilla.gecko.sync.ExtendedJSONObject;
-import org.mozilla.gecko.sync.NonObjectJSONException;
-import org.mozilla.gecko.sync.jpake.BigIntegerHelper;
-import org.mozilla.gecko.sync.jpake.Gx3OrGx4IsZeroOrOneException;
-import org.mozilla.gecko.sync.jpake.IncorrectZkpException;
-import org.mozilla.gecko.sync.jpake.JPakeClient;
-import org.mozilla.gecko.sync.jpake.JPakeCrypto;
-import org.mozilla.gecko.sync.jpake.JPakeJson;
-import org.mozilla.gecko.sync.jpake.Zkp;
-import org.mozilla.gecko.sync.setup.Constants;
-
-public class ComputeStepTwoStage extends JPakeStage {
-
-  @Override
-  public void execute(JPakeClient jClient) {
-    Logger.debug(LOG_TAG, "Computing round 2.");
-
-    // Check incoming message sender.
-    if (!jClient.jIncoming.get(Constants.JSON_KEY_TYPE).equals(jClient.theirSignerId + "1")) {
-      Logger.error(LOG_TAG, "Invalid round 1 message: " + jClient.jIncoming.toJSONString());
-      jClient.abort(Constants.JPAKE_ERROR_WRONGMESSAGE);
-      return;
-    }
-
-    // Check incoming message fields.
-    ExtendedJSONObject iPayload;
-    try {
-      iPayload = jClient.jIncoming.getObject(Constants.JSON_KEY_PAYLOAD);
-    } catch (NonObjectJSONException e) {
-      Logger.error(LOG_TAG, "JSON object exception.", e);
-      jClient.abort(Constants.JPAKE_ERROR_INVALID);
-      return;
-    }
-    if (iPayload == null) {
-      Logger.error(LOG_TAG, "Invalid round 1 message: " + jClient.jIncoming.toJSONString());
-      jClient.abort(Constants.JPAKE_ERROR_WRONGMESSAGE);
-      return;
-    }
-    ExtendedJSONObject zkpPayload3;
-    ExtendedJSONObject zkpPayload4;
-    try {
-      zkpPayload3 = iPayload.getObject(Constants.ZKP_KEY_ZKP_X1);
-      zkpPayload4 = iPayload.getObject(Constants.ZKP_KEY_ZKP_X2);
-    } catch (NonObjectJSONException e1) {
-      jClient.abort(Constants.JPAKE_ERROR_INVALID);
-      return;
-    }
-
-    if (zkpPayload3 == null || zkpPayload4 == null) {
-      Logger.error(LOG_TAG, "Invalid round 1 zkpPayload message");
-      jClient.abort(Constants.JPAKE_ERROR_WRONGMESSAGE);
-      return;
-    }
-
-    if (!jClient.theirSignerId.equals(zkpPayload3.get(Constants.ZKP_KEY_ID)) ||
-        !jClient.theirSignerId.equals(zkpPayload4.get(Constants.ZKP_KEY_ID))) {
-      Logger.error(LOG_TAG, "Invalid round 1 zkpPayload message");
-      jClient.abort(Constants.JPAKE_ERROR_WRONGMESSAGE);
-      return;
-    }
-
-    // Extract message fields.
-    jClient.jParty.gx3 = new BigInteger((String) iPayload.get(Constants.ZKP_KEY_GX1), 16);
-    jClient.jParty.gx4 = new BigInteger((String) iPayload.get(Constants.ZKP_KEY_GX2), 16);
-
-    // Extract ZKPs.
-    String zkp3_gr = (String) zkpPayload3.get(Constants.ZKP_KEY_GR);
-    String zkp3_b  = (String) zkpPayload3.get(Constants.ZKP_KEY_B);
-    String zkp3_id = (String) zkpPayload3.get(Constants.ZKP_KEY_ID);
-
-    String zkp4_gr = (String) zkpPayload4.get(Constants.ZKP_KEY_GR);
-    String zkp4_b  = (String) zkpPayload4.get(Constants.ZKP_KEY_B);
-    String zkp4_id = (String) zkpPayload4.get(Constants.ZKP_KEY_ID);
-
-    jClient.jParty.zkp3 = new Zkp(new BigInteger(zkp3_gr, 16), new BigInteger(zkp3_b, 16), zkp3_id);
-    jClient.jParty.zkp4 = new Zkp(new BigInteger(zkp4_gr, 16), new BigInteger(zkp4_b, 16), zkp4_id);
-
-    // J-PAKE round 2.
-    try {
-      JPakeCrypto.round2(JPakeClient.secretAsBigInteger(jClient.secret), jClient.jParty, jClient.numGen);
-    } catch (Gx3OrGx4IsZeroOrOneException e) {
-      Logger.error(LOG_TAG, "gx3 and gx4 cannot equal 0 or 1.");
-      jClient.abort(Constants.JPAKE_ERROR_INTERNAL);
-      return;
-    } catch (IncorrectZkpException e) {
-      Logger.error(LOG_TAG, "ZKP mismatch");
-      jClient.abort(Constants.JPAKE_ERROR_WRONGMESSAGE);
-      return;
-    } catch (NoSuchAlgorithmException e) {
-      Logger.error(LOG_TAG, "NoSuchAlgorithmException", e);
-      jClient.abort(Constants.JPAKE_ERROR_INTERNAL);
-      return;
-    } catch (UnsupportedEncodingException e) {
-      Logger.error(LOG_TAG, "UnsupportedEncodingException", e);
-      jClient.abort(Constants.JPAKE_ERROR_INTERNAL);
-      return;
-    }
-
-    // Make outgoing payload.
-    Zkp zkpA = jClient.jParty.thisZkpA;
-    ExtendedJSONObject oPayload = new ExtendedJSONObject();
-    ExtendedJSONObject jZkpA = JPakeJson.makeJZkp(zkpA.gr, zkpA.b, zkpA.id);
-    oPayload.put(Constants.ZKP_KEY_A, BigIntegerHelper.toEvenLengthHex(jClient.jParty.thisA));
-    oPayload.put(Constants.ZKP_KEY_ZKP_A, jZkpA);
-
-    // Make outgoing message.
-    jClient.jOutgoing = new ExtendedJSONObject();
-    jClient.jOutgoing.put(Constants.JSON_KEY_TYPE, jClient.mySignerId + "2");
-    jClient.jOutgoing.put(Constants.JSON_KEY_VERSION, JPakeClient.KEYEXCHANGE_VERSION);
-    jClient.jOutgoing.put(Constants.JSON_KEY_PAYLOAD, oPayload);
-
-    jClient.runNextStage();
-  }
-}
deleted file mode 100644
--- a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/jpake/stage/DecryptDataStage.java
+++ /dev/null
@@ -1,117 +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.sync.jpake.stage;
-
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-
-import org.json.simple.JSONObject;
-import org.json.simple.parser.ParseException;
-import org.mozilla.gecko.background.common.log.Logger;
-import org.mozilla.gecko.sync.ExtendedJSONObject;
-import org.mozilla.gecko.sync.NonObjectJSONException;
-import org.mozilla.gecko.sync.Utils;
-import org.mozilla.gecko.sync.crypto.CryptoException;
-import org.mozilla.gecko.sync.crypto.CryptoInfo;
-import org.mozilla.gecko.sync.crypto.KeyBundle;
-import org.mozilla.gecko.sync.jpake.JPakeClient;
-import org.mozilla.gecko.sync.setup.Constants;
-
-public class DecryptDataStage extends JPakeStage {
-
-  @Override
-  public void execute(JPakeClient jClient) {
-    Logger.debug(LOG_TAG, "Decrypting their payload.");
-    if (!(jClient.theirSignerId + "3").equals((String) jClient.jIncoming
-        .get(Constants.JSON_KEY_TYPE))) {
-      Logger.error(LOG_TAG, "Invalid round 3 data: " + jClient.jIncoming.toJSONString());
-      jClient.abort(Constants.JPAKE_ERROR_WRONGMESSAGE);
-      return;
-    }
-
-    // Decrypt payload and verify HMAC.
-    Logger.debug(LOG_TAG, "Decrypting payload.");
-    ExtendedJSONObject iPayload = null;
-    try {
-      iPayload = jClient.jIncoming.getObject(Constants.JSON_KEY_PAYLOAD);
-    } catch (NonObjectJSONException e1) {
-      Logger.error(LOG_TAG, "Invalid round 3 data.", e1);
-      jClient.abort(Constants.JPAKE_ERROR_WRONGMESSAGE);
-      return;
-    }
-    Logger.debug(LOG_TAG, "Decrypting data.");
-    String cleartext = null;
-    try {
-      cleartext = new String(decryptPayload(iPayload, jClient.myKeyBundle), "UTF-8");
-    } catch (UnsupportedEncodingException e) {
-      Logger.error(LOG_TAG, "Failed to decrypt data.", e);
-      jClient.abort(Constants.JPAKE_ERROR_INTERNAL);
-      return;
-    } catch (CryptoException e) {
-      Logger.error(LOG_TAG, "Failed to decrypt data.", e);
-      jClient.abort(Constants.JPAKE_ERROR_KEYMISMATCH);
-      return;
-    }
-    try {
-      jClient.jCreds = ExtendedJSONObject.parseJSONObject(cleartext).object;
-    } catch (IOException e) {
-      Logger.error(LOG_TAG, "I/O exception while creating JSON object.", e);
-      jClient.abort(Constants.JPAKE_ERROR_INVALID);
-      return;
-    } catch (ParseException | NonObjectJSONException e) {
-      Logger.error(LOG_TAG, "JSON parse error.", e);
-      jClient.abort(Constants.JPAKE_ERROR_INVALID);
-      return;
-    }
-
-    // Check that credentials were actually sent over.
-    if (!checkCredentials(jClient.jCreds)) {
-      Logger.error(LOG_TAG, "Credentials contain nulls, setup cannot be completed.");
-      jClient.abort(Constants.JPAKE_ERROR_INTERNAL);
-      return;
-    }
-
-    jClient.runNextStage();
-  }
-
-  /**
-   * Helper method for doing actual decryption.
-   *
-   * Input: JSONObject containing a valid payload (cipherText, IV, HMAC),
-   * KeyBundle with keys for decryption. Output: byte[] clearText
-   *
-   * @throws CryptoException
-   * @throws UnsupportedEncodingException
-   */
-  private byte[] decryptPayload(ExtendedJSONObject payload, KeyBundle keybundle)
-      throws CryptoException, UnsupportedEncodingException {
-
-    String sCiphertext = (String) payload.get(Constants.JSON_KEY_CIPHERTEXT);
-    String sIv = (String) payload.get(Constants.JSON_KEY_IV);
-    String sHmac = (String) payload.get(Constants.JSON_KEY_HMAC);
-
-    byte[] ciphertext = Utils.decodeBase64(sCiphertext);
-    byte[] iv = Utils.decodeBase64(sIv);
-    byte[] hmac = Utils.hex2Byte(sHmac);
-
-    CryptoInfo decrypted = CryptoInfo.decrypt(ciphertext, iv, hmac, keybundle);
-    return decrypted.getMessage();
-  }
-
-  private boolean checkCredentials(JSONObject creds) {
-    final String accountName = (String) creds.get(Constants.JSON_KEY_ACCOUNT);
-    final String password    = (String) creds.get(Constants.JSON_KEY_PASSWORD);
-    final String syncKey     = (String) creds.get(Constants.JSON_KEY_SYNCKEY);
-    final String serverUrl   = (String) creds.get(Constants.JSON_KEY_SERVER);
-
-    if (accountName == null || accountName.equals("") ||
-        password    == null || password.equals("")    ||
-        syncKey     == null || syncKey.equals("")     ||
-        serverUrl   == null || serverUrl.equals("")) {
-      return false;
-    }
-    return true;
-  }
-}
deleted file mode 100644
--- a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/jpake/stage/DeleteChannel.java
+++ /dev/null
@@ -1,101 +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.sync.jpake.stage;
-
-import java.io.IOException;
-import java.net.URISyntaxException;
-import java.security.GeneralSecurityException;
-
-import org.mozilla.gecko.background.common.log.Logger;
-import org.mozilla.gecko.sync.SyncConstants;
-import org.mozilla.gecko.sync.jpake.JPakeClient;
-import org.mozilla.gecko.sync.net.BaseResource;
-import org.mozilla.gecko.sync.net.BaseResourceDelegate;
-import org.mozilla.gecko.sync.setup.auth.AccountAuthenticator;
-
-import ch.boye.httpclientandroidlib.HttpResponse;
-import ch.boye.httpclientandroidlib.client.ClientProtocolException;
-import ch.boye.httpclientandroidlib.client.methods.HttpRequestBase;
-import ch.boye.httpclientandroidlib.impl.client.DefaultHttpClient;
-import ch.boye.httpclientandroidlib.message.BasicHeader;
-
-public class DeleteChannel {
-  private static final String LOG_TAG = "DeleteChannel";
-
-  public static final String KEYEXCHANGE_ID_HEADER  = "X-KeyExchange-Id";
-  public static final String KEYEXCHANGE_CID_HEADER = "X-KeyExchange-Cid";
-
-  public void execute(final JPakeClient jClient, final String reason) {
-    final BaseResource httpResource;
-    try {
-      httpResource = new BaseResource(jClient.channelUrl);
-    } catch (URISyntaxException e) {
-      Logger.debug(LOG_TAG, "Encountered URISyntax exception, displaying abort anyway.");
-      jClient.displayAbort(reason);
-      return;
-    }
-    httpResource.delegate = new BaseResourceDelegate(httpResource) {
-      @Override
-      public String getUserAgent() {
-        return SyncConstants.USER_AGENT;
-      }
-
-      @Override
-      public void addHeaders(HttpRequestBase request, DefaultHttpClient client) {
-        request.setHeader(new BasicHeader(KEYEXCHANGE_ID_HEADER,  jClient.clientId));
-        request.setHeader(new BasicHeader(KEYEXCHANGE_CID_HEADER, jClient.channel));
-      }
-
-      @Override
-      public void handleHttpResponse(HttpResponse response) {
-        try {
-          int statusCode = response.getStatusLine().getStatusCode();
-          switch (statusCode) {
-            case 200:
-              Logger.info(LOG_TAG, "Successfully reported error to server.");
-              break;
-            case 403:
-              Logger.info(LOG_TAG, "IP is blacklisted.");
-              break;
-            case 400:
-              Logger.info(LOG_TAG, "Bad request (missing logs, or bad ids");
-              break;
-            default:
-              Logger.info(LOG_TAG, "Server returned " + statusCode);
-          }
-        } finally {
-          BaseResource.consumeEntity(response);
-          // Always call displayAbort, even if abort fails. We can't do anything about it.
-          jClient.displayAbort(reason);
-        }
-      }
-
-      @Override
-      public void handleHttpProtocolException(ClientProtocolException e) {
-        Logger.debug(LOG_TAG, "Encountered HttpProtocolException, displaying abort anyway.");
-        jClient.displayAbort(reason);
-      }
-
-      @Override
-      public void handleHttpIOException(IOException e) {
-        Logger.debug(LOG_TAG, "Encountered IOException, displaying abort anyway.");
-        jClient.displayAbort(reason);
-      }
-
-      @Override
-      public void handleTransportException(GeneralSecurityException e) {
-        Logger.debug(LOG_TAG, "Encountered GeneralSecurityException, displaying abort anyway.");
-        jClient.displayAbort(reason);
-      }
-    };
-
-    AccountAuthenticator.runOnThread(new Runnable() {
-      @Override
-      public void run() {
-        httpResource.delete();
-      }
-    });
-  }
-}
deleted file mode 100644
--- a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/jpake/stage/GetChannelStage.java
+++ /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/. */
-
-package org.mozilla.gecko.sync.jpake.stage;
-
-import java.io.IOException;
-import java.net.URISyntaxException;
-import java.security.GeneralSecurityException;
-
-import org.json.simple.parser.JSONParser;
-import org.mozilla.gecko.background.common.log.Logger;
-import org.mozilla.gecko.sync.SyncConstants;
-import org.mozilla.gecko.sync.jpake.JPakeClient;
-import org.mozilla.gecko.sync.net.BaseResource;
-import org.mozilla.gecko.sync.net.BaseResourceDelegate;
-import org.mozilla.gecko.sync.net.SyncResponse;
-import org.mozilla.gecko.sync.setup.Constants;
-
-import ch.boye.httpclientandroidlib.HttpResponse;
-import ch.boye.httpclientandroidlib.client.ClientProtocolException;
-import ch.boye.httpclientandroidlib.client.methods.HttpRequestBase;
-import ch.boye.httpclientandroidlib.impl.client.DefaultHttpClient;
-import ch.boye.httpclientandroidlib.message.BasicHeader;
-
-public class GetChannelStage extends JPakeStage {
-
-  private interface GetChannelStageDelegate {
-    public void handleSuccess(String channel);
-    public void handleFailure(String error);
-    public void handleError(Exception e);
-  }
-
-  @Override
-  public void execute(final JPakeClient jClient) {
-    Logger.debug(LOG_TAG, "Getting channel.");
-
-    // Make delegate to handle responses and propagate them to JPakeClient.
-    GetChannelStageDelegate callbackDelegate = new GetChannelStageDelegate() {
-
-      @Override
-      public void handleSuccess(String channel) {
-        if (jClient.finished) {
-          Logger.debug(LOG_TAG, "Finished; returning.");
-          return;
-        }
-
-        jClient.channelUrl = jClient.jpakeServer + channel;
-        Logger.debug(LOG_TAG, "Using channel " + channel);
-        jClient.makeAndDisplayPin(channel);
-
-        jClient.runNextStage();
-      }
-
-      @Override
-      public void handleFailure(String error) {
-        Logger.error(LOG_TAG, "Got HTTP failure: " + error);
-        jClient.abort(error);
-      }
-
-      @Override
-      public void handleError(Exception e) {
-        Logger.error(LOG_TAG, "Threw HTTP exception.", e);
-        jClient.abort(Constants.JPAKE_ERROR_CHANNEL);
-      }
-    };
-
-    try {
-      makeChannelRequest(callbackDelegate, jClient.jpakeServer + "new_channel", jClient.clientId);
-    } catch (URISyntaxException e) {
-      Logger.error(LOG_TAG, "Incorrect URI syntax.", e);
-      jClient.abort(Constants.JPAKE_ERROR_CHANNEL);
-      return;
-    } catch (Exception e) {
-      Logger.error(LOG_TAG, "Unexpected exception.", e);
-      jClient.abort(Constants.JPAKE_ERROR_CHANNEL);
-      return;
-    }
-  }
-
-  private void makeChannelRequest(final GetChannelStageDelegate callbackDelegate, String getChannelUrl, final String clientId) throws URISyntaxException {
-    final BaseResource httpResource = new BaseResource(getChannelUrl);
-    httpResource.delegate = new BaseResourceDelegate(httpResource) {
-      @Override
-      public String getUserAgent() {
-        return SyncConstants.USER_AGENT;
-      }
-
-      @Override
-      public void addHeaders(HttpRequestBase request, DefaultHttpClient client) {
-        request.setHeader(new BasicHeader("X-KeyExchange-Id", clientId));
-      }
-
-      @Override
-      public void handleHttpResponse(HttpResponse response) {
-        try {
-          SyncResponse res = new SyncResponse(response);
-          String channel = null;
-          try {
-            String body = res.body();
-            channel = (String) new JSONParser().parse(body);
-          } catch (Exception e) {
-            callbackDelegate.handleError(e);
-            return;
-          }
-
-          if (channel == null) {
-            Logger.warn(LOG_TAG, "Got null channel.");
-            callbackDelegate.handleFailure(Constants.JPAKE_ERROR_CHANNEL);
-            return;
-          }
-
-          // Verify input.
-          // From http://docs.services.mozilla.com/keyexchange/apis.html#apis
-          // Returns in the response body a JSON-encoded random channel id of N chars from [a-z0-9].
-          for (int i = 0; i < channel.length(); i++) {
-            char c = channel.charAt(i);
-            if (('a' <= c && c <= 'z') || ('0' <= c && c <= '9')) {
-              continue;
-            }
-
-            Logger.warn(LOG_TAG, "Got bad channel name: " + channel + ".");
-            callbackDelegate.handleFailure(Constants.JPAKE_ERROR_CHANNEL);
-            return;
-          }
-
-          callbackDelegate.handleSuccess(channel);
-        } finally {
-          BaseResource.consumeEntity(response);
-        }
-      }
-
-      @Override
-      public void handleHttpProtocolException(ClientProtocolException e) {
-       callbackDelegate.handleError(e);
-      }
-
-      @Override
-      public void handleHttpIOException(IOException e) {
-        callbackDelegate.handleError(e);
-      }
-
-      @Override
-      public void handleTransportException(GeneralSecurityException e) {
-        callbackDelegate.handleError(e);
-      }
-
-      @Override
-      public int connectionTimeout() {
-        return JPakeClient.REQUEST_TIMEOUT;
-      }
-    };
-
-    // Make GET request.
-    JPakeClient.runOnThread(new Runnable() {
-      @Override
-      public void run() {
-        httpResource.get();
-      }
-    });
-  }
-}
deleted file mode 100644
--- a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/jpake/stage/GetRequestStage.java
+++ /dev/null
@@ -1,217 +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.sync.jpake.stage;
-
-import java.io.IOException;
-import java.net.URISyntaxException;
-import java.security.GeneralSecurityException;
-import java.util.Timer;
-import java.util.TimerTask;
-
-import org.mozilla.gecko.background.common.log.Logger;
-import org.mozilla.gecko.sync.SyncConstants;
-import org.mozilla.gecko.sync.jpake.JPakeClient;
-import org.mozilla.gecko.sync.net.BaseResource;
-import org.mozilla.gecko.sync.net.BaseResourceDelegate;
-import org.mozilla.gecko.sync.net.Resource;
-import org.mozilla.gecko.sync.net.SyncResponse;
-import org.mozilla.gecko.sync.setup.Constants;
-
-import ch.boye.httpclientandroidlib.Header;
-import ch.boye.httpclientandroidlib.HttpResponse;
-import ch.boye.httpclientandroidlib.client.ClientProtocolException;
-import ch.boye.httpclientandroidlib.client.methods.HttpRequestBase;
-import ch.boye.httpclientandroidlib.impl.client.DefaultHttpClient;
-import ch.boye.httpclientandroidlib.message.BasicHeader;
-
-public class GetRequestStage extends JPakeStage {
-
-  private final Timer timerScheduler = new Timer();
-  private int pollTries;
-  private GetStepTimerTask getStepTimerTask;
-
-  private interface GetRequestStageDelegate {
-    public void handleSuccess(HttpResponse response);
-    public void handleFailure(String error);
-    public void handleError(Exception e);
-  }
-
-  @Override
-  public void execute(final JPakeClient jClient) {
-    Logger.debug(LOG_TAG, "Retrieving next message.");
-
-    final GetRequestStageDelegate callbackDelegate = new GetRequestStageDelegate() {
-
-      @Override
-      public void handleSuccess(HttpResponse response) {
-        if (jClient.finished) {
-          Logger.debug(LOG_TAG, "Finished; returning.");
-          return;
-        }
-        SyncResponse res = new SyncResponse(response);
-
-        Header etagHeader = response.getFirstHeader("etag");
-        if (etagHeader == null) {
-          Logger.error(LOG_TAG, "Server did not supply ETag.");
-          jClient.abort(Constants.JPAKE_ERROR_SERVER);
-          return;
-        }
-
-        jClient.theirEtag = etagHeader.getValue();
-        try {
-          jClient.jIncoming = res.jsonObjectBody();
-        } catch (Exception e) {
-          Logger.error(LOG_TAG, "Illegal state.", e);
-          jClient.abort(Constants.JPAKE_ERROR_INVALID);
-          return;
-        }
-        Logger.debug(LOG_TAG, "incoming message: " + jClient.jIncoming.toJSONString());
-
-        jClient.runNextStage();
-      }
-
-      @Override
-      public void handleFailure(String error) {
-        Logger.error(LOG_TAG, "Got HTTP failure: " + error);
-        jClient.abort(error);
-      }
-
-      @Override
-      public void handleError(Exception e) {
-        Logger.error(LOG_TAG, "Threw HTTP exception.", e);
-        jClient.abort(Constants.JPAKE_ERROR_NETWORK);
-      }
-    };
-
-    Resource httpRequest;
-    try {
-      httpRequest = createGetRequest(callbackDelegate, jClient);
-    } catch (URISyntaxException e) {
-      Logger.error(LOG_TAG, "Incorrect URI syntax.", e);
-      jClient.abort(Constants.JPAKE_ERROR_INVALID);
-      return;
-    }
-
-    Logger.debug(LOG_TAG, "Scheduling GET request.");
-    getStepTimerTask = new GetStepTimerTask(httpRequest);
-    timerScheduler.schedule(getStepTimerTask, jClient.jpakePollInterval);
-  }
-
-  private Resource createGetRequest(final GetRequestStageDelegate callbackDelegate, final JPakeClient jpakeClient) throws URISyntaxException {
-    BaseResource httpResource = new BaseResource(jpakeClient.channelUrl);
-    httpResource.delegate = new BaseResourceDelegate(httpResource) {
-      @Override
-      public String getUserAgent() {
-        return SyncConstants.USER_AGENT;
-      }
-
-      @Override
-      public void addHeaders(HttpRequestBase request, DefaultHttpClient client) {
-        request.setHeader(new BasicHeader("X-KeyExchange-Id", jpakeClient.clientId));
-        if (jpakeClient.myEtag != null) {
-          request.setHeader(new BasicHeader("If-None-Match", jpakeClient.myEtag));
-        }
-      }
-
-      @Override
-      public void handleHttpResponse(HttpResponse response) {
-        try {
-          int statusCode = response.getStatusLine().getStatusCode();
-          switch (statusCode) {
-          case 200:
-            jpakeClient.pollTries = 0; // Reset pollTries for next GET.
-            callbackDelegate.handleSuccess(response);
-            break;
-          case 304:
-            Logger.debug(LOG_TAG, "Channel hasn't been updated yet. Will try again later");
-            if (pollTries >= jpakeClient.jpakeMaxTries) {
-              Logger.error(LOG_TAG, "Tried for " + pollTries + " times, maxTries " + jpakeClient.jpakeMaxTries + ", aborting");
-              callbackDelegate.handleFailure(Constants.JPAKE_ERROR_TIMEOUT);
-              break;
-            }
-            jpakeClient.pollTries += 1;
-            if (!jpakeClient.finished) {
-              Logger.debug(LOG_TAG, "Scheduling next GET request.");
-              scheduleGetRequest(jpakeClient.jpakePollInterval, jpakeClient);
-            } else {
-              Logger.debug(LOG_TAG, "Resetting pollTries");
-              jpakeClient.pollTries = 0;
-            }
-            break;
-          case 404:
-            Logger.error(LOG_TAG, "No data found in channel.");
-            callbackDelegate.handleFailure(Constants.JPAKE_ERROR_NODATA);
-            break;
-          case 412: // "Precondition failed"
-            Logger.debug(LOG_TAG, "Message already replaced on server by other party.");
-            callbackDelegate.handleSuccess(response);
-            break;
-          default:
-            Logger.error(LOG_TAG, "Could not retrieve data. Server responded with HTTP " + statusCode);
-            callbackDelegate.handleFailure(Constants.JPAKE_ERROR_SERVER);
-            break;
-          }
-        } finally {
-          // Clean up.
-          BaseResource.consumeEntity(response);
-        }
-      }
-
-      @Override
-      public void handleHttpProtocolException(ClientProtocolException e) {
-       callbackDelegate.handleError(e);
-      }
-
-      @Override
-      public void handleHttpIOException(IOException e) {
-        callbackDelegate.handleError(e);
-
-      }
-
-      @Override
-      public void handleTransportException(GeneralSecurityException e) {
-        callbackDelegate.handleError(e);
-      }
-
-      @Override
-      public int connectionTimeout() {
-        return JPakeClient.REQUEST_TIMEOUT;
-      }
-    };
-    return httpResource;
-  }
-
-  /**
-   * TimerTask for use with delayed GET requests.
-   *
-   */
-  public class GetStepTimerTask extends TimerTask {
-    private final Resource request;
-
-    public GetStepTimerTask(Resource request) {
-      this.request = request;
-    }
-
-    @Override
-    public void run() {
-      request.get();
-    }
-  }
-
-  /*
-   * Helper method to schedule a GET request with some delay.
-   * Basically, run another GetRequestStage.
-   */
-  private void scheduleGetRequest(int delay, final JPakeClient jClient) {
-    timerScheduler.schedule(new TimerTask() {
-
-      @Override
-      public void run() {
-        new GetRequestStage().execute(jClient);
-      }
-    }, delay);
-  }
-
-}
deleted file mode 100644
--- a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/jpake/stage/JPakeStage.java
+++ /dev/null
@@ -1,12 +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.sync.jpake.stage;
-
-import org.mozilla.gecko.sync.jpake.JPakeClient;
-
-public abstract class JPakeStage {
-  protected final String LOG_TAG = "SyncJPakeStage";
-  public abstract void execute(JPakeClient jClient);
-}
deleted file mode 100644
--- a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/jpake/stage/PutRequestStage.java
+++ /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/. */
-
-package org.mozilla.gecko.sync.jpake.stage;
-
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.net.URISyntaxException;
-import java.security.GeneralSecurityException;
-import java.util.Timer;
-import java.util.TimerTask;
-
-import org.mozilla.gecko.background.common.log.Logger;
-import org.mozilla.gecko.sync.SyncConstants;
-import org.mozilla.gecko.sync.jpake.JPakeClient;
-import org.mozilla.gecko.sync.net.BaseResource;
-import org.mozilla.gecko.sync.net.BaseResourceDelegate;
-import org.mozilla.gecko.sync.net.Resource;
-import org.mozilla.gecko.sync.setup.Constants;
-
-import ch.boye.httpclientandroidlib.Header;
-import ch.boye.httpclientandroidlib.HttpResponse;
-import ch.boye.httpclientandroidlib.client.ClientProtocolException;
-import ch.boye.httpclientandroidlib.client.methods.HttpRequestBase;
-import ch.boye.httpclientandroidlib.impl.client.DefaultHttpClient;
-import ch.boye.httpclientandroidlib.message.BasicHeader;
-
-public class PutRequestStage extends JPakeStage {
-
-  private interface PutRequestStageDelegate {
-    public void handleSuccess(HttpResponse response);
-    public void handleFailure(String error);
-    public void handleError(Exception e);
-  };
-
-  @Override
-  public void execute(final JPakeClient jClient) {
-    Logger.debug(LOG_TAG, "Upload message.");
-
-    // Create delegate.
-    final PutRequestStageDelegate callbackDelegate = new PutRequestStageDelegate() {
-
-      @Override
-      public void handleSuccess(HttpResponse response) {
-        TimerTask runNextStage = new TimerTask() {
-          @Override
-          public void run() {
-            jClient.runNextStage();
-          }
-        };
-        Timer timer = new Timer();
-
-        Logger.debug(LOG_TAG, "Pause for 2 * pollInterval before continuing.");
-        // There's no point in returning early here since the next step will
-        // always be a GET, so let's pause for twice the poll interval.
-        timer.schedule(runNextStage, 2 * jClient.jpakePollInterval);
-      }
-
-      @Override
-      public void handleFailure(String error) {
-        Logger.error(LOG_TAG, "Got HTTP failure: " + error);
-        jClient.abort(error);
-      }
-
-      @Override
-      public void handleError(Exception e) {
-        Logger.error(LOG_TAG, "HTTP exception.", e);
-        jClient.abort(Constants.JPAKE_ERROR_NETWORK);
-      }
-    };
-
-    // Create PUT request.
-    Resource putRequest;
-    try {
-      putRequest = createPutRequest(callbackDelegate, jClient);
-    } catch (URISyntaxException e) {
-      Logger.error(LOG_TAG, "URISyntaxException", e);
-      jClient.abort(Constants.JPAKE_ERROR_CHANNEL);
-      return;
-    }
-
-    try {
-      putRequest.put(JPakeClient.jsonEntity(jClient.jOutgoing.object));
-    } catch (UnsupportedEncodingException e) {
-      Logger.error(LOG_TAG, "UnsupportedEncodingException", e);
-      jClient.abort(Constants.JPAKE_ERROR_INTERNAL);
-      return;
-    }
-    Logger.debug(LOG_TAG, "Outgoing message: " + jClient.jOutgoing.toJSONString());
-  }
-
-  private Resource createPutRequest(final PutRequestStageDelegate callbackDelegate, final JPakeClient jpakeClient) throws URISyntaxException {
-    BaseResource httpResource = new BaseResource(jpakeClient.channelUrl);
-    httpResource.delegate = new BaseResourceDelegate(httpResource) {
-      @Override
-      public String getUserAgent() {
-        return SyncConstants.USER_AGENT;
-      }
-
-      @Override
-      public void addHeaders(HttpRequestBase request, DefaultHttpClient client) {
-        request.setHeader(new BasicHeader("X-KeyExchange-Id", jpakeClient.clientId));
-        if (jpakeClient.theirEtag != null) {
-          request.setHeader(new BasicHeader("If-Match", jpakeClient.theirEtag));
-        } else {
-          request.setHeader(new BasicHeader("If-None-Match", "*"));
-        }
-      }
-
-      @Override
-      public void handleHttpResponse(HttpResponse response) {
-        try {
-          int statusCode = response.getStatusLine().getStatusCode();
-          switch (statusCode) {
-          case 200:
-            Header etagHeader = response.getFirstHeader("etag");
-            if (etagHeader == null) {
-              Logger.error(LOG_TAG, "Server did not supply ETag.");
-              callbackDelegate.handleFailure(Constants.JPAKE_ERROR_SERVER);
-              return;
-            }
-            jpakeClient.myEtag = etagHeader.getValue();
-            callbackDelegate.handleSuccess(response);
-            break;
-          default:
-            Logger.error(LOG_TAG, "Could not upload data. Server responded with HTTP " + statusCode);
-            callbackDelegate.handleFailure(Constants.JPAKE_ERROR_SERVER);
-          }
-        } finally {
-          BaseResource.consumeEntity(response);
-        }
-      }
-
-      @Override
-      public void handleHttpProtocolException(ClientProtocolException e) {
-        callbackDelegate.handleError(e);
-      }
-
-      @Override
-      public void handleHttpIOException(IOException e) {
-        callbackDelegate.handleError(e);
-      }
-
-      @Override
-      public void handleTransportException(GeneralSecurityException e) {
-        callbackDelegate.handleError(e);
-      }
-
-      @Override
-      public int connectionTimeout() {
-        return JPakeClient.REQUEST_TIMEOUT;
-      }
-
-    };
-    return httpResource;
-  }
-}
deleted file mode 100644
--- a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/jpake/stage/VerifyPairingStage.java
+++ /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/. */
-
-package org.mozilla.gecko.sync.jpake.stage;
-
-import java.io.UnsupportedEncodingException;
-
-import org.mozilla.apache.commons.codec.binary.Base64;
-import org.mozilla.gecko.background.common.log.Logger;
-import org.mozilla.gecko.sync.ExtendedJSONObject;
-import org.mozilla.gecko.sync.NonObjectJSONException;
-import org.mozilla.gecko.sync.crypto.CryptoException;
-import org.mozilla.gecko.sync.crypto.CryptoInfo;
-import org.mozilla.gecko.sync.crypto.KeyBundle;
-import org.mozilla.gecko.sync.jpake.JPakeClient;
-import org.mozilla.gecko.sync.setup.Constants;
-
-public class VerifyPairingStage extends JPakeStage {
-
-  @Override
-  public void execute(JPakeClient jClient) {
-    Logger.debug(LOG_TAG, "Verifying their key.");
-
-    ExtendedJSONObject verificationObj = jClient.jIncoming;
-    String signerId = (String) verificationObj.get(Constants.JSON_KEY_TYPE);
-    if (!signerId.equals(jClient.theirSignerId + "3")) {
-      Logger.error(LOG_TAG, "Invalid round 3 message: " + verificationObj.toJSONString());
-      jClient.abort(Constants.JPAKE_ERROR_WRONGMESSAGE);
-      return;
-    }
-    ExtendedJSONObject payload;
-    try {
-      payload = verificationObj.getObject(Constants.JSON_KEY_PAYLOAD);
-    } catch (NonObjectJSONException e) {
-      Logger.error(LOG_TAG, "JSON exception.", e);
-      jClient.abort(Constants.JPAKE_ERROR_INVALID);
-      return;
-    }
-    String theirCiphertext = (String) payload.get(Constants.JSON_KEY_CIPHERTEXT);
-    String iv = (String) payload.get(Constants.JSON_KEY_IV);
-    boolean correctPairing;
-    try {
-      correctPairing = verifyCiphertext(theirCiphertext, iv, jClient.myKeyBundle);
-    } catch (UnsupportedEncodingException e) {
-      Logger.error(LOG_TAG, "Unsupported encoding.", e);
-      jClient.abort(Constants.JPAKE_ERROR_INTERNAL);
-      return;
-    } catch (CryptoException e) {
-      Logger.error(LOG_TAG, "Crypto exception.", e);
-      jClient.abort(Constants.JPAKE_ERROR_INTERNAL);
-      return;
-    }
-    if (correctPairing) {
-      Logger.debug(LOG_TAG, "Keys verified successfully.");
-      jClient.paired = true;
-      jClient.onPaired();
-    } else {
-      Logger.error(LOG_TAG, "Keys don't match.");
-      jClient.abort(Constants.JPAKE_ERROR_KEYMISMATCH);
-      return;
-    }
-  }
-
-  /*
-   * Helper function to verify an incoming ciphertext and IV against derived
-   * keyBundle.
-   *
-   * (Made 'public' for testing and is a stateless function.)
-   */
-
-  public boolean verifyCiphertext(String theirCiphertext, String iv,
-      KeyBundle keyBundle) throws UnsupportedEncodingException, CryptoException {
-    byte[] cleartextBytes = JPakeClient.JPAKE_VERIFY_VALUE.getBytes("UTF-8");
-    CryptoInfo encrypted = CryptoInfo.encrypt(cleartextBytes, Base64.decodeBase64(iv), keyBundle);
-    String myCiphertext = new String(Base64.encodeBase64(encrypted.getMessage()), "UTF-8");
-    return myCiphertext.equals(theirCiphertext);
-  }
-}
deleted file mode 100644
--- a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/receivers/SyncAccountDeletedReceiver.java
+++ /dev/null
@@ -1,33 +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.sync.receivers;
-
-import org.mozilla.gecko.background.common.log.Logger;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-
-public class SyncAccountDeletedReceiver extends BroadcastReceiver {
-  public static final String LOG_TAG = "SyncAccountDeletedReceiver";
-
-  /**
-   * This receiver can be killed as soon as it returns, but we have things to do
-   * that can't be done on the main thread (network activity). Therefore we
-   * start a service to do our clean up work for us, with Android doing the
-   * heavy lifting for the service's lifecycle.
-   * <p>
-   * See <a href="http://developer.android.com/reference/android/content/BroadcastReceiver.html#ReceiverLifecycle">the Android documentation</a>
-   * for details.
-   */
-  @Override
-  public void onReceive(final Context context, Intent broadcastIntent) {
-    Logger.debug(LOG_TAG, "Sync Account Deleted broadcast received.");
-
-    Intent serviceIntent = new Intent(context, SyncAccountDeletedService.class);
-    serviceIntent.putExtras(broadcastIntent);
-    context.startService(serviceIntent);
-  }
-}
deleted file mode 100644
--- a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/receivers/SyncAccountDeletedService.java
+++ /dev/null
@@ -1,179 +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.sync.receivers;
-
-import org.mozilla.gecko.fxa.FirefoxAccounts;
-import org.mozilla.gecko.fxa.FxAccountConstants;
-import org.mozilla.gecko.fxa.activities.FxAccountWebFlowActivity;
-import org.mozilla.gecko.sync.ExtendedJSONObject;
-import org.mozilla.gecko.background.common.GlobalConstants;
-import org.mozilla.gecko.background.common.log.Logger;
-import org.mozilla.gecko.sync.Sync11Configuration;
-import org.mozilla.gecko.sync.SyncConstants;
-import org.mozilla.gecko.sync.SyncConfiguration;
-import org.mozilla.gecko.sync.Utils;
-import org.mozilla.gecko.sync.config.AccountPickler;
-import org.mozilla.gecko.sync.config.ClientRecordTerminator;
-import org.mozilla.gecko.sync.net.BasicAuthHeaderProvider;
-import org.mozilla.gecko.sync.repositories.android.FennecTabsRepository;
-import org.mozilla.gecko.sync.setup.Constants;
-import org.mozilla.gecko.sync.setup.SyncAccounts;
-import org.mozilla.gecko.sync.setup.SyncAccounts.SyncAccountParameters;
-
-import android.accounts.Account;
-import android.accounts.AccountManager;
-import android.app.IntentService;
-import android.content.Context;
-import android.content.Intent;
-import android.content.SharedPreferences;
-
-public class SyncAccountDeletedService extends IntentService {
-  public static final String LOG_TAG = "SyncAccountDeletedService";
-
-  public SyncAccountDeletedService() {
-    super(LOG_TAG);
-  }
-
-  @Override
-  protected void onHandleIntent(Intent intent) {
-    // Intent can, in theory, be null. Bug 1025937.
-    if (intent == null) {
-      Logger.debug(LOG_TAG, "Short-circuiting on null intent.");
-      return;
-    }
-
-    final Context context = this;
-
-    if (SyncConstants.SYNC_ACCOUNT_DEPRECATED_ACTION.equals(intent.getAction())) {
-      // Delete Old Sync account.
-      final Account[] accounts = SyncAccounts.syncAccounts(this);
-      for (Account account : accounts) {
-        AccountManager.get(this).removeAccount(account, null, null);
-      }
-
-      // Offer signin for Firefox Account if we don't already have one.
-      if (!FirefoxAccounts.firefoxAccountsExist(this)) {
-        final Intent fxAccountWebIntent = new Intent(FxAccountConstants.ACTION_FXA_GET_STARTED);
-        fxAccountWebIntent.putExtra(FxAccountWebFlowActivity.EXTRA_ENDPOINT, FxAccountConstants.ENDPOINT_PREFERENCES);
-        fxAccountWebIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        fxAccountWebIntent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
-        context.startActivity(fxAccountWebIntent);
-      }
-
-      // Return early. The SYNC_ACCOUNT_DELETED_ACTION spawn by the account
-      // deletion above will remove the pickle file.
-      return;
-    }
-
-    long intentVersion = intent.getLongExtra(Constants.JSON_KEY_VERSION, 0);
-    long expectedVersion = SyncConstants.SYNC_ACCOUNT_DELETED_INTENT_VERSION;
-    if (intentVersion != expectedVersion) {
-      Logger.warn(LOG_TAG, "Intent malformed: version " + intentVersion + " given but version " + expectedVersion + "expected. " +
-          "Not cleaning up after deleted Account.");
-      return;
-    }
-
-    String accountName = intent.getStringExtra(Constants.JSON_KEY_ACCOUNT); // Android Account name, not Sync encoded account name.
-    if (accountName == null) {
-      Logger.warn(LOG_TAG, "Intent malformed: no account name given. Not cleaning up after deleted Account.");
-      return;
-    }
-
-    // Delete the Account pickle.
-    Logger.info(LOG_TAG, "Sync account named " + accountName + " being removed; " +
-        "deleting saved pickle file '" + Constants.ACCOUNT_PICKLE_FILENAME + "'.");
-    deletePickle(context);
-
-    SyncAccountParameters params;
-    try {
-      String payload = intent.getStringExtra(Constants.JSON_KEY_PAYLOAD);
-      if (payload == null) {
-        Logger.warn(LOG_TAG, "Intent malformed: no payload given. Not deleting client record.");
-        return;
-      }
-      ExtendedJSONObject o = ExtendedJSONObject.parseJSONObject(payload);
-      params = new SyncAccountParameters(context, AccountManager.get(context), o);
-    } catch (Exception e) {
-      Logger.warn(LOG_TAG, "Got exception fetching account parameters from intent data; not deleting client record.");
-      return;
-    }
-
-    // Bug 770785: delete the Account's client record.
-    Logger.info(LOG_TAG, "Account named " + accountName + " being removed; " +
-        "deleting client record from server.");
-    deleteClientRecord(context, accountName, params.password, params.serverURL);
-
-    // Delete client database and non-local tabs.
-    Logger.info(LOG_TAG, "Deleting the entire clients database and non-local tabs");
-    FennecTabsRepository.deleteNonLocalClientsAndTabs(context);
-  }
-
-  public static void deletePickle(final Context context) {
-    try {
-      AccountPickler.deletePickle(context, Constants.ACCOUNT_PICKLE_FILENAME);
-    } catch (Exception e) {
-      // This should never happen, but we really don't want to die in a background thread.
-      Logger.warn(LOG_TAG, "Got exception deleting saved pickle file; ignoring.", e);
-    }
-  }
-
-  public static void deleteClientRecord(final Context context, final String accountName,
-      final String password, final String serverURL) {
-    String encodedUsername;
-    try {
-      encodedUsername = Utils.usernameFromAccount(accountName);
-    } catch (Exception e) {
-      Logger.warn(LOG_TAG, "Got exception deleting client record from server; ignoring.", e);
-      return;
-    }
-
-    if (accountName == null || encodedUsername == null || password == null || serverURL == null) {
-      Logger.warn(LOG_TAG, "Account parameters were null; not deleting client record from server.");
-      return;
-    }
-
-    // This is not exactly modular. We need to get some information about
-    // the account, namely the current clusterURL and client GUID, and we
-    // extract it by hand. We're not worried about the Account being
-    // deleted out from under us since the prefs remain even after Account
-    // deletion.
-    final String product = GlobalConstants.BROWSER_INTENT_PACKAGE;
-    final String profile = Constants.DEFAULT_PROFILE;
-    final long version = SyncConfiguration.CURRENT_PREFS_VERSION;
-
-    SharedPreferences prefs;
-    try {
-      prefs = Utils.getSharedPreferences(context, product, encodedUsername, serverURL, profile, version);
-    } catch (Exception e) {
-      Logger.warn(LOG_TAG, "Caught exception fetching preferences; not deleting client record from server.", e);
-      return;
-    }
-
-    try {
-      final String clientGUID = prefs.getString(SyncConfiguration.PREF_ACCOUNT_GUID, null);
-      if (clientGUID == null) {
-        Logger.warn(LOG_TAG, "Client GUID was null; not deleting client record from server.");
-        return;
-      }
-
-      BasicAuthHeaderProvider authHeaderProvider = new BasicAuthHeaderProvider(encodedUsername, password);
-      SyncConfiguration configuration = new Sync11Configuration(encodedUsername, authHeaderProvider, prefs);
-      if (configuration.getClusterURL() == null) {
-        Logger.warn(LOG_TAG, "Cluster URL was null; not deleting client record from server.");
-        return;
-      }
-
-      try {
-        ClientRecordTerminator.deleteClientRecord(configuration, clientGUID);
-      } catch (Exception e) {
-        // This should never happen, but we really don't want to die in a background thread.
-        Logger.warn(LOG_TAG, "Got exception deleting client record from server; ignoring.", e);
-      }
-    } finally {
-      // Finally, a good place to do this.
-      prefs.edit().clear().commit();
-    }
-  }
-}
deleted file mode 100644
--- a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/receivers/UpgradeReceiver.java
+++ /dev/null
@@ -1,130 +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.sync.receivers;
-
-import org.mozilla.gecko.R;
-import org.mozilla.gecko.background.common.GlobalConstants;
-import org.mozilla.gecko.background.common.log.Logger;
-import org.mozilla.gecko.sync.CredentialException;
-import org.mozilla.gecko.sync.SyncConfiguration;
-import org.mozilla.gecko.sync.SyncConstants;
-import org.mozilla.gecko.sync.ThreadPool;
-import org.mozilla.gecko.sync.Utils;
-import org.mozilla.gecko.sync.config.ConfigurationMigrator;
-import org.mozilla.gecko.sync.setup.Constants;
-import org.mozilla.gecko.sync.setup.SyncAccounts;
-import org.mozilla.gecko.sync.setup.SyncAccounts.SyncAccountParameters;
-
-import android.accounts.Account;
-import android.accounts.AccountManager;
-import android.app.NotificationManager;
-import android.app.PendingIntent;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.support.v4.app.NotificationCompat.Builder;
-
-public class UpgradeReceiver extends BroadcastReceiver {
-  private static final String LOG_TAG = "UpgradeReceiver";
-
-  @Override
-  public void onReceive(final Context context, Intent intent) {
-    Logger.debug(LOG_TAG, "Broadcast received.");
-
-    // This unpickles any pickled accounts.
-    if (!SyncAccounts.syncAccountsExist(context)) {
-      Logger.info(LOG_TAG, "No Sync Accounts found; not upgrading anything.");
-      return;
-    }
-
-    // Show account not supported notification.
-    ThreadPool.run(new Runnable() {
-      @Override
-      public void run() {
-        notifyAccountDeprecation(context);
-      }
-    });
-
-    // Should filter for specific MY_PACKAGE_REPLACED intent, but Android does
-    // not expose it.
-    ThreadPool.run(new Runnable() {
-      @Override
-      public void run() {
-        final AccountManager accountManager = AccountManager.get(context);
-        final Account[] accounts = SyncAccounts.syncAccounts(context);
-
-        for (Account a : accounts) {
-          if ("1".equals(accountManager.getUserData(a, Constants.DATA_ENABLE_ON_UPGRADE))) {
-            SyncAccounts.setSyncAutomatically(a, true);
-            accountManager.setUserData(a, Constants.DATA_ENABLE_ON_UPGRADE, "0");
-          }
-
-          // If we are both set to enable after upgrade, and to be removed: we
-          // enable after upgrade first and then we try to remove. If removal
-          // fails, since we enabled sync, we'll try again the next time we
-          // sync, until we (eventually) remove the account.
-          if ("1".equals(accountManager.getUserData(a, Constants.DATA_SHOULD_BE_REMOVED))) {
-            accountManager.removeAccount(a, null, null);
-          }
-        }
-      }
-    });
-
-    /**
-     * Bug 761682: migrate preferences forward.
-     */
-    ThreadPool.run(new Runnable() {
-      @Override
-      public void run() {
-        AccountManager accountManager = AccountManager.get(context);
-        final Account[] accounts = SyncAccounts.syncAccounts(context);
-
-        for (Account account : accounts) {
-          Logger.info(LOG_TAG, "Migrating preferences on upgrade for Android account named " + Utils.obfuscateEmail(account.name) + ".");
-
-          SyncAccountParameters params;
-          try {
-            params = SyncAccounts.blockingFromAndroidAccountV0(context, accountManager, account);
-          } catch (CredentialException e) {
-            Logger.warn(LOG_TAG, "Caught exception fetching account parameters while trying to migrate preferences; ignoring.", e);
-            continue;
-          }
-
-          final String product = GlobalConstants.BROWSER_INTENT_PACKAGE;
-          final String username = params.username;
-          final String serverURL = params.serverURL;
-          final String profile = "default";
-          try {
-            ConfigurationMigrator.ensurePrefsAreVersion(SyncConfiguration.CURRENT_PREFS_VERSION, context, accountManager, account,
-                product, username, serverURL, profile);
-          } catch (Exception e) {
-            Logger.warn(LOG_TAG, "Caught exception trying to migrate preferences; ignoring.", e);
-            continue;
-          }
-        }
-      }
-    });
-  }
-
-  /**
-   * Show a persistent notification telling the user that their Old Sync account is deprecated.
-   */
-  private void notifyAccountDeprecation(final Context context) {
-    final Intent notificationIntent = new Intent(SyncConstants.SYNC_ACCOUNT_DEPRECATED_ACTION);
-    notificationIntent.setClass(context, SyncAccountDeletedService.class);
-    final PendingIntent pendingIntent = PendingIntent.getService(context, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
-    final Builder builder = new Builder(context)
-        .setSmallIcon(R.drawable.ic_status_logo)
-        .setContentTitle(context.getString(R.string.old_sync_deprecated_notification_title))
-        .setContentText(context.getString(R.string.old_sync_deprecated_notification_content))
-        .setAutoCancel(true)
-        .setOngoing(true)
-        .setContentIntent(pendingIntent);
-
-    final NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
-    final int notificationID = SyncConstants.SYNC_ACCOUNT_DEPRECATED_ACTION.hashCode();
-    notificationManager.notify(notificationID, builder.build());
-  }
-}
deleted file mode 100644
--- a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/setup/SyncAuthenticatorService.java
+++ /dev/null
@@ -1,254 +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.sync.setup;
-
-import java.io.UnsupportedEncodingException;
-import java.security.NoSuchAlgorithmException;
-
-import org.mozilla.gecko.background.common.log.Logger;
-import org.mozilla.gecko.sync.SyncConstants;
-import org.mozilla.gecko.sync.Utils;
-import org.mozilla.gecko.sync.setup.activities.SetupSyncActivity;
-
-import android.accounts.AbstractAccountAuthenticator;
-import android.accounts.Account;
-import android.accounts.AccountAuthenticatorResponse;
-import android.accounts.AccountManager;
-import android.accounts.NetworkErrorException;
-import android.app.Service;
-import android.content.Context;
-import android.content.Intent;
-import android.os.Bundle;
-import android.os.IBinder;
-
-public class SyncAuthenticatorService extends Service {
-  private static final String LOG_TAG = "SyncAuthService";
-
-  private SyncAccountAuthenticator sAccountAuthenticator = null;
-
-  @Override
-  public void onCreate() {
-    Logger.debug(LOG_TAG, "onCreate");
-    sAccountAuthenticator = getAuthenticator();
-  }
-
-  @Override
-  public IBinder onBind(Intent intent) {
-    if (intent.getAction().equals(android.accounts.AccountManager.ACTION_AUTHENTICATOR_INTENT)) {
-      return getAuthenticator().getIBinder();
-    }
-    return null;
-  }
-
-  private SyncAccountAuthenticator getAuthenticator() {
-    if (sAccountAuthenticator == null) {
-      sAccountAuthenticator = new SyncAccountAuthenticator(this);
-    }
-    return sAccountAuthenticator;
-  }
-
-  /**
-   * Generate a "plain" auth token.
-   * <p>
-   * Android caches only the value of the key
-   * <code>AccountManager.KEY_AUTHTOKEN</code>, so if a caller needs the other
-   * keys in this bundle, it needs to invalidate the token (so that the bundle
-   * is re-generated).
-   *
-   * @param context
-   *          Android context.
-   * @param account
-   *          Android account.
-   * @return a <code>Bundle</code> instance containing a subset of the following
-   *         keys: (caller's must check for missing keys)
-   *         <ul>
-   *         <li><code>AccountManager.KEY_ACCOUNT_TYPE</code>: the Android
-   *         Account's type</li>
-   *
-   *         <li><code>AccountManager.KEY_ACCOUNT_NAME</code>: the Android
-   *         Account's name</li>
-   *
-   *         <li><code>AccountManager.KEY_AUTHTOKEN</code>: the Sync account's
-   *         password </li>
-   *
-   *         <li><code> Constants.OPTION_USERNAME</code>: the Sync account's
-   *         hashed username</li>
-   *
-   *         <li><code>Constants.OPTION_SERVER</code>: the Sync account's
-   *         server</li>
-   *
-   *         <li><code> Constants.OPTION_SYNCKEY</code>: the Sync account's
-   *         sync key</li>
-   *
-   *         </ul>
-   * @throws NetworkErrorException
-   */
-  public static Bundle getPlainAuthToken(final Context context, final Account account)
-      throws NetworkErrorException {
-    // Extract the username and password from the Account Manager, and ask
-    // the server for an appropriate AuthToken.
-    final AccountManager am = AccountManager.get(context);
-    final String password = am.getPassword(account);
-    if (password == null) {
-      Logger.warn(LOG_TAG, "Returning null bundle for getPlainAuthToken since Account password is null.");
-      return null;
-    }
-
-    final Bundle result = new Bundle();
-
-    // This is a Sync account.
-    result.putString(AccountManager.KEY_ACCOUNT_TYPE, SyncConstants.ACCOUNTTYPE_SYNC);
-
-    // Server.
-    String serverURL = am.getUserData(account, Constants.OPTION_SERVER);
-    result.putString(Constants.OPTION_SERVER, serverURL);
-
-    // Full username, before hashing.
-    result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name);
-
-    // Username after hashing.
-    try {
-      String username = Utils.usernameFromAccount(account.name);
-      Logger.pii(LOG_TAG, "Account " + account.name + " hashes to " + username + ".");
-      Logger.debug(LOG_TAG, "Setting username. Null? " + (username == null));
-      result.putString(Constants.OPTION_USERNAME, username);
-    } catch (NoSuchAlgorithmException | UnsupportedEncodingException e) {
-      // Do nothing. Calling code must check for missing value.
-      Logger.debug(LOG_TAG, "Exception in account lookup: " + e);
-    }
-
-    // Sync key.
-    final String syncKey = am.getUserData(account, Constants.OPTION_SYNCKEY);
-    Logger.debug(LOG_TAG, "Setting sync key. Null? " + (syncKey == null));
-    result.putString(Constants.OPTION_SYNCKEY, syncKey);
-
-    // Password.
-    result.putString(AccountManager.KEY_AUTHTOKEN, password);
-    return result;
-  }
-
-  private static class SyncAccountAuthenticator extends AbstractAccountAuthenticator {
-    private final Context mContext;
-    public SyncAccountAuthenticator(Context context) {
-      super(context);
-      mContext = context;
-    }
-
-    @Override
-    public Bundle addAccount(AccountAuthenticatorResponse response,
-        String accountType, String authTokenType, String[] requiredFeatures,
-        Bundle options) throws NetworkErrorException {
-      Logger.debug(LOG_TAG, "addAccount()");
-      final Intent intent = new Intent(mContext, SetupSyncActivity.class);
-      intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE,
-                      response);
-      intent.putExtra("accountType", SyncConstants.ACCOUNTTYPE_SYNC);
-      intent.putExtra(Constants.INTENT_EXTRA_IS_SETUP, true);
-
-      final Bundle result = new Bundle();
-      result.putParcelable(AccountManager.KEY_INTENT, intent);
-
-      return result;
-    }
-
-    @Override
-    public Bundle confirmCredentials(AccountAuthenticatorResponse response,
-                                     Account account,
-                                     Bundle options) throws NetworkErrorException {
-      Logger.debug(LOG_TAG, "confirmCredentials()");
-      return null;
-    }
-
-    @Override
-    public Bundle editProperties(AccountAuthenticatorResponse response,
-                                 String accountType) {
-      Logger.debug(LOG_TAG, "editProperties");
-      return null;
-    }
-
-    @Override
-    public Bundle getAuthToken(AccountAuthenticatorResponse response,
-        Account account, String authTokenType, Bundle options)
-        throws NetworkErrorException {
-      Logger.debug(LOG_TAG, "getAuthToken()");
-
-      if (Constants.AUTHTOKEN_TYPE_PLAIN.equals(authTokenType)) {
-        return getPlainAuthToken(mContext, account);
-      }
-
-      final Bundle result = new Bundle();
-      result.putString(AccountManager.KEY_ERROR_MESSAGE, "invalid authTokenType");
-      return result;
-    }
-
-    @Override
-    public String getAuthTokenLabel(String authTokenType) {
-      Logger.debug(LOG_TAG, "getAuthTokenLabel()");
-      return null;
-    }
-
-    @Override
-    public Bundle hasFeatures(AccountAuthenticatorResponse response,
-        Account account, String[] features) throws NetworkErrorException {
-      Logger.debug(LOG_TAG, "hasFeatures()");
-      return null;
-    }
-
-    @Override
-    public Bundle updateCredentials(AccountAuthenticatorResponse response,
-        Account account, String authTokenType, Bundle options)
-        throws NetworkErrorException {
-      Logger.debug(LOG_TAG, "updateCredentials()");
-      return null;
-    }
-
-    /**
-     * Bug 769745: persist pickled Sync account settings so that we can unpickle
-     * after Fennec is moved to the SD card.
-     * <p>
-     * This is <b>not</b> called when an Android Account is blown away due to
-     * the SD card being unmounted.
-     * <p>
-     * Broadcasting a Firefox intent to version sharing this Android Account is
-     * a terrible hack, but it's better than the catching the generic
-     * "accounts changed" broadcast intent and trying to figure out whether our
-     * Account disappeared.
-     */
-    @Override
-    public Bundle getAccountRemovalAllowed(final AccountAuthenticatorResponse response, Account account)
-        throws NetworkErrorException {
-      Bundle result = super.getAccountRemovalAllowed(response, account);
-
-      if (result == null ||
-          !result.containsKey(AccountManager.KEY_BOOLEAN_RESULT) ||
-          result.containsKey(AccountManager.KEY_INTENT)) {
-        return result;
-      }
-
-      final boolean removalAllowed = result.getBoolean(AccountManager.KEY_BOOLEAN_RESULT);
-      if (!removalAllowed) {
-        return result;
-      }
-
-      // Bug 790931: Broadcast a message to all Firefox versions sharing this
-      // Android Account type telling that this Sync Account has been deleted.
-      //
-      // We would really prefer to receive Android's
-      // LOGIN_ACCOUNTS_CHANGED_ACTION broadcast, but that
-      // doesn't include enough information about which Accounts changed to
-      // correctly identify whether a Sync account has been removed (when some
-      // Firefox versions are installed on the SD card).
-      //
-      // Broadcast intents protected with permissions are secure, so it's okay
-      // to include password and sync key, etc.
-      final Intent intent = SyncAccounts.makeSyncAccountDeletedIntent(mContext, AccountManager.get(mContext), account);
-      Logger.info(LOG_TAG, "Account named " + account.name + " being removed; " +
-          "broadcasting secure intent " + intent.getAction() + ".");
-      mContext.sendBroadcast(intent, SyncConstants.PER_ACCOUNT_TYPE_PERMISSION);
-
-      return result;
-    }
-  }
-}
deleted file mode 100644
--- a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/setup/activities/AccountActivity.java
+++ /dev/null
@@ -1,353 +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.sync.setup.activities;
-
-import java.util.Locale;
-
-import org.mozilla.gecko.R;
-import org.mozilla.gecko.background.common.log.Logger;
-import org.mozilla.gecko.sync.SyncConstants;
-import org.mozilla.gecko.sync.ThreadPool;
-import org.mozilla.gecko.sync.setup.Constants;
-import org.mozilla.gecko.sync.setup.InvalidSyncKeyException;
-import org.mozilla.gecko.sync.setup.SyncAccounts;
-import org.mozilla.gecko.sync.setup.SyncAccounts.SyncAccountParameters;
-import org.mozilla.gecko.sync.setup.auth.AccountAuthenticator;
-import org.mozilla.gecko.sync.setup.auth.AuthenticationResult;
-
-import android.accounts.Account;
-import android.accounts.AccountAuthenticatorActivity;
-import android.accounts.AccountManager;
-import android.app.ProgressDialog;
-import android.content.Context;
-import android.content.Intent;
-import android.os.Bundle;
-import android.text.Editable;
-import android.text.TextWatcher;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.Window;
-import android.view.WindowManager;
-import android.widget.Button;
-import android.widget.CheckBox;
-import android.widget.CompoundButton;
-import android.widget.CompoundButton.OnCheckedChangeListener;
-import android.widget.EditText;
-import android.widget.Toast;
-
-public class AccountActivity extends AccountAuthenticatorActivity {
-  private final static String LOG_TAG = "AccountActivity";
-
-  private AccountManager      mAccountManager;
-  private Context             mContext;
-  private String              username;
-  private String              password;
-  private String              key;
-  private String              server = SyncConstants.DEFAULT_AUTH_SERVER;
-
-  // UI elements.
-  private EditText            serverInput;
-  private EditText            usernameInput;
-  private EditText            passwordInput;
-  private EditText            synckeyInput;
-  private CheckBox            serverCheckbox;
-  private Button              connectButton;
-  private Button              cancelButton;
-  private ProgressDialog      progressDialog;
-
-  private AccountAuthenticator accountAuthenticator;
-
-  @Override
-  public void onCreate(Bundle savedInstanceState) {
-    super.onCreate(savedInstanceState);
-    setContentView(R.layout.sync_account);
-
-    ActivityUtils.prepareLogging();
-    mContext = getApplicationContext();
-    Logger.debug(LOG_TAG, "AccountManager.get(" + mContext + ")");
-    mAccountManager = AccountManager.get(mContext);
-
-    // Set "screen on" flag.
-    Logger.debug(LOG_TAG, "Setting screen-on flag.");
-    Window w = getWindow();
-    w.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
-
-    // Find UI elements.
-    usernameInput = (EditText) findViewById(R.id.usernameInput);
-    passwordInput = (EditText) findViewById(R.id.passwordInput);
-    synckeyInput = (EditText) findViewById(R.id.keyInput);
-    serverInput = (EditText) findViewById(R.id.serverInput);
-
-    TextWatcher inputValidator = makeInputValidator();
-
-    usernameInput.addTextChangedListener(inputValidator);
-    passwordInput.addTextChangedListener(inputValidator);
-    synckeyInput.addTextChangedListener(inputValidator);
-    serverInput.addTextChangedListener(inputValidator);
-
-    connectButton = (Button) findViewById(R.id.accountConnectButton);
-    cancelButton = (Button) findViewById(R.id.accountCancelButton);
-    serverCheckbox = (CheckBox) findViewById(R.id.checkbox_server);
-
-    serverCheckbox.setOnCheckedChangeListener(new OnCheckedChangeListener() {
-      @Override
-      public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
-        Logger.info(LOG_TAG, "Toggling checkbox: " + isChecked);
-        if (!isChecked) { // Clear server input.
-          serverInput.setVisibility(View.GONE);
-          findViewById(R.id.server_error).setVisibility(View.GONE);
-          serverInput.setText("");
-        } else {
-          serverInput.setVisibility(View.VISIBLE);
-          serverInput.setEnabled(true);
-        }
-        // Activate connectButton if necessary.
-        activateView(connectButton, validateInputs());
-      }
-    });
-  }
-
-  @Override
-  public void onResume() {
-    super.onResume();
-    ActivityUtils.prepareLogging();
-    clearCredentials();
-    usernameInput.requestFocus();
-    cancelButton.setOnClickListener(new OnClickListener() {
-
-      @Override
-      public void onClick(View v) {
-        cancelClickHandler(v);
-      }
-
-    });
-  }
-
-  public void cancelClickHandler(View target) {
-    finish();
-  }
-
-  public void cancelConnectHandler(View target) {
-    if (accountAuthenticator != null) {
-      accountAuthenticator.isCanceled = true;
-      accountAuthenticator = null;
-    }
-    displayVerifying(false);
-    activateView(connectButton, true);
-    clearCredentials();
-    usernameInput.requestFocus();
-  }
-
-  private void clearCredentials() {
-    // Only clear password. Re-typing the sync key or email is annoying.
-    passwordInput.setText("");
-  }
-  /*
-   * Get credentials on "Connect" and write to AccountManager, where it can be
-   * accessed by Fennec and Sync Service.
-   */
-  public void connectClickHandler(View target) {
-    Logger.debug(LOG_TAG, "connectClickHandler for view " + target);
-    // Validate sync key format.
-    try {
-      key = ActivityUtils.validateSyncKey(synckeyInput.getText().toString());
-    } catch (InvalidSyncKeyException e) {
-      // Toast: invalid sync key format.
-      Toast toast = Toast.makeText(mContext, R.string.sync_new_recoverykey_status_incorrect, Toast.LENGTH_LONG);
-      toast.show();
-      return;
-    }
-    username = usernameInput.getText().toString().toLowerCase(Locale.US);
-    password = passwordInput.getText().toString();
-    key      = synckeyInput.getText().toString();
-    server   = SyncConstants.DEFAULT_AUTH_SERVER;
-
-    if (serverCheckbox.isChecked()) {
-      String userServer = serverInput.getText().toString();
-      if (userServer != null) {
-        userServer = userServer.trim();
-        if (userServer.length() != 0) {
-          if (!userServer.startsWith("https://") &&
-              !userServer.startsWith("http://")) {
-            // Assume HTTPS if not specified.
-            userServer = "https://" + userServer;
-            serverInput.setText(userServer);
-          }
-          server = userServer;
-        }
-      }
-    }
-
-    clearErrors();
-    displayVerifying(true);
-    cancelButton.setOnClickListener(new OnClickListener() {
-      @Override
-      public void onClick(View v) {
-        cancelConnectHandler(v);
-        // Set cancel click handler to leave account setup.
-        cancelButton.setOnClickListener(new OnClickListener() {
-          @Override
-          public void onClick(View v) {
-            cancelClickHandler(v);
-          }
-        });
-      }
-    });
-
-    accountAuthenticator = new AccountAuthenticator(this);
-    accountAuthenticator.authenticate(server, username, password);
-  }
-
-  private TextWatcher makeInputValidator() {
-    return new TextWatcher() {
-
-      @Override
-      public void afterTextChanged(Editable s) {
-        activateView(connectButton, validateInputs());
-      }
-
-      @Override
-      public void beforeTextChanged(CharSequence s, int start, int count,
-          int after) {
-      }
-
-      @Override
-      public void onTextChanged(CharSequence s, int start, int before, int count) {
-      }
-    };
-  }
-
-  private boolean validateInputs() {
-    if (usernameInput.length() == 0 ||
-        passwordInput.length() == 0 ||
-        synckeyInput.length() == 0  ||
-        (serverCheckbox.isChecked() &&
-         serverInput.length() == 0)) {
-      return false;
-    }
-    return true;
-  }
-
-  /*
-   * Callback that handles auth based on success/failure
-   */
-  public void authCallback(final AuthenticationResult result) {
-    displayVerifying(false);
-    if (result != AuthenticationResult.SUCCESS) {
-      Logger.debug(LOG_TAG, "displayFailure()");
-      displayFailure(result);
-      return;
-    }
-    // Successful authentication. Create and add account to AccountManager.
-    SyncAccountParameters syncAccount = new SyncAccountParameters(
-        mContext, mAccountManager, username, key, password, server);
-    createAccountOnThread(syncAccount);
-  }
-
-  private void createAccountOnThread(final SyncAccountParameters syncAccount) {
-    ThreadPool.run(new Runnable() {
-      @Override
-      public void run() {
-        Account account = SyncAccounts.createSyncAccount(syncAccount);
-        boolean isSuccess = (account != null);
-        if (!isSuccess) {
-          setResult(RESULT_CANCELED);
-          runOnUiThread(new Runnable() {
-            @Override
-            public void run() {
-              displayFailure(AuthenticationResult.FAILURE_ACCOUNT);
-            }
-          });
-          return;
-        }
-
-        // Account created successfully.
-        clearErrors();
-
-        Bundle resultBundle = new Bundle();
-        resultBundle.putString(AccountManager.KEY_ACCOUNT_NAME, syncAccount.username);
-        resultBundle.putString(AccountManager.KEY_ACCOUNT_TYPE, SyncConstants.ACCOUNTTYPE_SYNC);
-        resultBundle.putString(AccountManager.KEY_AUTHTOKEN, SyncConstants.ACCOUNTTYPE_SYNC);
-        setAccountAuthenticatorResult(resultBundle);
-
-        setResult(RESULT_OK);
-        runOnUiThread(new Runnable() {
-          @Override
-          public void run() {
-            authSuccess();
-          }
-        });
-      }
-    });
-  }
-
-  private void displayVerifying(final boolean isVerifying) {
-    if (isVerifying) {
-      progressDialog = ProgressDialog.show(AccountActivity.this, "", getString(R.string.sync_verifying_label), true);
-    } else {
-      progressDialog.dismiss();
-    }
-  }
-
-  private void displayFailure(final AuthenticationResult result) {
-    runOnUiThread(new Runnable() {
-      @Override
-      public void run() {
-        Intent intent;
-        switch (result) {
-        case FAILURE_USERNAME:
-          // No such username. Don't leak whether the username exists.
-        case FAILURE_PASSWORD:
-          findViewById(R.id.cred_error).setVisibility(View.VISIBLE);
-          usernameInput.requestFocus();
-          break;
-        case FAILURE_SERVER:
-          findViewById(R.id.server_error).setVisibility(View.VISIBLE);
-          serverInput.requestFocus();
-          break;
-        case FAILURE_ACCOUNT:
-          intent = new Intent(mContext, SetupFailureActivity.class);
-          intent.setFlags(Constants.FLAG_ACTIVITY_REORDER_TO_FRONT_NO_ANIMATION);
-          intent.putExtra(Constants.INTENT_EXTRA_IS_ACCOUNTERROR, true);
-          startActivity(intent);
-          break;
-        case FAILURE_OTHER:
-        default:
-          // Display default error screen.
-          Logger.debug(LOG_TAG, "displaying default failure.");
-          intent = new Intent(mContext, SetupFailureActivity.class);
-          intent.setFlags(Constants.FLAG_ACTIVITY_REORDER_TO_FRONT_NO_ANIMATION);
-          startActivity(intent);
-        }
-      }
-    });
-  }
-
-  /**
-   * Feedback to user of account setup success.
-   */
-  public void authSuccess() {
-    // Display feedback of successful account setup.
-    Intent intent = new Intent(mContext, SetupSuccessActivity.class);
-    intent.setFlags(Constants.FLAG_ACTIVITY_REORDER_TO_FRONT_NO_ANIMATION);
-    startActivity(intent);
-    finish();
-  }
-
-  private void activateView(View view, boolean toActivate) {
-    view.setEnabled(toActivate);
-    view.setClickable(toActivate);
-  }
-
-  private void clearErrors() {
-    runOnUiThread(new Runnable() {
-      @Override
-      public void run() {
-        findViewById(R.id.cred_error).setVisibility(View.GONE);
-        findViewById(R.id.server_error).setVisibility(View.GONE);
-      }
-    });
-  }
-}
deleted file mode 100644
--- a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/setup/activities/RedirectToSetupActivity.java
+++ /dev/null
@@ -1,36 +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.sync.setup.activities;
-
-import org.mozilla.gecko.R;
-import org.mozilla.gecko.background.common.log.Logger;
-import org.mozilla.gecko.sync.setup.Constants;
-
-import android.content.Intent;
-import android.os.Bundle;
-import android.view.View;
-
-public class RedirectToSetupActivity extends SyncActivity {
-  public static final String LOG_TAG = "RedirectToSetupActivity";
-
-  @Override
-  public void onCreate(Bundle savedInstanceState) {
-    super.onCreate(savedInstanceState);
-    setContentView(R.layout.sync_redirect_to_setup);
-  }
-
-  public void redirectToSetupHandler(View view) {
-    Logger.info(LOG_TAG, "Setup Sync was clicked.");
-
-    Intent intent = new Intent(this, SetupSyncActivity.class);
-    intent.setFlags(Constants.FLAG_ACTIVITY_REORDER_TO_FRONT_NO_ANIMATION);
-    startActivity(intent);
-  }
-
-  public void cancelClickHandler(View target) {
-    setResult(RESULT_CANCELED);
-    finish();
-  }
-}
deleted file mode 100644
--- a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/setup/activities/SendTabData.java
+++ /dev/null
@@ -1,58 +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.sync.setup.activities;
-
-import java.util.Arrays;
-import java.util.List;
-
-import android.content.Intent;
-import android.os.Bundle;
-
-/**
- * A static factory that extracts (title, uri) pairs suitable for send tab from
- * Android intent instances.
- * <p>
- * Takes some care to extract likely "Web URLs" in preference to general URIs.
- */
-public class SendTabData {
-  public final String title;
-  public final String uri;
-
-  public SendTabData(String title, String uri) {
-    this.title = title;
-    this.uri = uri;
-  }
-
-  public static SendTabData fromIntent(Intent intent) {
-    if (intent == null) {
-      throw new IllegalArgumentException("intent must not be null");
-    }
-
-    return fromBundle(intent.getExtras());
-  }
-
-  protected static SendTabData fromBundle(Bundle bundle) {
-    if (bundle == null) {
-      throw new IllegalArgumentException("bundle must not be null");
-    }
-
-    String text = bundle.getString(Intent.EXTRA_TEXT);
-    String subject = bundle.getString(Intent.EXTRA_SUBJECT);
-    String title = bundle.getString(Intent.EXTRA_TITLE);
-
-    // For title, prefer EXTRA_SUBJECT but accept EXTRA_TITLE.
-    String theTitle = subject;
-    if (theTitle == null) {
-      theTitle = title;
-    }
-
-    // For URL, take first URL from EXTRA_TEXT, EXTRA_SUBJECT, and EXTRA_TITLE
-    // (in that order).
-    List<String> strings = Arrays.asList(text, subject, title);
-    String theUri = new WebURLFinder(strings).bestWebURL();
-
-    return new SendTabData(theTitle, theUri);
-  }
-}
deleted file mode 100644
--- a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/setup/activities/SetupFailureActivity.java
+++ /dev/null
@@ -1,58 +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.sync.setup.activities;
-
-import org.mozilla.gecko.R;
-import org.mozilla.gecko.sync.setup.Constants;
-
-import android.content.Context;
-import android.content.Intent;
-import android.os.Bundle;
-import android.view.View;
-import android.widget.TextView;
-
-public class SetupFailureActivity extends SyncActivity {
-  private Context mContext;
-
-  @Override
-  public void onCreate(Bundle savedInstanceState) {
-    super.onCreate(savedInstanceState);
-    setContentView(R.layout.sync_setup_failure);
-    mContext = this.getApplicationContext();
-
-    // Modify general error message if necessary.
-    Bundle extras = this.getIntent().getExtras();
-    if (extras != null) {
-      boolean isAccountError = extras.getBoolean(Constants.INTENT_EXTRA_IS_ACCOUNTERROR);
-      if (isAccountError) {
-        TextView subtitle1 = (TextView) findViewById(R.id.failure_subtitle1);
-        // Display error for multiple accounts.
-        // TODO: Remove when Bug 761206 is resolved (support for multiple versions).
-        TextView subtitle2 = (TextView) findViewById(R.id.failure_subtitle2);
-        subtitle1.setText(getString(R.string.sync_subtitle_failaccount));
-        subtitle2.setVisibility(View.VISIBLE);
-        subtitle2.setText(getString(R.string.sync_subtitle_failmultiple));
-      }
-    }
-  }
-
-  public void manualClickHandler(View target) {
-    Intent intent = new Intent(mContext, AccountActivity.class);
-    intent.setFlags(Constants.FLAG_ACTIVITY_REORDER_TO_FRONT_NO_ANIMATION);
-    startActivity(intent);
-    overridePendingTransition(0, 0);
-    finish();
-  }
-
-  public void tryAgainClickHandler(View target) {
-    finish();
-  }
-
-  public void cancelClickHandler(View target) {
-    setResult(RESULT_CANCELED);
-    moveTaskToBack(true);
-    finish();
-  }
-}
deleted file mode 100644
--- a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/setup/activities/SetupSuccessActivity.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-package org.mozilla.gecko.sync.setup.activities;
-
-import org.mozilla.gecko.R;
-import org.mozilla.gecko.sync.setup.Constants;
-import org.mozilla.gecko.sync.setup.SyncAccounts;
-
-import android.os.Bundle;
-import android.view.View;
-import android.widget.TextView;
-
-public class SetupSuccessActivity extends SyncActivity {
-  private TextView setupSubtitle;
-
-  @Override
-  public void onCreate(Bundle savedInstanceState) {
-    super.onCreate(savedInstanceState);
-    Bundle extras = this.getIntent().getExtras();
-    setContentView(R.layout.sync_setup_success);
-    setupSubtitle = ((TextView) findViewById(R.id.setup_success_subtitle));
-    if (extras != null) {
-      boolean isSetup = extras.getBoolean(Constants.INTENT_EXTRA_IS_SETUP);
-      if (!isSetup) {
-        setupSubtitle.setText(getString(R.string.sync_subtitle_manage));
-      }
-    }
-  }
-
-  @Override
-  public void onDestroy() {
-    super.onDestroy();
-  }
-
-  /* Click Handlers */
-  public void settingsClickHandler(View target) {
-    SyncAccounts.openSyncSettings(this);
-  }
-
-  public void launchBrowser(View target) {
-    ActivityUtils.openURLInFennec(this, null);
-  }
-}
deleted file mode 100644
--- a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/setup/activities/SetupSyncActivity.java
+++ /dev/null
@@ -1,623 +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.sync.setup.activities;
-
-import java.io.UnsupportedEncodingException;
-import java.util.HashMap;
-
-import org.json.simple.JSONObject;
-import org.mozilla.gecko.R;
-import org.mozilla.gecko.background.common.log.Logger;
-import org.mozilla.gecko.sync.SyncConstants;
-import org.mozilla.gecko.sync.ThreadPool;
-import org.mozilla.gecko.sync.Utils;
-import org.mozilla.gecko.sync.jpake.JPakeClient;
-import org.mozilla.gecko.sync.jpake.JPakeNoActivePairingException;
-import org.mozilla.gecko.sync.setup.Constants;
-import org.mozilla.gecko.sync.setup.SyncAccounts;
-import org.mozilla.gecko.sync.setup.SyncAccounts.SyncAccountParameters;
-
-import android.accounts.Account;
-import android.accounts.AccountAuthenticatorActivity;
-import android.accounts.AccountManager;
-import android.app.Activity;
-import android.content.Context;
-import android.content.Intent;
-import android.net.ConnectivityManager;
-import android.net.NetworkInfo;
-import android.net.Uri;
-import android.os.Bundle;
-import android.text.Editable;
-import android.text.TextWatcher;
-import android.view.View;
-import android.view.Window;
-import android.view.WindowManager;
-import android.widget.Button;
-import android.widget.EditText;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-import android.widget.Toast;
-
-public class SetupSyncActivity extends AccountAuthenticatorActivity {
-  private final static String LOG_TAG = "SetupSync";
-
-  private boolean pairWithPin = false;
-
-  // UI elements for pairing through PIN entry.
-  private EditText            row1;
-  private EditText            row2;
-  private EditText            row3;
-  private Button              connectButton;
-  private LinearLayout        pinError;
-
-  // UI elements for pairing through PIN generation.
-  private TextView            pinTextView1;
-  private TextView            pinTextView2;
-  private TextView            pinTextView3;
-  private JPakeClient         jClient;
-
-  // Android context.
-  private AccountManager      mAccountManager;
-  private Context             mContext;
-
-  public SetupSyncActivity() {
-    super();
-  }
-
-  /** Called when the activity is first created. */
-  @Override
-  public void onCreate(Bundle savedInstanceState) {
-    ActivityUtils.prepareLogging();
-    Logger.info(LOG_TAG, "Called SetupSyncActivity.onCreate.");
-    super.onCreate(savedInstanceState);
-
-    // Set Activity variables.
-    mContext = getApplicationContext();
-    Logger.debug(LOG_TAG, "AccountManager.get(" + mContext + ")");
-    mAccountManager = AccountManager.get(mContext);
-
-    // Set "screen on" flag for this activity. Screen will not automatically dim as long as this
-    // activity is at the top of the stack.
-    // Attempting to set this flag more than once causes hanging, so we set it here, not in onResume().
-    Window w = getWindow();
-    w.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
-    Logger.debug(LOG_TAG, "Successfully set screen-on flag.");
-  }
-
-  @Override
-  public void onResume() {
-    ActivityUtils.prepareLogging();
-    Logger.info(LOG_TAG, "Called SetupSyncActivity.onResume.");
-    super.onResume();
-
-    if (!hasInternet()) {
-      runOnUiThread(new Runnable() {
-        @Override
-        public void run() {
-          setContentView(R.layout.sync_setup_nointernet);
-        }
-      });
-      return;
-    }
-
-    // Check whether Sync accounts exist; if not, display J-PAKE PIN.
-    // Run this on a separate thread to comply with Strict Mode thread policies.
-    ThreadPool.run(new Runnable() {
-      @Override
-      public void run() {
-        ActivityUtils.prepareLogging();
-        Account[] accts = mAccountManager.getAccountsByType(SyncConstants.ACCOUNTTYPE_SYNC);
-        finishResume(accts);
-      }
-    });
-  }
-
-  public void finishResume(Account[] accts) {
-    Logger.debug(LOG_TAG, "Finishing Resume after fetching accounts.");
-
-    if (accts.length == 0) { // Start J-PAKE for pairing if no accounts present.
-      Logger.debug(LOG_TAG, "No accounts; starting J-PAKE receiver.");
-      displayReceiveNoPin();
-      if (jClient != null) {
-        // Mark previous J-PAKE as finished. Don't bother propagating back up to this Activity.
-        jClient.finished = true;
-      }
-      jClient = new JPakeClient(this);
-      jClient.receiveNoPin();
-      return;
-    }
-
-    // Set layout based on starting Intent.
-    Bundle extras = this.getIntent().getExtras();
-    if (extras != null) {
-      Logger.debug(LOG_TAG, "SetupSync with extras.");
-      boolean isSetup = extras.getBoolean(Constants.INTENT_EXTRA_IS_SETUP);
-      if (!isSetup) {
-        Logger.debug(LOG_TAG, "Account exists; Pair a Device started.");
-        pairWithPin = true;
-        displayPairWithPin();
-        return;
-      }
-    }
-
-    runOnUiThread(new Runnable() {
-      @Override
-      public void run() {
-        Logger.debug(LOG_TAG, "Only one account supported. Redirecting.");
-        // Display toast for "Only one account supported."
-        // Redirect to account management.
-        Toast toast = Toast.makeText(mContext,
-            R.string.sync_notification_oneaccount, Toast.LENGTH_LONG);
-        toast.show();
-
-        // Setting up Sync when an existing account exists only happens from Settings,
-        // so we can safely finish() the activity to return to Settings.
-        finish();
-      }
-    });
-  }
-
-
-  @Override
-  public void onPause() {
-    super.onPause();
-
-    if (jClient != null) {
-      jClient.abort(Constants.JPAKE_ERROR_USERABORT);
-    }
-    if (pairWithPin) {
-      finish();
-    }
-  }
-
-  @Override
-  public void onNewIntent(Intent intent) {
-    Logger.debug(LOG_TAG, "Started SetupSyncActivity with new intent.");
-    setIntent(intent);
-  }
-
-  @Override
-  public void onDestroy() {
-    Logger.debug(LOG_TAG, "onDestroy() called.");
-    super.onDestroy();
-  }
-
-  /* Click Handlers */
-  public void manualClickHandler(View target) {
-    Intent accountIntent = new Intent(this, AccountActivity.class);
-    accountIntent.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
-    startActivityForResult(accountIntent, 0);
-    overridePendingTransition(0, 0);
-  }
-
-  public void cancelClickHandler(View target) {
-    finish();
-  }
-
-  public void connectClickHandler(View target) {
-    Logger.debug(LOG_TAG, "Connect clicked.");
-    // Set UI feedback.
-    pinError.setVisibility(View.INVISIBLE);
-    enablePinEntry(false);
-    connectButton.requestFocus();
-    activateButton(connectButton, false);
-
-    // Extract PIN.
-    String pin = row1.getText().toString();
-    pin += row2.getText().toString() + row3.getText().toString();
-
-    // Start J-PAKE.
-    if (jClient != null) {
-      // Cancel previous J-PAKE exchange.
-      jClient.finished = true;
-    }
-    jClient = new JPakeClient(this);
-    jClient.pairWithPin(pin);
-  }
-
-  /**
-   * Handler when "Show me how" link is clicked.
-   * @param target
-   *          View that received the click.
-   */
-  public void showClickHandler(View target) {
-    Uri uri = null;
-    // TODO: fetch these from fennec
-    if (pairWithPin) {
-      uri = Uri.parse(Constants.LINK_FIND_CODE);
-    } else {
-      uri = Uri.parse(Constants.LINK_FIND_ADD_DEVICE);
-    }
-    Intent intent = new Intent(this, WebViewActivity.class);
-    intent.setData(uri);
-    startActivity(intent);
-  }
-
-  /* Controller methods */
-
-  /**
-   * Display generated PIN to user.
-   * @param pin
-   *          12-character string generated for J-PAKE.
-   */
-  public void displayPin(String pin) {
-    if (pin == null) {
-      Logger.warn(LOG_TAG, "Asked to display null pin.");
-      return;
-    }
-    // Format PIN for display.
-    int charPerLine = pin.length() / 3;
-    final String pin1 = pin.substring(0, charPerLine);
-    final String pin2 = pin.substring(charPerLine, 2 * charPerLine);
-    final String pin3 = pin.substring(2 * charPerLine, pin.length());
-
-    runOnUiThread(new Runnable() {
-      @Override
-      public void run() {
-        TextView view1 = pinTextView1;
-        TextView view2 = pinTextView2;
-        TextView view3 = pinTextView3;
-        if (view1 == null || view2 == null || view3 == null) {
-          Logger.warn(LOG_TAG, "Couldn't find view to display PIN.");
-          return;
-        }
-        view1.setText(pin1);
-        view1.setContentDescription(pin1.replaceAll("\\B", ", "));
-
-        view2.setText(pin2);
-        view2.setContentDescription(pin2.replaceAll("\\B", ", "));
-
-        view3.setText(pin3);
-        view3.setContentDescription(pin3.replaceAll("\\B", ", "));
-      }
-    });
-  }
-
-  /**
-   * Abort current J-PAKE pairing. Clear forms/restart pairing.
-   * @param error
-   */
-  public void displayAbort(String error) {
-    if (!Constants.JPAKE_ERROR_USERABORT.equals(error) && !hasInternet()) {
-      runOnUiThread(new Runnable() {
-        @Override
-        public void run() {
-          setContentView(R.layout.sync_setup_nointernet);
-        }
-      });
-      return;
-    }
-    if (pairWithPin) {
-      // Clear PIN entries and display error.
-      runOnUiThread(new Runnable() {
-        @Override
-        public void run() {
-          enablePinEntry(true);
-          row1.setText("");
-          row2.setText("");
-          row3.setText("");
-          row1.requestFocus();
-
-          // Display error.
-          pinError.setVisibility(View.VISIBLE);
-        }
-      });
-      return;
-    }
-
-    // Start new JPakeClient for restarting J-PAKE.
-    Logger.debug(LOG_TAG, "abort reason: " + error);
-    if (!Constants.JPAKE_ERROR_USERABORT.equals(error)) {
-      jClient = new JPakeClient(this);
-      runOnUiThread(new Runnable() {
-        @Override
-        public void run() {
-          displayReceiveNoPin();
-          jClient.receiveNoPin();
-        }
-      });
-    }
-  }
-
-  @SuppressWarnings({ "unchecked", "static-method" })
-  protected JSONObject makeAccountJSON(String username, String password,
-                                       String syncKey, String serverURL) {
-
-    JSONObject jAccount = new JSONObject();
-
-    // Hack to try to keep Java 1.7 from complaining about unchecked types,
-    // despite the presence of SuppressWarnings.
-    HashMap<String, String> fields = (HashMap<String, String>) jAccount;
-
-    fields.put(Constants.JSON_KEY_SYNCKEY,  syncKey);
-    fields.put(Constants.JSON_KEY_ACCOUNT,  username);
-    fields.put(Constants.JSON_KEY_PASSWORD, password);
-    fields.put(Constants.JSON_KEY_SERVER,   serverURL);
-
-    if (Logger.LOG_PERSONAL_INFORMATION) {
-      Logger.pii(LOG_TAG, "Extracted account data: " + jAccount.toJSONString());
-    }
-    return jAccount;
-  }
-
-  /**
-   * Device has finished key exchange, waiting for remote device to set up or
-   * link to a Sync account. Display "waiting for other device" dialog.
-   */
-  public void onPaired() {
-    // Extract Sync account data.
-    Account[] accts = mAccountManager.getAccountsByType(SyncConstants.ACCOUNTTYPE_SYNC);
-    if (accts.length == 0) {
-      // Error, no account present.
-      Logger.error(LOG_TAG, "No accounts present.");
-      displayAbort(Constants.JPAKE_ERROR_INVALID);
-      return;
-    }
-
-    // TODO: Single account supported. Create account selection if spec changes.
-    Account account = accts[0];
-    String username  = account.name;
-    String password  = mAccountManager.getPassword(account);
-    String syncKey   = mAccountManager.getUserData(account, Constants.OPTION_SYNCKEY);
-    String serverURL = mAccountManager.getUserData(account, Constants.OPTION_SERVER);
-
-    JSONObject jAccount = makeAccountJSON(username, password, syncKey, serverURL);
-    try {
-      jClient.sendAndComplete(jAccount);
-    } catch (JPakeNoActivePairingException e) {
-      Logger.error(LOG_TAG, "No active J-PAKE pairing.", e);
-      displayAbort(Constants.JPAKE_ERROR_INVALID);
-    }
-  }
-
-  /**
-   * J-PAKE pairing has started, but when this device has generated the PIN for
-   * pairing, does not require UI feedback to user.
-   */
-  public void onPairingStart() {
-    if (!pairWithPin) {
-      runOnUiThread(new Runnable() {
-        @Override
-        public void run() {
-          setContentView(R.layout.sync_setup_jpake_waiting);
-        }
-      });
-      return;
-    }
-  }
-
-  /**
-   * On J-PAKE completion, store the Sync Account credentials sent by other
-   * device. Display progress to user.
-   *
-   * @param jCreds
-   */
-  public void onComplete(JSONObject jCreds) {
-    if (!pairWithPin) {
-      // Create account from received credentials.
-      String accountName  = (String) jCreds.get(Constants.JSON_KEY_ACCOUNT);
-      String password     = (String) jCreds.get(Constants.JSON_KEY_PASSWORD);
-      String syncKey      = (String) jCreds.get(Constants.JSON_KEY_SYNCKEY);
-      String serverURL    = (String) jCreds.get(Constants.JSON_KEY_SERVER);
-
-      // The password we get is double-encoded.
-      try {
-        password = Utils.decodeUTF8(password);
-      } catch (UnsupportedEncodingException e) {
-        Logger.warn(LOG_TAG, "Unsupported encoding when decoding UTF-8 ASCII J-PAKE message. Ignoring.");
-      }
-
-      final SyncAccountParameters syncAccount = new SyncAccountParameters(mContext, mAccountManager, accountName,
-                                                                          syncKey, password, serverURL);
-      createAccountOnThread(syncAccount);
-    } else {
-      // No need to create an account; just clean up.
-      displayResultAndFinish(true);
-    }
-  }
-
-  private void displayResultAndFinish(final boolean isSuccess) {
-    jClient = null;
-    runOnUiThread(new Runnable() {
-      @Override
-      public void run() {
-        int result = isSuccess ? RESULT_OK : RESULT_CANCELED;
-        setResult(result);
-        displayResult(isSuccess);
-      }
-    });
-  }
-
-  private void createAccountOnThread(final SyncAccountParameters syncAccount) {
-    ThreadPool.run(new Runnable() {
-      @Override
-      public void run() {
-        Account account = SyncAccounts.createSyncAccount(syncAccount);
-        boolean isSuccess = (account != null);
-        if (isSuccess) {
-          Bundle resultBundle = new Bundle();
-          resultBundle.putString(AccountManager.KEY_ACCOUNT_NAME, syncAccount.username);
-          resultBundle.putString(AccountManager.KEY_ACCOUNT_TYPE, SyncConstants.ACCOUNTTYPE_SYNC);
-          resultBundle.putString(AccountManager.KEY_AUTHTOKEN, SyncConstants.ACCOUNTTYPE_SYNC);
-          setAccountAuthenticatorResult(resultBundle);
-        }
-        displayResultAndFinish(isSuccess);
-      }
-    });
-  }
-
-  /*
-   * Helper functions
-   */
-  private void activateButton(Button button, boolean toActivate) {
-    button.setEnabled(toActivate);
-    button.setClickable(toActivate);
-  }
-
-  private void enablePinEntry(boolean toEnable) {
-    row1.setEnabled(toEnable);
-    row2.setEnabled(toEnable);
-    row3.setEnabled(toEnable);
-  }
-
-  /**
-   * Displays Sync account setup result to user.
-   *
-   * @param isSetup
-   *          true if account was set up successfully, false otherwise.
-   */
-  private void displayResult(boolean isSuccess) {
-    Intent intent = null;
-    if (isSuccess) {
-      intent = new Intent(mContext, SetupSuccessActivity.class);
-      intent.setFlags(Constants.FLAG_ACTIVITY_REORDER_TO_FRONT_NO_ANIMATION);
-      intent.putExtra(Constants.INTENT_EXTRA_IS_SETUP, !pairWithPin);
-      startActivity(intent);
-      finish();
-    } else {
-      intent = new Intent(mContext, SetupFailureActivity.class);
-      intent.putExtra(Constants.INTENT_EXTRA_IS_ACCOUNTERROR, true);
-      intent.setFlags(Constants.FLAG_ACTIVITY_REORDER_TO_FRONT_NO_ANIMATION);
-      intent.putExtra(Constants.INTENT_EXTRA_IS_SETUP, !pairWithPin);
-      startActivity(intent);
-      // Do not finish, so user can retry setup by hitting "back."
-    }
-  }
-
-  /**
-   * Validate PIN entry fields to check if the three PIN entry fields are all
-   * filled in.
-   *
-   * @return true, if all PIN fields have 4 characters, false otherwise
-   */
-  private boolean pinEntryCompleted() {
-    if (row1.length() == 4 &&
-        row2.length() == 4 &&
-        row3.length() == 4) {
-      return true;
-    }
-    return false;
-  }
-
-  private boolean hasInternet() {
-    Logger.debug(LOG_TAG, "Checking internet connectivity.");
-    ConnectivityManager connManager = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
-    NetworkInfo network = connManager.getActiveNetworkInfo();
-
-    if (network != null && network.isConnected()) {
-      Logger.debug(LOG_TAG, network + " is connected.");
-      return true;
-    }
-    Logger.debug(LOG_TAG, "No connected networks.");
-    return false;
-  }
-
-  /**
-   * Displays layout for entering a PIN from another device.
-   * A Sync Account has already been set up.
-   */
-  private void displayPairWithPin() {
-    Logger.debug(LOG_TAG, "PairWithPin initiated.");
-    runOnUiThread(new Runnable() {
-
-      @Override
-      public void run() {
-        setContentView(R.layout.sync_setup_pair);
-        connectButton = (Button) findViewById(R.id.pair_button_connect);
-        pinError = (LinearLayout) findViewById(R.id.pair_error);
-
-        row1 = (EditText) findViewById(R.id.pair_row1);
-        row2 = (EditText) findViewById(R.id.pair_row2);
-        row3 = (EditText) findViewById(R.id.pair_row3);
-
-        row1.addTextChangedListener(new TextWatcher() {
-          @Override
-          public void afterTextChanged(Editable s) {
-             activateButton(connectButton, pinEntryCompleted());
-             if (s.length() == 4) {
-               row2.requestFocus();
-             }
-          }
-
-          @Override
-          public void beforeTextChanged(CharSequence s, int start, int count,
-              int after) {
-          }
-
-          @Override
-          public void onTextChanged(CharSequence s, int start, int before, int count) {
-          }
-
-        });
-        row2.addTextChangedListener(new TextWatcher() {
-          @Override
-          public void afterTextChanged(Editable s) {
-            activateButton(connectButton, pinEntryCompleted());
-            if (s.length() == 4) {
-              row3.requestFocus();
-            }
-          }
-
-          @Override
-          public void beforeTextChanged(CharSequence s, int start, int count,
-              int after) {
-          }
-
-          @Override
-          public void onTextChanged(CharSequence s, int start, int before, int count) {
-          }
-
-        });
-
-        row3.addTextChangedListener(new TextWatcher() {
-          @Override
-          public void afterTextChanged(Editable s) {
-            activateButton(connectButton, pinEntryCompleted());
-          }
-
-          @Override
-          public void beforeTextChanged(CharSequence s, int start, int count,
-              int after) {
-          }
-
-          @Override
-          public void onTextChanged(CharSequence s, int start, int before, int count) {
-          }
-        });
-
-        row1.requestFocus();
-      }
-    });
-  }
-
-  /**
-   * Displays layout with PIN for pairing with another device.
-   * No Sync Account has been set up yet.
-   */
-  private void displayReceiveNoPin() {
-    Logger.debug(LOG_TAG, "ReceiveNoPin initiated");
-    runOnUiThread(new Runnable(){
-
-      @Override
-      public void run() {
-        setContentView(R.layout.sync_setup);
-
-        // Set up UI.
-        pinTextView1 = ((TextView) findViewById(R.id.text_pin1));
-        pinTextView2 = ((TextView) findViewById(R.id.text_pin2));
-        pinTextView3 = ((TextView) findViewById(R.id.text_pin3));
-      }
-    });
-  }
-
-  @Override
-  public void onActivityResult(int requestCode, int resultCode, Intent data) {
-    switch (resultCode) {
-    case Activity.RESULT_OK:
-      // Setup completed in manual setup.
-      finish();
-    }
-  }
-}
deleted file mode 100644
--- a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/setup/activities/SyncActivity.java
+++ /dev/null
@@ -1,27 +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.sync.setup.activities;
-
-import android.app.Activity;
-import android.os.Bundle;
-
-/**
- * Shared superclass of Sync activities. Currently exists to prepare per-thread
- * logging.
- */
-public abstract class SyncActivity extends Activity {
-
-  @Override
-  protected void onResume() {
-    super.onResume();
-    ActivityUtils.prepareLogging();
-  }
-
-  @Override
-  public void onCreate(Bundle savedInstanceState) {
-    super.onCreate(savedInstanceState);
-    ActivityUtils.prepareLogging();
-  }
-}
deleted file mode 100644
--- a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/setup/activities/WebViewActivity.java
+++ /dev/null
@@ -1,61 +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.sync.setup.activities;
-
-import org.mozilla.gecko.R;
-import org.mozilla.gecko.background.common.log.Logger;
-
-import android.app.Activity;
-import android.net.Uri;
-import android.os.Bundle;
-import android.view.Window;
-import android.webkit.WebChromeClient;
-import android.webkit.WebView;
-import android.webkit.WebViewClient;
-
-/**
- * Displays URI in an embedded WebView. Closes if there no URI is passed in.
- * @author liuche
- *
- */
-public class WebViewActivity extends SyncActivity {
-  private final static String LOG_TAG = "WebViewActivity";
-
-  @Override
-  public void onCreate(Bundle savedInstanceState) {
-    super.onCreate(savedInstanceState);
-    getWindow().requestFeature(Window.FEATURE_PROGRESS);
-    setContentView(R.layout.sync_setup_webview);
-    // Extract URI to launch from Intent.
-    Uri uri = this.getIntent().getData();
-    if (uri == null) {
-      Logger.debug(LOG_TAG, "No URI passed to display.");
-      finish();
-      return;
-    }
-
-    WebView wv = (WebView) findViewById(R.id.web_engine);
-    // Add a progress bar.
-    final Activity activity = this;
-    wv.setWebChromeClient(new WebChromeClient() {
-      @Override
-      public void onProgressChanged(WebView view, int progress) {
-        // Activities and WebViews measure progress with different scales.
-        // The progress meter will automatically disappear when we reach 100%
-        activity.setProgress(progress * 100);
-      }
-    });
-    wv.setWebViewClient(new WebViewClient() {
-      // Handle url loading in this WebView, instead of asking the ActivityManager.
-      @Override
-      public boolean shouldOverrideUrlLoading(WebView view, String url) {
-        view.loadUrl(url);
-        return false;
-      }
-    });
-    wv.loadUrl(uri.toString());
-
-  }
-}
deleted file mode 100644
--- a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/setup/auth/AccountAuthenticator.java
+++ /dev/null
@@ -1,105 +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.sync.setup.auth;
-
-import java.util.LinkedList;
-import java.util.Queue;
-
-import org.mozilla.gecko.background.common.log.Logger;
-import org.mozilla.gecko.sync.ThreadPool;
-import org.mozilla.gecko.sync.Utils;
-import org.mozilla.gecko.sync.setup.activities.AccountActivity;
-
-public class AccountAuthenticator {
-  private final String LOG_TAG = "AccountAuthenticator";
-
-  private final AccountActivity activityCallback;
-  private Queue<AuthenticatorStage> stages;
-
-  // Values for authentication.
-  public String password;
-  public String username;
-
-  public String authServer;
-  public String nodeServer;
-
-  public boolean isSuccess = false;
-  public boolean isCanceled = false;
-
-  public AccountAuthenticator(AccountActivity activity) {
-    activityCallback = activity;
-    prepareStages();
-  }
-
-  private void prepareStages() {
-    stages = new LinkedList<AuthenticatorStage>();
-    stages.add(new EnsureUserExistenceStage());
-    stages.add(new FetchUserNodeStage());
-    stages.add(new AuthenticateAccountStage());
-  }
-
-  public void authenticate(String server, String account, String password) {
-    // Set authentication values.
-    if (!server.endsWith("/")) {
-      server += "/";
-    }
-    nodeServer = server;
-    this.password = password;
-
-    // Calculate and save username hash.
-    try {
-      username = Utils.usernameFromAccount(account);
-    } catch (Exception e) {
-      abort(AuthenticationResult.FAILURE_OTHER, e);
-      return;
-    }
-    Logger.pii(LOG_TAG, "Username:" + username);
-    Logger.debug(LOG_TAG, "Running first stage.");
-    // Start first stage of authentication.
-    runNextStage();
-  }
-
-  /**
-   * Run next stage of authentication.
-   */
-  public void runNextStage() {
-    if (isCanceled) {
-      return;
-    }
-    if (stages.size() == 0) {
-      Logger.debug(LOG_TAG, "Authentication completed.");
-      activityCallback.authCallback(isSuccess ? AuthenticationResult.SUCCESS : AuthenticationResult.FAILURE_PASSWORD);
-      return;
-    }
-    AuthenticatorStage nextStage = stages.remove();
-    try {
-      nextStage.execute(this);
-    } catch (Exception e) {
-      Logger.warn(LOG_TAG, "Unhandled exception in stage " + nextStage);
-      abort(AuthenticationResult.FAILURE_OTHER, e);
-    }
-  }
-
-  /**
-   * Abort authentication.
-   *
-   * @param result
-   *    returned to callback.
-   * @param e
-   *    Exception causing abort.
-   */
-  public void abort(AuthenticationResult result, Exception e) {
-    if (isCanceled) {
-      return;
-    }
-    Logger.warn(LOG_TAG, "Authentication failed.", e);
-    activityCallback.authCallback(result);
-  }
-
-  /* Helper functions */
-  public static void runOnThread(Runnable run) {
-    ThreadPool.run(run);
-  }
-}
deleted file mode 100644
--- a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/setup/auth/AuthenticateAccountStage.java
+++ /dev/null
@@ -1,176 +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.sync.setup.auth;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.UnsupportedEncodingException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.security.GeneralSecurityException;
-
-import org.mozilla.apache.commons.codec.binary.Base64;
-import org.mozilla.gecko.background.common.log.Logger;
-import org.mozilla.gecko.sync.SyncConstants;
-import org.mozilla.gecko.sync.net.BaseResource;
-import org.mozilla.gecko.sync.net.BaseResourceDelegate;
-import org.mozilla.gecko.sync.setup.Constants;
-
-import ch.boye.httpclientandroidlib.HttpResponse;
-import ch.boye.httpclientandroidlib.client.ClientProtocolException;
-import ch.boye.httpclientandroidlib.client.methods.HttpRequestBase;
-import ch.boye.httpclientandroidlib.impl.client.DefaultHttpClient;
-import ch.boye.httpclientandroidlib.message.BasicHeader;
-
-public class AuthenticateAccountStage implements AuthenticatorStage {
-  private final String LOG_TAG = "AuthAccountStage";
-  private HttpRequestBase httpRequest = null;
-
-  public interface AuthenticateAccountStageDelegate {
-    public void handleSuccess(boolean isSuccess);
-    public void handleFailure(HttpResponse response);
-    public void handleError(Exception e);
-  }
-
-  @Override
-  public void execute(final AccountAuthenticator aa) throws URISyntaxException, UnsupportedEncodingException {
-    AuthenticateAccountStageDelegate callbackDelegate = new AuthenticateAccountStageDelegate() {
-
-      @Override
-      public void handleSuccess(boolean isSuccess) {
-        aa.isSuccess = isSuccess;
-        aa.runNextStage();
-      }
-
-      @Override
-      public void handleFailure(HttpResponse response) {
-        Logger.debug(LOG_TAG, "handleFailure");
-        aa.abort(AuthenticationResult.FAILURE_OTHER, new Exception(response.getStatusLine().getStatusCode() + " error."));
-        if (response.getEntity() == null) {
-          // No cleanup necessary.
-          return;
-        }
-        try {
-          BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "UTF-8"));
-          BaseResource.consumeReader(reader);
-        } catch (IllegalStateException | IOException e) {
-          Logger.debug(LOG_TAG, "Error reading content.", e);
-        } catch (RuntimeException e) {
-          Logger.debug(LOG_TAG, "Unexpected exception.", e);
-          if (httpRequest != null) {
-            httpRequest.abort();
-          }
-        }
-      }
-
-      @Override
-      public void handleError(Exception e) {
-        Logger.debug(LOG_TAG, "handleError", e);
-        aa.abort(AuthenticationResult.FAILURE_OTHER, e);
-      }
-    };
-
-    // Calculate BasicAuth hash of username/password.
-    String authHeader = makeAuthHeader(aa.username, aa.password);
-    String authRequestUrl = makeAuthRequestUrl(aa.authServer, aa.username);
-    // Might contain plaintext username for old Sync accounts.
-    Logger.pii(LOG_TAG, "Making auth request to: " + authRequestUrl);
-    authenticateAccount(callbackDelegate, authRequestUrl, authHeader);
-
-  }
-
-  /**
-   * Makes an authentication request to the server and passes appropriate response back to callback.
-   * @param callbackDelegate
-   *        Delegate to deal with HTTP response.
-   * @param authRequestUrl
-   * @param authHeader
-   * @throws URISyntaxException
-   */
-  // Made public for testing.
-  public void authenticateAccount(final AuthenticateAccountStageDelegate callbackDelegate, final String authRequestUrl, final String authHeader) throws URISyntaxException {
-    final BaseResource httpResource = new BaseResource(authRequestUrl);
-    httpResource.delegate = new BaseResourceDelegate(httpResource) {
-      @Override
-      public String getUserAgent() {
-        return SyncConstants.USER_AGENT;
-      }
-
-      @Override
-      public void addHeaders(HttpRequestBase request, DefaultHttpClient client) {
-        // Make reference to request, to abort if necessary.
-        httpRequest = request;
-        client.log.enableDebug(true);
-        // Host header is not set for some reason, so do it explicitly.
-        try {
-          URI authServerUri = new URI(authRequestUrl);
-          request.setHeader(new BasicHeader("Host", authServerUri.getHost()));
-        } catch (URISyntaxException e) {
-          Logger.error(LOG_TAG, "Malformed uri, will be caught elsewhere.", e);
-        }
-        request.setHeader(new BasicHeader("Authorization", authHeader));
-      }
-
-      @Override
-      public void handleHttpResponse(HttpResponse response) {
-        int statusCode = response.getStatusLine().getStatusCode();
-        try {
-          switch (statusCode) {
-          case 200:
-            callbackDelegate.handleSuccess(true);
-            break;
-          case 401:
-            callbackDelegate.handleSuccess(false);
-            break;
-          default:
-            callbackDelegate.handleFailure(response);
-          }
-        } finally {
-          BaseResource.consumeEntity(response.getEntity());
-          Logger.info(LOG_TAG, "Released entity.");
-        }
-      }
-
-      @Override
-      public void handleHttpProtocolException(ClientProtocolException e) {
-        Logger.error(LOG_TAG, "Client protocol error.", e);
-        callbackDelegate.handleError(e);
-      }
-
-      @Override
-      public void handleHttpIOException(IOException e) {
-        Logger.error(LOG_TAG, "I/O exception.");
-        callbackDelegate.handleError(e);
-      }
-
-      @Override
-      public void handleTransportException(GeneralSecurityException e) {
-        Logger.error(LOG_TAG, "Transport exception.");
-        callbackDelegate.handleError(e);
-      }
-    };
-
-    AccountAuthenticator.runOnThread(new Runnable() {
-      @Override
-      public void run() {
-        httpResource.get();
-      }
-    });
-  }
-
-  public String makeAuthHeader(String usernameHash, String password) {
-    try {
-      return "Basic " + Base64.encodeBase64String((usernameHash + ":" + password).getBytes("UTF-8"));
-    } catch (UnsupportedEncodingException e) {
-      Logger.debug(LOG_TAG, "Unsupported encoding: UTF-8.");
-      return null;
-    }
-  }
-
-  public String makeAuthRequestUrl(String authServer, String usernameHash) {
-    return authServer + Constants.AUTH_SERVER_VERSION + usernameHash + "/" + Constants.AUTH_SERVER_SUFFIX;
-  }
-}
deleted file mode 100644
--- a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/setup/auth/AuthenticationResult.java
+++ /dev/null
@@ -1,9 +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.sync.setup.auth;
-
-public enum AuthenticationResult {
-  SUCCESS, FAILURE_USERNAME, FAILURE_PASSWORD, FAILURE_SERVER, FAILURE_ACCOUNT, FAILURE_OTHER
-}
deleted file mode 100644
--- a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/setup/auth/AuthenticatorStage.java
+++ /dev/null
@@ -1,12 +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.sync.setup.auth;
-
-import java.io.UnsupportedEncodingException;
-import java.net.URISyntaxException;
-
-public interface AuthenticatorStage {
-  public void execute(AccountAuthenticator aa) throws URISyntaxException, UnsupportedEncodingException;
-}
deleted file mode 100644
--- a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/setup/auth/EnsureUserExistenceStage.java
+++ /dev/null
@@ -1,121 +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.sync.setup.auth;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.UnsupportedEncodingException;
-import java.net.URISyntaxException;
-import java.security.GeneralSecurityException;
-
-import org.mozilla.gecko.background.common.log.Logger;
-import org.mozilla.gecko.sync.SyncConstants;
-import org.mozilla.gecko.sync.net.BaseResource;
-import org.mozilla.gecko.sync.net.BaseResourceDelegate;
-
-import ch.boye.httpclientandroidlib.HttpResponse;
-import ch.boye.httpclientandroidlib.client.ClientProtocolException;
-
-public class EnsureUserExistenceStage implements AuthenticatorStage {
-  private final String LOG_TAG = "EnsureUserExistence";
-
-  public interface EnsureUserExistenceStageDelegate {
-    public void handleSuccess();
-    public void handleFailure(AuthenticationResult result);
-    public void handleError(Exception e);
-  }
-  @Override
-  public void execute(final AccountAuthenticator aa) throws URISyntaxException,
-      UnsupportedEncodingException {
-    final EnsureUserExistenceStageDelegate callbackDelegate = new EnsureUserExistenceStageDelegate() {
-
-      @Override
-      public void handleSuccess() {
-        // User exists; now determine auth node.
-        Logger.debug(LOG_TAG, "handleSuccess()");
-        aa.runNextStage();
-      }
-
-      @Override
-      public void handleFailure(AuthenticationResult result) {
-        aa.abort(result, new Exception("Failure in EnsureUser"));
-      }
-
-      @Override
-      public void handleError(Exception e) {
-        Logger.info(LOG_TAG, "Error checking for user existence.");
-        aa.abort(AuthenticationResult.FAILURE_SERVER, e);
-      }
-
-    };
-
-    // This is not the same as Utils.nodeWeaveURL: it's missing the trailing node/weave.
-    String userRequestUrl = aa.nodeServer + "user/1.0/" + aa.username;
-    final BaseResource httpResource = new BaseResource(userRequestUrl);
-    httpResource.delegate = new BaseResourceDelegate(httpResource) {
-      @Override
-      public String getUserAgent() {
-        return SyncConstants.USER_AGENT;
-      }
-
-      @Override
-      public void handleHttpResponse(HttpResponse response) {
-        int statusCode = response.getStatusLine().getStatusCode();
-        switch(statusCode) {
-        case 200:
-          try {
-            InputStream content = response.getEntity().getContent();
-            BufferedReader reader = new BufferedReader(new InputStreamReader(content, "UTF-8"), 1024);
-            String inUse = reader.readLine();
-            BaseResource.consumeReader(reader);
-            reader.close();
-            // Removed Logger.debug inUse, because stalling.
-            if (inUse.equals("1")) { // Username exists.
-              callbackDelegate.handleSuccess();
-            } else { // User does not exist.
-              Logger.info(LOG_TAG, "No such user.");
-              callbackDelegate.handleFailure(AuthenticationResult.FAILURE_USERNAME);
-            }
-          } catch (Exception e) {
-            Logger.error(LOG_TAG, "Failure in content parsing.", e);
-            callbackDelegate.handleFailure(AuthenticationResult.FAILURE_OTHER);
-          }
-          break;
-        default: // No other response is acceptable.
-          callbackDelegate.handleFailure(AuthenticationResult.FAILURE_OTHER);
-        }
-        Logger.debug(LOG_TAG, "Consuming entity.");
-        BaseResource.consumeEntity(response.getEntity());
-      }
-
-      @Override
-      public void handleHttpProtocolException(ClientProtocolException e) {
-        callbackDelegate.handleError(e);
-      }
-
-      @Override
-      public void handleHttpIOException(IOException e) {
-        callbackDelegate.handleError(e);
-      }
-
-      @Override
-      public void handleTransportException(GeneralSecurityException e) {
-        callbackDelegate.handleError(e);
-      }
-
-    };
-    // Make request.
-    AccountAuthenticator.runOnThread(new Runnable() {
-
-      @Override
-      public void run() {
-        httpResource.get();
-      }
-    });
-  }
-
-}
deleted file mode 100644
--- a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/setup/auth/FetchUserNodeStage.java
+++ /dev/null
@@ -1,130 +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.sync.setup.auth;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.net.URISyntaxException;
-import java.security.GeneralSecurityException;
-
-import org.mozilla.gecko.background.common.log.Logger;
-import org.mozilla.gecko.sync.SyncConstants;
-import org.mozilla.gecko.sync.Utils;
-import org.mozilla.gecko.sync.net.BaseResource;
-import org.mozilla.gecko.sync.net.BaseResourceDelegate;
-
-import ch.boye.httpclientandroidlib.HttpResponse;
-import ch.boye.httpclientandroidlib.client.ClientProtocolException;
-
-public class FetchUserNodeStage implements AuthenticatorStage {
-  private final String LOG_TAG = "FetchUserNodeStage";
-
-  public interface FetchNodeStageDelegate {
-    public void handleSuccess(String url);
-    public void handleFailure(HttpResponse response);
-    public void handleError(Exception e);
-  }
-
-  @Override
-  public void execute(final AccountAuthenticator aa) throws URISyntaxException {
-
-    FetchNodeStageDelegate callbackDelegate = new FetchNodeStageDelegate() {
-
-      @Override
-      public void handleSuccess(String server) {
-        if (server == null) { // No separate auth node; use server url.
-          Logger.debug(LOG_TAG, "Using server as auth node.");
-          aa.authServer = aa.nodeServer;
-          aa.runNextStage();
-          return;
-        }
-        if (!server.endsWith("/")) {
-          server += "/";
-        }
-        aa.authServer = server;
-        aa.runNextStage();
-      }
-
-      @Override
-      public void handleFailure(HttpResponse response) {
-        int statusCode = response.getStatusLine().getStatusCode();
-        Logger.debug(LOG_TAG, "Failed to fetch user node, with status " + statusCode);
-        aa.abort(AuthenticationResult.FAILURE_OTHER, new Exception("HTTP " + statusCode + " error."));
-      }
-
-      @Override
-      public void handleError(Exception e) {
-        Logger.debug(LOG_TAG, "Error in fetching node.");
-        aa.abort(AuthenticationResult.FAILURE_OTHER, e);
-      }
-    };
-    String nodeRequestUrl = Utils.nodeWeaveURL(aa.nodeServer, aa.username);
-    // Might contain a plaintext username in the case of old Sync accounts.
-    Logger.pii(LOG_TAG, "NodeUrl: " + nodeRequestUrl);
-    final BaseResource httpResource = makeFetchNodeRequest(callbackDelegate, nodeRequestUrl);
-    // Make request on separate thread.
-    AccountAuthenticator.runOnThread(new Runnable() {
-      @Override
-      public void run() {
-        httpResource.get();
-      }
-    });
-  }
-
-  private BaseResource makeFetchNodeRequest(final FetchNodeStageDelegate callbackDelegate, String fetchNodeUrl) throws URISyntaxException {
-    // Fetch node containing user.
-    final BaseResource httpResource = new BaseResource(fetchNodeUrl);
-    httpResource.delegate = new BaseResourceDelegate(httpResource) {
-      @Override
-      public String getUserAgent() {
-        return SyncConstants.USER_AGENT;
-      }
-
-      @Override
-      public void handleHttpResponse(HttpResponse response) {
-        int statusCode = response.getStatusLine().getStatusCode();
-        switch(statusCode) {
-        case 200:
-          try {
-            InputStream content = response.getEntity().getContent();
-            BufferedReader reader = new BufferedReader(new InputStreamReader(content, "UTF-8"), 1024);
-            String server = reader.readLine();
-            callbackDelegate.handleSuccess(server);
-            BaseResource.consumeReader(reader);
-            reader.close();
-          } catch (IllegalStateException | IOException e) {
-            callbackDelegate.handleError(e);
-          }
-          break;
-        case 404: // Does not support auth nodes, use server instead.
-          callbackDelegate.handleSuccess(null);
-          break;
-        default:
-          // No other acceptable states.
-          callbackDelegate.handleFailure(response);
-        }
-        BaseResource.consumeEntity(response.getEntity());
-      }
-
-      @Override
-      public void handleHttpProtocolException(ClientProtocolException e) {
-        callbackDelegate.handleError(e);
-      }
-
-      @Override
-      public void handleHttpIOException(IOException e) {
-        callbackDelegate.handleError(e);
-      }
-
-      @Override
-      public void handleTransportException(GeneralSecurityException e) {
-        callbackDelegate.handleError(e);
-      }
-    };
-    return httpResource;
-  }
-}
\ No newline at end of file
deleted file mode 100644
--- a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/syncadapter/SyncAdapter.java
+++ /dev/null
@@ -1,628 +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.sync.syncadapter;
-
-import java.io.IOException;
-import java.net.URI;
-import java.security.NoSuchAlgorithmException;
-import java.util.Collection;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import org.json.simple.parser.ParseException;
-import org.mozilla.gecko.AppConstants;
-import org.mozilla.gecko.background.common.GlobalConstants;
-import org.mozilla.gecko.background.common.log.Logger;
-import org.mozilla.gecko.db.BrowserContract;
-import org.mozilla.gecko.fxa.FxAccountConstants;
-import org.mozilla.gecko.sync.AlreadySyncingException;
-import org.mozilla.gecko.sync.BackoffHandler;
-import org.mozilla.gecko.sync.CredentialException;
-import org.mozilla.gecko.sync.GlobalSession;
-import org.mozilla.gecko.sync.NonObjectJSONException;
-import org.mozilla.gecko.sync.PrefsBackoffHandler;
-import org.mozilla.gecko.sync.SharedPreferencesClientsDataDelegate;
-import org.mozilla.gecko.sync.SharedPreferencesNodeAssignmentCallback;
-import org.mozilla.gecko.sync.Sync11Configuration;
-import org.mozilla.gecko.sync.SyncConfiguration;
-import org.mozilla.gecko.sync.SyncConfigurationException;
-import org.mozilla.gecko.sync.SyncConstants;
-import org.mozilla.gecko.sync.SyncException;
-import org.mozilla.gecko.sync.ThreadPool;
-import org.mozilla.gecko.sync.Utils;
-import org.mozilla.gecko.sync.config.AccountPickler;
-import org.mozilla.gecko.sync.crypto.CryptoException;
-import org.mozilla.gecko.sync.crypto.KeyBundle;
-import org.mozilla.gecko.sync.delegates.BaseGlobalSessionCallback;
-import org.mozilla.gecko.sync.delegates.ClientsDataDelegate;
-import org.mozilla.gecko.sync.net.AuthHeaderProvider;
-import org.mozilla.gecko.sync.net.BasicAuthHeaderProvider;
-import org.mozilla.gecko.sync.net.ConnectionMonitorThread;
-import org.mozilla.gecko.sync.receivers.SyncAccountDeletedService;
-import org.mozilla.gecko.sync.setup.Constants;
-import org.mozilla.gecko.sync.setup.SyncAccounts;
-import org.mozilla.gecko.sync.setup.SyncAccounts.SyncAccountParameters;
-import org.mozilla.gecko.sync.stage.GlobalSyncStage.Stage;
-
-import android.accounts.Account;
-import android.accounts.AccountManager;
-import android.accounts.AuthenticatorException;
-import android.accounts.OperationCanceledException;
-import android.content.AbstractThreadedSyncAdapter;
-import android.content.ContentProviderClient;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.content.SyncResult;
-import android.database.sqlite.SQLiteConstraintException;
-import android.database.sqlite.SQLiteException;
-import android.os.Bundle;
-
-public class SyncAdapter extends AbstractThreadedSyncAdapter implements BaseGlobalSessionCallback {
-  private static final String  LOG_TAG = "SyncAdapter";
-
-  private static final int     BACKOFF_PAD_SECONDS = 5;
-  public  static final int     MULTI_DEVICE_INTERVAL_MILLISECONDS = 5 * 60 * 1000;         // 5 minutes.
-  public  static final int     SINGLE_DEVICE_INTERVAL_MILLISECONDS = 24 * 60 * 60 * 1000;  // 24 hours.
-
-  private final Context        mContext;
-
-  protected long syncStartTimestamp;
-
-  protected volatile BackoffHandler backoffHandler;
-
-  public SyncAdapter(Context context, boolean autoInitialize) {
-    super(context, autoInitialize);
-    mContext = context;
-  }
-
-  /**
-   * Handle an exception: update stats, log errors, etc.
-   * Wakes up sleeping threads by calling notifyMonitor().
-   *
-   * @param globalSession
-   *          current global session, or null.
-   * @param e
-   *          Exception to handle.
-   */
-  protected void processException(final GlobalSession globalSession, final Exception e) {
-    try {
-      if (e instanceof SQLiteConstraintException) {
-        Logger.error(LOG_TAG, "Constraint exception. Aborting sync.", e);
-        syncResult.stats.numParseExceptions++;       // This is as good as we can do.
-        return;
-      }
-      if (e instanceof SQLiteException) {
-        Logger.error(LOG_TAG, "Couldn't open database (locked?). Aborting sync.", e);
-        syncResult.stats.numIoExceptions++;
-        return;
-      }
-      if (e instanceof OperationCanceledException) {
-        Logger.error(LOG_TAG, "Operation canceled. Aborting sync.", e);
-        return;
-      }
-      if (e instanceof AuthenticatorException) {
-        syncResult.stats.numParseExceptions++;
-        Logger.error(LOG_TAG, "AuthenticatorException. Aborting sync.", e);
-        return;
-      }
-      if (e instanceof IOException) {
-        syncResult.stats.numIoExceptions++;
-        Logger.error(LOG_TAG, "IOException. Aborting sync.", e);
-        e.printStackTrace();
-        return;
-      }
-
-      // Blanket stats updating for SyncException subclasses.
-      if (e instanceof SyncException) {
-        ((SyncException) e).updateStats(globalSession, syncResult);
-      } else {
-        // Generic exception.
-        syncResult.stats.numIoExceptions++;
-      }
-
-      if (e instanceof CredentialException.MissingAllCredentialsException) {
-        // This is bad: either we couldn't fetch credentials, or the credentials
-        // were totally blank. Most likely the user has two copies of Firefox
-        // installed, and something is misbehaving.
-        // Either way, disable this account.
-        if (localAccount == null) {
-          // Should not happen, but be safe.
-          Logger.error(LOG_TAG, "No credentials attached to account. Aborting sync.");
-          return;
-        }
-
-        Logger.error(LOG_TAG, "No credentials attached to account " + localAccount.name + ". Aborting sync.");
-        try {
-          SyncAccounts.setSyncAutomatically(localAccount, false);
-        } catch (Exception ex) {
-          Logger.error(LOG_TAG, "Unable to disable account " + localAccount.name + ".", ex);
-        }
-        return;
-      }
-
-      if (e instanceof CredentialException.MissingCredentialException) {
-        Logger.error(LOG_TAG, "Credentials attached to account, but missing " +
-            ((CredentialException.MissingCredentialException) e).missingCredential + ". Aborting sync.");
-        return;
-      }
-
-      if (e instanceof CredentialException) {
-        Logger.error(LOG_TAG, "Credentials attached to account were bad.");
-        return;
-      }
-
-      // Bug 755638 - Uncaught SecurityException when attempting to sync multiple Fennecs
-      // to the same Sync account.
-      // Uncheck Sync checkbox because we cannot sync this instance.
-      if (e instanceof SecurityException) {
-        Logger.error(LOG_TAG, "SecurityException, multiple Fennecs. Disabling this instance.", e);
-        SyncAccounts.backgroundSetSyncAutomatically(localAccount, false);
-        return;
-      }
-      // Generic exception.
-      Logger.error(LOG_TAG, "Unknown exception. Aborting sync.", e);
-    } finally {
-      notifyMonitor();
-    }
-  }
-
-  @Override
-  public void onSyncCanceled() {
-    super.onSyncCanceled();
-    // TODO: cancel the sync!
-    // From the docs: "This will be invoked on a separate thread than the sync
-    // thread and so you must consider the multi-threaded implications of the
-    // work that you do in this method."
-  }
-
-  public Object syncMonitor = new Object();
-  private SyncResult syncResult;
-
-  protected Account localAccount;
-  protected boolean thisSyncIsForced = false;
-  protected SharedPreferences accountSharedPreferences;
-  protected SharedPreferencesClientsDataDelegate clientsDataDelegate;
-  protected SharedPreferencesNodeAssignmentCallback nodeAssignmentDelegate;
-
-  /**
-   * Request that no sync start right away.  A new sync won't start until
-   * at least <code>backoff</code> milliseconds from now.
-   *
-   * Don't call this unless you are inside `run`.
-   *
-   * @param backoff time to wait in milliseconds.
-   */
-  @Override
-  public void requestBackoff(final long backoff) {
-    if (this.backoffHandler == null) {
-      throw new IllegalStateException("No backoff handler: requesting backoff outside run()?");
-    }
-    if (backoff > 0) {
-      // Fuzz the backoff time (up to 25% more) to prevent client lock-stepping; agrees with desktop.
-      final long fuzzedBackoff = backoff + Math.round(backoff * 0.25d * Math.random());
-      this.backoffHandler.extendEarliestNextRequest(System.currentTimeMillis() + fuzzedBackoff);
-    }
-  }
-
-  @Override
-  public boolean shouldBackOffStorage() {
-    if (thisSyncIsForced) {
-      /*
-       * If the user asks us to sync, we should sync regardless. This path is
-       * hit if the user force syncs and we restart a session after a
-       * freshStart.
-       */
-      return false;
-    }
-
-    if (nodeAssignmentDelegate.wantNodeAssignment()) {
-      /*
-       * We recently had a 401 and we aborted the last sync. We should kick off
-       * another sync to fetch a new node/weave cluster URL, since ours is
-       * stale. If we have a user authentication error, the next sync will
-       * determine that and will stop requesting node assignment, so this will
-       * only force one abnormally scheduled sync.
-       */
-      return false;
-    }
-
-    if (this.backoffHandler == null) {
-      throw new IllegalStateException("No backoff handler: checking backoff outside run()?");
-    }
-    return this.backoffHandler.delayMilliseconds() > 0;
-  }
-
-  /**
-   * Asynchronously request an immediate sync, optionally syncing only the given
-   * named stages.
-   * <p>
-   * Returns immediately.
-   *
-   * @param account
-   *          the Android <code>Account</code> instance to sync.
-   * @param stageNames
-   *          stage names to sync, or <code>null</code> to sync all known stages.
-   */
-  public static void requestImmediateSync(final Account account, final String[] stageNames) {
-    requestImmediateSync(account, stageNames, null);
-  }
-
-  /**
-   * Asynchronously request an immediate sync, optionally syncing only the given
-   * named stages.
-   * <p>
-   * Returns immediately.
-   *
-   * @param account
-   *          the Android <code>Account</code> instance to sync.
-   * @param stageNames
-   *          stage names to sync, or <code>null</code> to sync all known stages.
-   * @param moreExtras
-   *          bundle of extras to give to the sync, or <code>null</code>
-   */
-  public static void requestImmediateSync(final Account account, final String[] stageNames, Bundle moreExtras) {
-    if (account == null) {
-      Logger.warn(LOG_TAG, "Not requesting immediate sync because Android Account is null.");
-      return;
-    }
-
-    final Bundle extras = new Bundle();
-    Utils.putStageNamesToSync(extras, stageNames, null);
-    extras.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
-
-    if (moreExtras != null) {
-      extras.putAll(moreExtras);
-    }
-
-    ContentResolver.requestSync(account, BrowserContract.AUTHORITY, extras);
-  }
-
-  @Override
-  public void onPerformSync(final Account account,
-                            final Bundle extras,
-                            final String authority,
-                            final ContentProviderClient provider,
-                            final SyncResult syncResult) {
-    syncStartTimestamp = System.currentTimeMillis();
-
-    Logger.setThreadLogTag(SyncConstants.GLOBAL_LOG_TAG);
-    Logger.resetLogging();
-    Utils.reseedSharedRandom(); // Make sure we don't work with the same random seed for too long.
-
-    // Set these so that we don't need to thread them through assorted calls and callbacks.
-    this.syncResult   = syncResult;
-    this.localAccount = account;
-
-    final AccountManager manager = AccountManager.get(mContext);
-    final SyncAccountParameters params;
-    try {
-      if ("1".equals(manager.getUserData(account, Constants.DATA_SHOULD_BE_REMOVED))) {
-        Logger.warn(LOG_TAG, "Account named like " + Utils.obfuscateEmail(account.name) + " should be removed. " +
-          "Removing and aborting sync.");
-        manager.removeAccount(account, null, null);
-        return;
-      }
-
-      params = SyncAccounts.blockingFromAndroidAccountV0(mContext, manager, this.localAccount);
-    } catch (Exception e) {
-      // Updates syncResult and (harmlessly) calls notifyMonitor().
-      processException(null, e);
-      return;
-    }
-
-    // params and the following fields are non-null at this point.
-    final String username  = params.username; // Encoded with Utils.usernameFromAccount.
-    final String password  = params.password;
-    final String serverURL = params.serverURL;
-    final String syncKey   = params.syncKey;
-
-    final AtomicBoolean setNextSync = new AtomicBoolean(true);
-    final SyncAdapter self = this;
-    final Runnable runnable = new Runnable() {
-      @Override
-      public void run() {
-        Logger.trace(LOG_TAG, "AccountManagerCallback invoked.");
-        // TODO: N.B.: Future must not be used on the main thread.
-        try {
-          if (Logger.LOG_PERSONAL_INFORMATION) {
-            Logger.pii(LOG_TAG, "Syncing account named " + account.name +
-                " for authority " + authority + ".");
-          } else {
-            // Replace "foo@bar.com" with "XXX@XXX.XXX".
-            Logger.info(LOG_TAG, "Syncing account named like " + Utils.obfuscateEmail(account.name) +
-                " for authority " + authority + ".");
-          }
-
-          // We dump this information right away to help with debugging.
-          Logger.debug(LOG_TAG, "Username: " + username);
-          Logger.debug(LOG_TAG, "Server:   " + serverURL);
-          if (Logger.LOG_PERSONAL_INFORMATION) {
-            Logger.debug(LOG_TAG, "Password: " + password);
-            Logger.debug(LOG_TAG, "Sync key: " + syncKey);
-          } else {
-            Logger.debug(LOG_TAG, "Password? " + (password != null));
-            Logger.debug(LOG_TAG, "Sync key? " + (syncKey != null));
-          }
-
-          // Support multiple accounts by mapping each server/account pair to a branch of the
-          // shared preferences space.
-          final String product = GlobalConstants.BROWSER_INTENT_PACKAGE;
-          final String profile = Constants.DEFAULT_PROFILE;
-          final long version = SyncConfiguration.CURRENT_PREFS_VERSION;
-          self.accountSharedPreferences = Utils.getSharedPreferences(mContext, product, username, serverURL, profile, version);
-          self.clientsDataDelegate = new SharedPreferencesClientsDataDelegate(accountSharedPreferences, mContext);
-          self.backoffHandler = new PrefsBackoffHandler(accountSharedPreferences, SyncConstants.BACKOFF_PREF_SUFFIX_11);
-          final String nodeWeaveURL = Utils.nodeWeaveURL(serverURL, username);
-          self.nodeAssignmentDelegate = new SharedPreferencesNodeAssignmentCallback(accountSharedPreferences, nodeWeaveURL);
-
-          Logger.info(LOG_TAG,
-              "Client is named '" + clientsDataDelegate.getClientName() + "'" +
-              ", has client guid " + clientsDataDelegate.getAccountGUID() +
-              ", and has " + clientsDataDelegate.getClientsCount() + " clients.");
-
-          final boolean thisSyncIsForced = (extras != null) && (extras.getBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, false));
-          final long delayMillis = backoffHandler.delayMilliseconds();
-          boolean shouldSync = thisSyncIsForced || (delayMillis <= 0L);
-          if (!shouldSync) {
-            long remainingSeconds = delayMillis / 1000;
-            syncResult.delayUntil = remainingSeconds + BACKOFF_PAD_SECONDS;
-            setNextSync.set(false);
-            self.notifyMonitor();
-            return;
-          }
-
-          final String prefsPath = Utils.getPrefsPath(product, username, serverURL, profile, version);
-          self.performSync(account, extras, authority, provider, syncResult,
-              username, password, prefsPath, serverURL, syncKey);
-        } catch (Exception e) {
-          self.processException(null, e);
-          return;
-        }
-      }
-    };
-
-    synchronized (syncMonitor) {
-      // Perform the work in a new thread from within this synchronized block,
-      // which allows us to be waiting on the monitor before the callback can
-      // notify us in a failure case. Oh, concurrent programming.
-      new Thread(runnable).start();
-
-      // Start our stale connection monitor thread.
-      ConnectionMonitorThread stale = new ConnectionMonitorThread();
-      stale.start();
-
-      Logger.trace(LOG_TAG, "Waiting on sync monitor.");
-      try {
-        syncMonitor.wait();
-
-        if (setNextSync.get()) {
-          long interval = getSyncInterval(clientsDataDelegate);
-          long next = System.currentTimeMillis() + interval;
-
-          if (thisSyncIsForced) {
-            Logger.info(LOG_TAG, "Setting minimum next sync time to " + next + " (" + interval + "ms from now).");
-            self.backoffHandler.setEarliestNextRequest(next);
-          } else {
-            Logger.info(LOG_TAG, "Extending minimum next sync time to " + next + " (" + interval + "ms from now).");
-            self.backoffHandler.extendEarliestNextRequest(next);
-          }
-        }
-        Logger.info(LOG_TAG, "Sync took " + Utils.formatDuration(syncStartTimestamp, System.currentTimeMillis()) + ".");
-      } catch (InterruptedException e) {
-        Logger.warn(LOG_TAG, "Waiting on sync monitor interrupted.", e);
-      } finally {
-        // And we're done with HTTP stuff.
-        stale.shutdown();
-      }
-    }
-  }
-
-  public int getSyncInterval(ClientsDataDelegate clientsDataDelegate) {
-    // Must have been a problem that means we can't access the Account.
-    if (this.localAccount == null) {
-      return SINGLE_DEVICE_INTERVAL_MILLISECONDS;
-    }
-
-    int clientsCount = clientsDataDelegate.getClientsCount();
-    if (clientsCount <= 1) {
-      return SINGLE_DEVICE_INTERVAL_MILLISECONDS;
-    }
-
-    return MULTI_DEVICE_INTERVAL_MILLISECONDS;
-  }
-
-  /**
-   * Now that we have a sync key and password, go ahead and do the work.
-   * @throws NoSuchAlgorithmException
-   * @throws IllegalArgumentException
-   * @throws SyncConfigurationException
-   * @throws AlreadySyncingException
-   * @throws NonObjectJSONException
-   * @throws ParseException
-   * @throws IOException
-   * @throws CryptoException
-   */
-  protected void performSync(final Account account,
-                             final Bundle extras,
-                             final String authority,
-                             final ContentProviderClient provider,
-                             final SyncResult syncResult,
-                             final String username,
-                             final String password,
-                             final String prefsPath,
-                             final String serverURL,
-                             final String syncKey)
-                                 throws NoSuchAlgorithmException,
-                                        SyncConfigurationException,
-                                        IllegalArgumentException,
-                                        AlreadySyncingException,
-                                        IOException, ParseException,
-                                        NonObjectJSONException, CryptoException {
-    Logger.trace(LOG_TAG, "Performing sync.");
-
-    /**
-     * Bug 769745: pickle Sync account parameters to JSON file. Un-pickle in
-     * <code>SyncAccounts.syncAccountsExist</code>.
-     */
-    try {
-      // Constructor can throw on nulls, which should not happen -- but let's be safe.
-      final SyncAccountParameters params = new SyncAccountParameters(mContext, null,
-        account.name, // Un-encoded, like "test@mozilla.com".
-        syncKey,
-        password,
-        serverURL,
-        null, // We'll re-fetch cluster URL; not great, but not harmful.
-        clientsDataDelegate.getClientName(),
-        clientsDataDelegate.getAccountGUID());
-
-      // Bug 772971: pickle Sync account parameters on background thread to
-      // avoid strict mode warnings.
-      ThreadPool.run(new Runnable() {
-        @Override
-        public void run() {
-          final boolean syncAutomatically = ContentResolver.getSyncAutomatically(account, authority);
-          try {
-            AccountPickler.pickle(mContext, Constants.ACCOUNT_PICKLE_FILENAME, params, syncAutomatically);
-          } catch (Exception e) {
-            // Should never happen, but we really don't want to die in a background thread.
-            Logger.warn(LOG_TAG, "Got exception pickling current account details; ignoring.", e);
-          }
-        }
-      });
-    } catch (IllegalArgumentException e) {
-      // Do nothing.
-    }
-
-    if (username == null) {
-      throw new IllegalArgumentException("username must not be null.");
-    }
-
-    if (syncKey == null) {
-      throw new SyncConfigurationException();
-    }
-
-    final KeyBundle keyBundle = new KeyBundle(username, syncKey);
-
-    if (keyBundle == null ||
-        keyBundle.getEncryptionKey() == null ||
-        keyBundle.getHMACKey() == null) {
-      throw new SyncConfigurationException();
-    }
-
-    final AuthHeaderProvider authHeaderProvider = new BasicAuthHeaderProvider(username, password);
-    final SharedPreferences prefs = getContext().getSharedPreferences(prefsPath, Utils.SHARED_PREFERENCES_MODE);
-    final SyncConfiguration config = new Sync11Configuration(username, authHeaderProvider, prefs, keyBundle);
-
-    Collection<String> knownStageNames = SyncConfiguration.validEngineNames();
-    config.stagesToSync = Utils.getStagesToSyncFromBundle(knownStageNames, extras);
-
-    GlobalSession globalSession = new GlobalSession(config, this, this.mContext, clientsDataDelegate, nodeAssignmentDelegate);
-    globalSession.start();
-  }
-
-  private void notifyMonitor() {
-    synchronized (syncMonitor) {
-      Logger.trace(LOG_TAG, "Notifying sync monitor.");
-      syncMonitor.notifyAll();
-    }
-  }
-
-  // Implementing GlobalSession callbacks.
-  @Override
-  public void handleError(GlobalSession globalSession, Exception ex) {
-    Logger.info(LOG_TAG, "GlobalSession indicated error.");
-    this.processException(globalSession, ex);
-  }
-
-  @Override
-  public void handleAborted(GlobalSession globalSession, String reason) {
-    Logger.warn(LOG_TAG, "Sync aborted: " + reason);
-    notifyMonitor();
-  }
-
-  @Override
-  public void handleSuccess(GlobalSession globalSession) {
-    Logger.info(LOG_TAG, "GlobalSession indicated success.");
-    globalSession.config.persistToPrefs();
-    notifyMonitor();
-  }
-
-  @Override
-  public void handleStageCompleted(Stage currentState,
-                                   GlobalSession globalSession) {
-    Logger.trace(LOG_TAG, "Stage completed: " + currentState);
-  }
-
-  @Override
-  public void informUnauthorizedResponse(GlobalSession session, URI oldClusterURL) {
-    nodeAssignmentDelegate.setClusterURLIsStale(true);
-  }
-
-  @Override
-  public void informUpgradeRequiredResponse(final GlobalSession session) {
-    final AccountManager manager = AccountManager.get(mContext);
-    final Account toDisable      = localAccount;
-    if (toDisable == null || manager == null) {
-      Logger.warn(LOG_TAG, "Attempting to disable account, but null found.");
-      return;
-    }
-    // Sync needs to be upgraded. Don't automatically sync anymore.
-    ThreadPool.run(new Runnable() {
-      @Override
-      public void run() {
-        manager.setUserData(toDisable, Constants.DATA_ENABLE_ON_UPGRADE, "1");
-        SyncAccounts.setSyncAutomatically(toDisable, false);
-      }
-    });
-  }
-
-  @Override
-  public void informMigrated(GlobalSession session) {
-    final AccountManager manager = AccountManager.get(mContext);
-    final Account account = localAccount;
-    if (account == null || manager == null) {
-      Logger.warn(LOG_TAG, "Attempting to mark account migrated, but no Account or AccountManager found.");
-      return;
-    }
-
-    // Mark the account as slated for deletion. We're going to try to wipe the
-    // account right now anyway, but if we fail, or a sync is triggered before
-    // we succeed, the next sync will see this flag, try to delete the account,
-    // and abort the sync.
-    manager.setUserData(account, Constants.DATA_SHOULD_BE_REMOVED, "1");
-
-    // We delete any existing pickle as soon as possible -- no sense unpickling
-    // an account scheduled for deletion.
-    SyncAccountDeletedService.deletePickle(mContext);
-
-    // We write an escape hatch pickle of the Old Sync Account parameters,
-    // just in case.
-    try {
-      final SyncAccountParameters params =
-          SyncAccounts.blockingFromAndroidAccountV0(mContext, manager, account);
-      AccountPickler.pickle(mContext, FxAccountConstants.OLD_SYNC_ACCOUNT_PICKLE_FILENAME, params, false);
-    } catch (Exception e) {
-      Logger.error(LOG_TAG, "Failed to pickle old Account; removing old Account without emergency pickle.", e);
-    }
-
-    // Try to remove this account entirely. We can't *guarantee* the account
-    // will be removed, but it's a good deal of effort to retry over time. An
-    // option would be to have the new Account we've migrated to try to clean up
-    // the old Account as well; we'll do that if we see problems in the wild.
-    try {
-      manager.removeAccount(account, null, null);
-    } catch (Exception e) {
-      // We should always be able to remove the Account, but it's Android --
-      // is one ever confident? We log, but crash for non-release builds.
-      // We want to know if we see problems in the wild.
-      if (AppConstants.RELEASE_BUILD) {
-        Logger.error(LOG_TAG, "Failed to remove account; ignoring and leaving old Account.", e);
-      } else {
-        Logger.error(LOG_TAG, "Failed to remove account; crashing.", e);
-        throw e;
-      }
-    }
-  }
-}
deleted file mode 100644
--- a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/syncadapter/SyncService.java
+++ /dev/null
@@ -1,35 +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.sync.syncadapter;
-
-import android.app.Service;
-import android.content.Intent;
-import android.os.IBinder;
-
-/**
- * Service to handle Account sync. This is invoked with an intent with action
- * ACTION_AUTHENTICATOR_INTENT. It instantiates the SyncAdaptor and returns its
- * IBinder.
- */
-public class SyncService extends Service {
-
-    private static final Object sSyncAdapterLock = new Object();
-
-    private static SyncAdapter sSyncAdapter = null;
-
-    @Override
-    public void onCreate() {
-        synchronized (sSyncAdapterLock) {
-            if (sSyncAdapter == null) {
-                sSyncAdapter = new SyncAdapter(getApplicationContext(), true);
-            }
-        }
-    }
-
-    @Override
-    public IBinder onBind(Intent intent) {
-        return sSyncAdapter.getSyncAdapterBinder();
-    }
-}
--- a/mobile/android/tests/background/junit3/background_junit3_sources.mozbuild
+++ b/mobile/android/tests/background/junit3/background_junit3_sources.mozbuild
@@ -61,25 +61,23 @@ background_junit3_sources = [
     'src/org/mozilla/gecko/background/sync/helpers/SessionTestHelper.java',
     'src/org/mozilla/gecko/background/sync/helpers/SimpleSuccessBeginDelegate.java',
     'src/org/mozilla/gecko/background/sync/helpers/SimpleSuccessCreationDelegate.java',
     'src/org/mozilla/gecko/background/sync/helpers/SimpleSuccessFetchDelegate.java',
     'src/org/mozilla/gecko/background/sync/helpers/SimpleSuccessFinishDelegate.java',
     'src/org/mozilla/gecko/background/sync/helpers/SimpleSuccessStoreDelegate.java',
     'src/org/mozilla/gecko/background/sync/TestClientsStage.java',
     'src/org/mozilla/gecko/background/sync/TestResetting.java',
-    'src/org/mozilla/gecko/background/sync/TestSendTabData.java',
     'src/org/mozilla/gecko/background/sync/TestStoreTracking.java',
     'src/org/mozilla/gecko/background/sync/TestSyncConfiguration.java',
     'src/org/mozilla/gecko/background/sync/TestTabsRecord.java',
     'src/org/mozilla/gecko/background/sync/TestWebURLFinder.java',
     'src/org/mozilla/gecko/background/testhelpers/BaseMockServerSyncStage.java',
     'src/org/mozilla/gecko/background/testhelpers/CommandHelpers.java',
     'src/org/mozilla/gecko/background/testhelpers/DefaultGlobalSessionCallback.java',
-    'src/org/mozilla/gecko/background/testhelpers/JPakeNumGeneratorFixed.java',
     'src/org/mozilla/gecko/background/testhelpers/MockAbstractNonRepositorySyncStage.java',
     'src/org/mozilla/gecko/background/testhelpers/MockClientsDatabaseAccessor.java',
     'src/org/mozilla/gecko/background/testhelpers/MockClientsDataDelegate.java',
     'src/org/mozilla/gecko/background/testhelpers/MockGlobalSession.java',
     'src/org/mozilla/gecko/background/testhelpers/MockPrefsGlobalSession.java',
     'src/org/mozilla/gecko/background/testhelpers/MockRecord.java',
     'src/org/mozilla/gecko/background/testhelpers/MockServerSyncStage.java',
     'src/org/mozilla/gecko/background/testhelpers/MockSharedPreferences.java',
--- a/mobile/android/tests/background/junit3/instrumentation.ini
+++ b/mobile/android/tests/background/junit3/instrumentation.ini
@@ -17,13 +17,12 @@ subsuite = background
 [src/org/mozilla/gecko/background/db/TestFennecTabsStorage.java]
 [src/org/mozilla/gecko/background/db/TestFormHistoryRepositorySession.java]
 [src/org/mozilla/gecko/background/db/TestPasswordsRepository.java]
 [src/org/mozilla/gecko/background/fxa/TestBrowserIDKeyPairGeneration.java]
 [src/org/mozilla/gecko/background/fxa/authenticator/TestAccountPickler.java]
 [src/org/mozilla/gecko/background/nativecode/test/TestNativeCrypto.java]
 [src/org/mozilla/gecko/background/sync/TestClientsStage.java]
 [src/org/mozilla/gecko/background/sync/TestResetting.java]
-[src/org/mozilla/gecko/background/sync/TestSendTabData.java]
 [src/org/mozilla/gecko/background/sync/TestStoreTracking.java]
 [src/org/mozilla/gecko/background/sync/TestSyncConfiguration.java]
 [src/org/mozilla/gecko/background/sync/TestTabsRecord.java]
 [src/org/mozilla/gecko/background/sync/TestWebURLFinder.java]
deleted file mode 100644
--- a/mobile/android/tests/background/junit3/src/org/mozilla/gecko/background/sync/TestSendTabData.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
-   http://creativecommons.org/publicdomain/zero/1.0/ */
-
-package org.mozilla.gecko.background.sync;
-
-import org.mozilla.gecko.background.helpers.AndroidSyncTestCase;
-import org.mozilla.gecko.sync.setup.activities.SendTabData;
-
-import android.content.Intent;
-
-/**
- * These tests are on device because the Intent, Pattern, and Matcher APIs are
- * stubs on desktop.
- */
-public class TestSendTabData extends AndroidSyncTestCase {
-  protected static Intent makeShareIntent(String text, String subject, String title) {
-    Intent intent = new Intent();
-
-    intent.putExtra(Intent.EXTRA_TEXT, text);
-    intent.putExtra(Intent.EXTRA_SUBJECT, subject);
-    intent.putExtra(Intent.EXTRA_TITLE, title);
-
-    return intent;
-  }
-
-  //  From Fennec:
-  //
-  //  I/FxSync  ( 7420): fennec :: SendTabActivity :: Send was clicked.
-  //  I/FxSync  ( 7420): fennec :: SendTabActivity :: android.intent.extra.TEXT -> http://www.reddit.com/
-  //  I/FxSync  ( 7420): fennec :: SendTabActivity :: android.intent.extra.SUBJECT -> reddit: the front page of the internet
-  public void testFennecBrowser() {
-    Intent shareIntent = makeShareIntent("http://www.reddit.com/",
-        "reddit: the front page of the internet",
-        null);
-    SendTabData fromIntent = SendTabData.fromIntent(shareIntent);
-
-    assertEquals("reddit: the front page of the internet", fromIntent.title);
-    assertEquals("http://www.reddit.com/", fromIntent.uri);
-  }
-
-  //  From Android Browser:
-  //
-  //  I/FxSync  ( 7420): fennec :: SendTabActivity :: Send was clicked.
-  //  I/FxSync  ( 7420): fennec :: SendTabActivity :: android.intent.extra.TEXT -> http://bl176w.blu176.mail.live.com/m/messages.m/?mid=m95277577-e5a5-11e1-bfeb-00237de49bb0&mts=2012-08-14T00%3a18%3a44.390Z&fid=00000000-0000-0000-0000-000000000001&iru=%2fm%2ffolders.m%2f&pmid=m173216c1-e5ea-11e1-bac7-002264c17c66&pmts=2012-08-14T08%3a29%3a01.057Z&nmid=m0e0a4a3a-e511-11e1-bfe5-00237de3362a&nmts=2012-08-13T06%3a44%3a51.910Z
-  //  I/FxSync  ( 7420): fennec :: SendTabActivity :: android.intent.extra.SUBJECT -> Hotmail: ONLY SIX PERFORMANCES LEFT! SPECIAL SECOND SHOW OFFER - GET $
-  public void testAndroidBrowser() {
-    Intent shareIntent = makeShareIntent("http://www.reddit.com/",
-        "reddit: the front page of the internet",
-        null);
-    SendTabData fromIntent = SendTabData.fromIntent(shareIntent);
-
-    assertEquals("reddit: the front page of the internet", fromIntent.title);
-    assertEquals("http://www.reddit.com/", fromIntent.uri);
-  }
-
-  //  From Pocket:
-  //
-  //  I/FxSync  ( 7420): fennec :: SendTabActivity :: Send was clicked.
-  //  I/FxSync  ( 7420): fennec :: SendTabActivity :: android.intent.extra.TEXT -> http://t.co/bfsbM2oV
-  //  I/FxSync  ( 7420): fennec :: SendTabActivity :: android.intent.extra.SUBJECT -> Launching the Canadian OGP Civil Society Discussion Group
-  //  I/FxSync  ( 7420): fennec :: SendTabActivity :: android.intent.extra.TITLE -> Launching the Canadian OGP Civil Society Discussion Group
-  public void testPocket() {
-    Intent shareIntent = makeShareIntent("http://t.co/bfsbM2oV",
-        "Launching the Canadian OGP Civil Society Discussion Group",
-        "Launching the Canadian OGP Civil Society Discussion Group");
-    SendTabData fromIntent = SendTabData.fromIntent(shareIntent);
-
-    assertEquals("Launching the Canadian OGP Civil Society Discussion Group", fromIntent.title);
-    assertEquals("http://t.co/bfsbM2oV", fromIntent.uri);
-  }
-
-  //  A couple of examples from Twitter App:
-  //
-  //  I/FxSync  ( 7420): fennec :: SendTabActivity :: Send was clicked.
-  //  I/FxSync  (17610): fennec :: SendTabActivity :: android.intent.extra.TEXT = Cory Doctorow (@doctorow) tweeted at 11:21 AM on Sat, Jan 12, 2013:
-  //  I/FxSync  (17610): Pls RT: @lessig on the DoJ's vindictive prosecution of Aaron Swartz http://t.co/qNalE70n #aaronsw
-  //  I/FxSync  (17610): (https://twitter.com/doctorow/status/290176681065451520)
-  //  I/FxSync  (17610):
-  //  I/FxSync  (17610): Get the official Twitter app at https://twitter.com/download
-  //  I/FxSync  (17610): fennec :: SendTabActivity :: android.intent.extra.SUBJECT = Tweet from Cory Doctorow (@doctorow)
-  //
-  //  I/FxSync  ( 7420): fennec :: SendTabActivity :: Send was clicked.
-  //  I/FxSync  ( 7420): fennec :: SendTabActivity :: android.intent.extra.TEXT -> David Eaves (@daeaves) tweeted at 0:08 PM on Fri, Jan 11, 2013:
-  //  I/FxSync  ( 7420): New on eaves.ca: Launching the Canadian OGP Civil Society Discussion Group http://t.co/bfsbM2oV
-  //  I/FxSync  ( 7420): (https://twitter.com/daeaves/status/289826143723466752)
-  //  I/FxSync  ( 7420):
-  //  I/FxSync  ( 7420): Get the official Twitter app at https://twitter.com/download
-  //  I/FxSync  ( 7420): fennec :: SendTabActivity :: android.intent.extra.SUBJECT -> Tweet from David Eaves (@daeaves)
-  public void testTwitter() {
-    Intent shareIntent1 = makeShareIntent("Cory Doctorow (@doctorow) tweeted at 11:21 AM on Sat, Jan 12, 2013:\n" +
-        "Pls RT: @lessig on the DoJ's vindictive prosecution of Aaron Swartz http://t.co/qNalE70n #aaronsw\n" +
-        "(https://twitter.com/doctorow/status/290176681065451520)\n" +
-        "\n" +
-        "Get the official Twitter app at https://twitter.com/download",
-        "Tweet from Cory Doctorow (@doctorow)",
-        null);
-    SendTabData fromIntent1 = SendTabData.fromIntent(shareIntent1);
-
-    assertEquals("Tweet from Cory Doctorow (@doctorow)", fromIntent1.title);
-    assertEquals("http://t.co/qNalE70n", fromIntent1.uri);
-
-    Intent shareIntent2 = makeShareIntent("David Eaves (@daeaves) tweeted at 0:08 PM on Fri, Jan 11, 2013:\n" +
-        "New on eaves.ca: Launching the Canadian OGP Civil Society Discussion Group http://t.co/bfsbM2oV\n" +
-        "(https://twitter.com/daeaves/status/289826143723466752)\n" +
-        "\n" +
-        "Get the official Twitter app at https://twitter.com/download",
-        "Tweet from David Eaves (@daeaves)",
-        null);
-    SendTabData fromIntent2 = SendTabData.fromIntent(shareIntent2);
-
-    assertEquals("Tweet from David Eaves (@daeaves)", fromIntent2.title);
-    assertEquals("http://t.co/bfsbM2oV", fromIntent2.uri);
-  }
-}
deleted file mode 100644
--- a/mobile/android/tests/background/junit3/src/org/mozilla/gecko/background/testhelpers/JPakeNumGeneratorFixed.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
-   http://creativecommons.org/publicdomain/zero/1.0/ */
-
-package org.mozilla.gecko.background.testhelpers;
-
-import java.math.BigInteger;
-
-import org.mozilla.gecko.sync.jpake.JPakeNumGenerator;
-
-public class JPakeNumGeneratorFixed implements JPakeNumGenerator {
-  private String[] values;
-  private int index = 0;
-
-  public JPakeNumGeneratorFixed(String[] values) {
-    this.values = values;
-  }
-
-  @Override
-  public BigInteger generateFromRange(BigInteger r) {
-    BigInteger ret = new BigInteger(values[index], 16).mod(r);
-    index = (++index) % values.length;
-    return ret;
-  }
-}
deleted file mode 100644
--- a/mobile/android/tests/background/junit4/src/org/mozilla/android/sync/net/test/TestAccountAuthenticatorStage.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
-   http://creativecommons.org/publicdomain/zero/1.0/ */
-
-package org.mozilla.android.sync.net.test;
-
-import ch.boye.httpclientandroidlib.HttpResponse;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mozilla.android.sync.test.helpers.HTTPServerTestHelper;
-import org.mozilla.android.sync.test.helpers.MockServer;
-import org.mozilla.gecko.background.common.log.Logger;
-import org.mozilla.gecko.background.testhelpers.TestRunner;
-import org.mozilla.gecko.background.testhelpers.WaitHelper;
-import org.mozilla.gecko.sync.setup.auth.AuthenticateAccountStage;
-import org.mozilla.gecko.sync.setup.auth.AuthenticateAccountStage.AuthenticateAccountStageDelegate;
-import org.simpleframework.http.Request;
-import org.simpleframework.http.Response;
-
-import java.io.IOException;
-import java.io.PrintStream;
-import java.net.URISyntaxException;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-/**
- * Tests the authentication request stage of manual Account setup.
- * @author liuche
- *
- */
-@RunWith(TestRunner.class)
-public class TestAccountAuthenticatorStage {
-  private static final int TEST_PORT      = HTTPServerTestHelper.getTestPort();
-  private static final String TEST_SERVER = "http://localhost:" + TEST_PORT;
-
-  private static final String USERNAME  = "john-hashed";
-  private static final String PASSWORD  = "password";
-
-  private MockServer authServer;
-  private HTTPServerTestHelper serverHelper = new HTTPServerTestHelper();
-  private AuthenticateAccountStage authStage = new AuthenticateAccountStage();
-  private AuthenticateAccountStageDelegate testCallback;
-
-  @Before
-  public void setup() {
-    // Make mock server to check authentication header.
-    authServer = new MockServer() {
-      @Override
-      protected void handle(Request request, Response response, int code, String body) {
-        try {
-          final int c;
-          String responseAuth = request.getValue("Authorization");
-          // Trim whitespace, HttpResponse has an extra space?
-          if (expectedBasicAuthHeader.equals(responseAuth.trim())) {
-            c = 200;
-          } else {
-            c = 401;
-          }
-
-          Logger.debug(LOG_TAG, "Handling request...");
-          PrintStream bodyStream = this.handleBasicHeaders(request, response, c, "application/json");
-          bodyStream.println(body);
-          bodyStream.close();
-        } catch (IOException e) {
-          Logger.error(LOG_TAG, "Oops.", e);
-        }
-      }
-    };
-    authServer.expectedBasicAuthHeader = authStage.makeAuthHeader(USERNAME, PASSWORD);
-
-    // Authentication delegate to handle HTTP responses.
-    testCallback = new AuthenticateAccountStageDelegate() {
-      protected int numFailedTries = 0;
-
-      @Override
-      public void handleSuccess(boolean isSuccess) {
-        if (isSuccess) {
-          // Succeed on retry (after failing first attempt).
-          assertEquals(1, numFailedTries);
-          testWaiter().performNotify();
-        } else {
-          numFailedTries++;
-          // Fail only once.
-          if (numFailedTries != 1) {
-            testWaiter().performNotify(new Exception("Failed on retry."));
-            return;
-          }
-          String authHeader = authStage.makeAuthHeader(USERNAME, PASSWORD);
-          try {
-            authStage.authenticateAccount(testCallback, TEST_SERVER, authHeader);
-          } catch (URISyntaxException e) {
-            fail("Malformed URI.");
-          }
-        }
-      }
-
-      @Override
-      public void handleFailure(HttpResponse response) {
-        fail("Unexpected response " + response.getStatusLine().getStatusCode());
-      }
-
-      @Override
-      public void handleError(Exception e) {
-        fail("Unexpected error during authentication.");
-      }
-    };
-    assertTrue(testWaiter().isIdle());
-
-  }
-
-  @After
-  public void cleanup() {
-    serverHelper.stopHTTPServer();
-    assertTrue(testWaiter().isIdle());
-  }
-
-  @Test
-  public void testAuthenticationRetry() {
-    serverHelper.startHTTPServer(authServer);
-    testWaiter().performWait(new Runnable() {
-      @Override
-      public void run() {
-        // Try auth request with incorrect password. We want to fail the first time.
-        String authHeader = authStage.makeAuthHeader(USERNAME, "wrong-password");
-        try {
-          authStage.authenticateAccount(testCallback, TEST_SERVER, authHeader);
-        } catch (URISyntaxException e) {
-          fail("Malformed URI.");
-        }
-      }
-    });
-  }
-
-  protected static WaitHelper testWaiter() {
-    return WaitHelper.getTestWaiter();
-  }
-}
deleted file mode 100644
--- a/mobile/android/tests/background/junit4/src/org/mozilla/android/sync/test/TestJPakeSetup.java
+++ /dev/null
@@ -1,262 +0,0 @@
-package org.mozilla.android.sync.test;
-
-import org.json.simple.parser.ParseException;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mozilla.apache.commons.codec.binary.Base64;
-import org.mozilla.gecko.background.testhelpers.TestRunner;
-import org.mozilla.gecko.sync.ExtendedJSONObject;
-import org.mozilla.gecko.sync.NonObjectJSONException;
-import org.mozilla.gecko.sync.crypto.CryptoException;
-import org.mozilla.gecko.sync.crypto.KeyBundle;
-import org.mozilla.gecko.sync.jpake.Gx3OrGx4IsZeroOrOneException;
-import org.mozilla.gecko.sync.jpake.IncorrectZkpException;
-import org.mozilla.gecko.sync.jpake.JPakeClient;
-import org.mozilla.gecko.sync.jpake.JPakeCrypto;
-import org.mozilla.gecko.sync.jpake.JPakeNumGenerator;
-import org.mozilla.gecko.sync.jpake.JPakeNumGeneratorRandom;
-import org.mozilla.gecko.sync.jpake.JPakeParty;
-import org.mozilla.gecko.sync.jpake.stage.ComputeKeyVerificationStage;
-import org.mozilla.gecko.sync.jpake.stage.VerifyPairingStage;
-import org.mozilla.gecko.sync.setup.Constants;
-
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.math.BigInteger;
-import java.security.InvalidKeyException;
-import java.security.NoSuchAlgorithmException;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-@RunWith(TestRunner.class)
-public class TestJPakeSetup {
-  // Note: will throw NullPointerException if aborts. Only use stateless public
-  // methods.
-
-  @Test
-  public void testGx3OrGx4ZeroOrOneThrowsException()
-      throws UnsupportedEncodingException
-  {
-    JPakeNumGeneratorRandom gen = new JPakeNumGeneratorRandom();
-    JPakeParty p = new JPakeParty("foobar");
-    BigInteger secret = JPakeClient.secretAsBigInteger("secret");
-
-    p.gx4 = new BigInteger("2");
-    p.gx3 = new BigInteger("0");
-    try {
-      JPakeCrypto.round2(secret, p, gen);
-      fail("round2 should fail if gx3 == 0");
-    } catch (Gx3OrGx4IsZeroOrOneException e) {
-      // Hurrah.
-    } catch (Exception e) {
-      fail("Unexpected exception " + e);
-    }
-
-    p.gx3 = new BigInteger("1");
-    try {
-      JPakeCrypto.round2(secret, p, gen);
-      fail("round2 should fail if gx3 == 1");
-    } catch (Gx3OrGx4IsZeroOrOneException e) {
-      // Hurrah.
-    } catch (Exception e) {
-      fail("Unexpected exception " + e);
-    }
-
-    p.gx3 = new BigInteger("3");
-    try {
-      JPakeCrypto.round2(secret, p, gen);
-    } catch (Gx3OrGx4IsZeroOrOneException e) {
-      fail("Unexpected exception " + e);
-    } catch (Exception e) {
-      // There are plenty of other reasons this should fail.
-    }
-
-    p.gx3 = new BigInteger("2");
-    p.gx4 = new BigInteger("0");
-    try {
-      JPakeCrypto.round2(secret, p, gen);
-      fail("round2 should fail if gx4 == 0");
-    } catch (Gx3OrGx4IsZeroOrOneException e) {
-      // Hurrah.
-    } catch (Exception e) {
-      fail("Unexpected exception " + e);
-    }
-
-    p.gx4 = new BigInteger("1");
-    try {
-      JPakeCrypto.round2(secret, p, gen);
-      fail("round2 should fail if gx4 == 1");
-    } catch (Gx3OrGx4IsZeroOrOneException e) {
-      // Hurrah.
-    } catch (Exception e) {
-      fail("Unexpected exception " + e);
-    }
-
-    p.gx4 = new BigInteger("3");
-    try {
-      JPakeCrypto.round2(secret, p, gen);
-    } catch (Gx3OrGx4IsZeroOrOneException e) {
-      fail("Unexpected exception " + e);
-    } catch (Exception e) {
-      // There are plenty of other reasons this should fail.
-    }
-  }
-
-  /*
-   * Tests encryption key and hmac generation from a derived key, using values
-   * taken from a successful run of J-PAKE.
-   */
-  @Test
-  public void testKeyDerivation() throws UnsupportedEncodingException {
-    String keyChars16 = "811565455b22c857a3e303d1f48ff72ae9ef42d9c3fe3740ce7772cb5bfe23491dd5b7ee5af4828ab9b7d5844866f378b4cf0156810aff0504ef2947402e8e40be1179cf7f37b231bc0db9e4e1bb239c849aa5c12ed2b0b4413017599270aae71ee993dd755ee8c045c5fe03d713894692bf72158d9835ad905442edfd8235e1d0c915053debfc49d8248e4dae16608743aef5dab061f49fd6edd0b93ecdf9feafcbe47eb7e6c3678356d96e9bcd87814b13b9eb1a791fd446d69cb040ec7d7194031267e26f266ee3decbc1a85c5203427361997adf9823fbffe16af9946f1347c5354956356732e436ef5f8307e96554cf69a54e4e8a78552e3f506e9310a1c4438d3ddce44a37482270533e47fc40dc84abfe39c1f95328d0d2540074f6301d4f121c2f0eac49c47a2c430614234ca26dede2a429e2fdb6d282a85174886c3a68c3cf5edc87ccb82af4ae4a9a26fffadc7f4d8ded4ff47b3d2d171f374b230e52e6b45963d3a0a6b20cbe6a440fd4a932279d52a6fd7694b4cbc0cb67ff3c";
-    String expectedEncKey64 = "3TXwVlWf6YbuIPcg8m/2U4UXYV4a8RNu6pE2GOVkJJo=";
-    String expectedHmac64 = "L49fnEPAD31G5uEKy5e4bGZ6IF3G/62qW6Ua/1NvBeQ=";
-
-    byte[] encKeyBytes = new byte[32];
-    byte[] hmacBytes = new byte[32];
-
-    try {
-      JPakeCrypto.generateKeyAndHmac(new BigInteger(keyChars16, 16), encKeyBytes, hmacBytes);
-    } catch (Exception e) {
-      fail("Unexpected exception " + e);
-    }
-    String encKey64 = new String(Base64.encodeBase64(encKeyBytes));
-    String hmac64 = new String(Base64.encodeBase64(hmacBytes));
-
-    assertTrue(expectedEncKey64.equals(encKey64));
-    assertTrue(expectedHmac64.equals(hmac64));
-  }
-
-  /*
-   * Test correct key derivation when both parties share a secret.
-   */
-  @Test
-  public void testJPakeCorrectSecret() throws Gx3OrGx4IsZeroOrOneException,
-      IncorrectZkpException, IOException, ParseException,
-      NonObjectJSONException, CryptoException, NoSuchAlgorithmException, InvalidKeyException {
-    BigInteger secret = JPakeClient.secretAsBigInteger("byubd7u75qmq");
-    JPakeNumGenerator gen = new JPakeNumGeneratorRandom();
-    // Keys derived should be the same.
-    assertTrue(jPakeDeriveSameKey(gen, gen, secret, secret));
-  }
-
-  /*
-   * Test incorrect key derivation when parties do not share the same secret.
-   */
-  @Test
-  public void testJPakeIncorrectSecret() throws Gx3OrGx4IsZeroOrOneException,
-      IncorrectZkpException, IOException, ParseException,
-      NonObjectJSONException, CryptoException, NoSuchAlgorithmException, InvalidKeyException {
-    BigInteger secret1 = JPakeClient.secretAsBigInteger("shareSecret1");
-    BigInteger secret2 = JPakeClient.secretAsBigInteger("shareSecret2");
-    JPakeNumGenerator gen = new JPakeNumGeneratorRandom();
-    // Unsuccessful key derivation.
-    assertFalse(jPakeDeriveSameKey(gen, gen, secret1, secret2));
-  }
-
-  /*
-   * Helper simulation of a J-PAKE key derivation between two parties, with
-   * secret1 and secret2. Both parties are assumed to be communicating on the
-   * same channel; otherwise, J-PAKE would have failed immediately.
-   */
-  public boolean jPakeDeriveSameKey(JPakeNumGenerator gen1,
-      JPakeNumGenerator gen2, BigInteger secret1, BigInteger secret2)
-      throws IncorrectZkpException, Gx3OrGx4IsZeroOrOneException, IOException,
-      ParseException, NonObjectJSONException, CryptoException, NoSuchAlgorithmException, InvalidKeyException {
-
-    // Communicating parties.
-    JPakeParty party1 = new JPakeParty("party1");
-    JPakeParty party2 = new JPakeParty("party2");
-
-    JPakeCrypto.round1(party1, gen1);
-    // After party1 round 1, these values should no longer be null.
-    assertNotNull(party1.signerId);
-    assertNotNull(party1.x2);
-    assertNotNull(party1.gx1);
-    assertNotNull(party1.gx2);
-    assertNotNull(party1.zkp1);
-    assertNotNull(party1.zkp2);
-    assertNotNull(party1.zkp1.b);
-    assertNotNull(party1.zkp1.gr);
-    assertNotNull(party1.zkp1.id);
-    assertNotNull(party1.zkp2.b);
-    assertNotNull(party1.zkp2.gr);
-    assertNotNull(party1.zkp2.id);
-
-    // party2 receives the following values from party1.
-    party2.gx3 = party1.gx1;
-    party2.gx4 = party1.gx2;
-    party2.zkp3 = party1.zkp1;
-    party2.zkp4 = party1.zkp2;
-    // TODO Run JPakeClient checks.
-
-    JPakeCrypto.round1(party2, gen2);
-    // After party2 round 1, these values should no longer be null.
-    assertNotNull(party2.signerId);
-    assertNotNull(party2.x2);
-    assertNotNull(party2.gx1);
-    assertNotNull(party2.gx2);
-    assertNotNull(party2.zkp1);
-    assertNotNull(party2.zkp2);
-    assertNotNull(party2.zkp1.b);
-    assertNotNull(party2.zkp1.gr);
-    assertNotNull(party2.zkp1.id);
-    assertNotNull(party2.zkp2.b);
-    assertNotNull(party2.zkp2.gr);
-    assertNotNull(party2.zkp2.id);
-
-    // Pass relevant values to party1.
-    party1.gx3 = party2.gx1;
-    party1.gx4 = party2.gx2;
-    party1.zkp3 = party2.zkp1;
-    party1.zkp4 = party2.zkp2;
-    // TODO Run JPakeClient checks.
-
-    JPakeCrypto.round2(secret1, party1, gen1);
-    // After party1 round 2, these values should no longer be null.
-    assertNotNull(party1.thisA);
-    assertNotNull(party1.thisZkpA);
-    assertNotNull(party1.thisZkpA.b);
-    assertNotNull(party1.thisZkpA.gr);
-    assertNotNull(party1.thisZkpA.id);
-
-    // Pass relevant values to party2.
-    party2.otherA = party1.thisA;
-    party2.otherZkpA = party1.thisZkpA;
-
-    JPakeCrypto.round2(secret2, party2, gen2);
-    // Check for nulls.
-    assertNotNull(party2.thisA);
-    assertNotNull(party2.thisZkpA);
-    assertNotNull(party2.thisZkpA.b);
-    assertNotNull(party2.thisZkpA.gr);
-    assertNotNull(party2.thisZkpA.id);
-
-    // Pass values to party1.
-    party1.otherA = party2.thisA;
-    party1.otherZkpA = party2.thisZkpA;
-
-    KeyBundle keyBundle1 = JPakeCrypto.finalRound(secret1, party1);
-    assertNotNull(keyBundle1);
-
-    // party1 computes the shared key, generates an encrypted message to party2.
-    ExtendedJSONObject verificationMsg = new ComputeKeyVerificationStage()
-        .computeKeyVerification(keyBundle1, party1.signerId);
-    ExtendedJSONObject payload = verificationMsg
-        .getObject(Constants.JSON_KEY_PAYLOAD);
-    String ciphertext1 = (String) payload.get(Constants.JSON_KEY_CIPHERTEXT);
-    String iv1 = (String) payload.get(Constants.JSON_KEY_IV);
-
-    // party2 computes the key as well, using its copy of the secret.
-    KeyBundle keyBundle2 = JPakeCrypto.finalRound(secret2, party2);
-    // party2 fetches the encrypted message and verifies the pairing against its
-    // own derived key.
-
-    boolean isSuccess = new VerifyPairingStage().verifyCiphertext(ciphertext1, iv1,
-        keyBundle2);
-    return isSuccess;
-  }
-}
deleted file mode 100644
--- a/mobile/android/tests/background/junit4/src/org/mozilla/gecko/background/testhelpers/JPakeNumGeneratorFixed.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
-   http://creativecommons.org/publicdomain/zero/1.0/ */
-
-package org.mozilla.gecko.background.testhelpers;
-
-import org.mozilla.gecko.sync.jpake.JPakeNumGenerator;
-
-import java.math.BigInteger;
-
-public class JPakeNumGeneratorFixed implements JPakeNumGenerator {
-  private String[] values;
-  private int index = 0;
-
-  public JPakeNumGeneratorFixed(String[] values) {
-    this.values = values;
-  }
-
-  @Override
-  public BigInteger generateFromRange(BigInteger r) {
-    BigInteger ret = new BigInteger(values[index], 16).mod(r);
-    index = (++index) % values.length;
-    return ret;
-  }
-}