diff --git a/F-Droid/res/layout/swap_wifi_qr.xml b/F-Droid/res/layout/swap_wifi_qr.xml
index 38dba512b..006be63ac 100644
--- a/F-Droid/res/layout/swap_wifi_qr.xml
+++ b/F-Droid/res/layout/swap_wifi_qr.xml
@@ -45,13 +45,6 @@
                 android:layout_gravity="center"
                 android:id="@+id/btn_qr_scanner"/>
 
-        <!-- Mark as "gone" for now, until it appears in a future mockup. Don't comment it out,
-             because then we'd need to modify the code which adds a listener for it too. -->
-        <Button style="@style/SwapTheme.Wizard.OptionButton"
-                android:id="@+id/btn_cancel_swap"
-                android:visibility="gone"
-                android:text="@string/cancel" />
-
     </LinearLayout>
 
 </org.fdroid.fdroid.views.swap.WifiQrView>
\ No newline at end of file
diff --git a/F-Droid/res/values-cs/strings.xml b/F-Droid/res/values-cs/strings.xml
index f9001f7e3..c8c4180d6 100644
--- a/F-Droid/res/values-cs/strings.xml
+++ b/F-Droid/res/values-cs/strings.xml
@@ -24,8 +24,6 @@
   <string name="root_installer_on">Vyžádat si oprávnění roota k instalaci, aktualizaci či odstraňování balíčků</string>
   <string name="system_installer">Instalovat s použitím systémových oprávnění</string>
   <string name="system_installer_on">Použít systémová oprávnění k instalování, aktualizaci a odebírání balíčků</string>
-  <string name="local_repo_bonjour">Oznamovat místní repozitář</string>
-  <string name="local_repo_bonjour_on">Oznamovat místní repozitář pomocí Bonjour (mDNS)</string>
   <string name="local_repo_name">Název místního repozitáře</string>
   <string name="local_repo_name_summary">Oznamovaný název místního repozitáře: %s</string>
   <string name="local_repo_https">Použít soukromé připojení</string>
diff --git a/F-Droid/res/values-de/strings.xml b/F-Droid/res/values-de/strings.xml
index 9f71678e4..e0b2a4f68 100644
--- a/F-Droid/res/values-de/strings.xml
+++ b/F-Droid/res/values-de/strings.xml
@@ -28,8 +28,6 @@
   <string name="root_installer_on">Root-Rechte anfordern, um Pakete zu installieren, zu aktualisieren und zu entfernen</string>
   <string name="system_installer">Mit Verwendung von Systemberechtigungen installieren</string>
   <string name="system_installer_on">Systemberechtigungen verwenden, um Pakete zu installieren, zu aktualisieren und zu entfernen</string>
-  <string name="local_repo_bonjour">Lokale Paketquelle übertragen</string>
-  <string name="local_repo_bonjour_on">Die lokale Paketquelle durch Verwendung von Bonjour (mDNS) bewerben</string>
   <string name="local_repo_name">Name Ihrer lokalen Paketquelle</string>
   <string name="local_repo_name_summary">Der werbende Titel Ihrer lokalen Paketquelle: %s</string>
   <string name="local_repo_https">Gesicherte Verbindung verwenden</string>
diff --git a/F-Droid/res/values-es/strings.xml b/F-Droid/res/values-es/strings.xml
index 168ea8d16..1270b229c 100644
--- a/F-Droid/res/values-es/strings.xml
+++ b/F-Droid/res/values-es/strings.xml
@@ -28,8 +28,6 @@
   <string name="root_installer_on">Pedir acceso root para instalar, actualizar y borrar paquetes</string>
   <string name="system_installer">Instalar usando permisos de sistema</string>
   <string name="system_installer_on">Utilice permisos de sistema para instalar , actualizar y eliminar paquetes</string>
-  <string name="local_repo_bonjour">Transmitir repositorio local</string>
-  <string name="local_repo_bonjour_on">Publicar repositorio local usando Bonjour(mDNS)</string>
   <string name="local_repo_name">Nombre de tu repo local</string>
   <string name="local_repo_name_summary">El título que se publicita para el repo local: %s</string>
   <string name="local_repo_https">Usar Conexión Privada</string>
diff --git a/F-Droid/res/values-fi/strings.xml b/F-Droid/res/values-fi/strings.xml
index 14e92c2b0..759fa44ed 100644
--- a/F-Droid/res/values-fi/strings.xml
+++ b/F-Droid/res/values-fi/strings.xml
@@ -28,8 +28,6 @@
   <string name="root_installer_on">Pyydä root-oikeuksia asennuksiin, päivityksiin ja pakettien poistoon</string>
   <string name="system_installer">Asenna käytäen järjestelmän oikeuksia</string>
   <string name="system_installer_on">Käytä järjestelmän oikeuksia asennuksiin, päivityksiin ja pakettien poistoihin.</string>
-  <string name="local_repo_bonjour">Kuuluta paikallista säilöä</string>
-  <string name="local_repo_bonjour_on">Mainosta paikallista säilöäsi Bonjour-palvelua käyttäen (mDNS)</string>
   <string name="local_repo_name">Paikallisen säilösi nimi</string>
   <string name="local_repo_name_summary">Paikallisen säilösi mainostettava otsikko: %s</string>
   <string name="local_repo_https">Käytä yksityistä yhteyttä</string>
diff --git a/F-Droid/res/values-fr/strings.xml b/F-Droid/res/values-fr/strings.xml
index 85912f299..839389776 100644
--- a/F-Droid/res/values-fr/strings.xml
+++ b/F-Droid/res/values-fr/strings.xml
@@ -28,8 +28,6 @@
   <string name="root_installer_on">Demander les droits root pour installer, mettre à jour et supprimer des paquets</string>
   <string name="system_installer">Installer en utilisant les permissions systèmes</string>
   <string name="system_installer_on">Utiliser les permissions du système pour installer, mettre à jour et supprimer des paquets</string>
-  <string name="local_repo_bonjour">Diffuser votre dépôt local</string>
-  <string name="local_repo_bonjour_on">Annoncer votre dépôt local avec \"Bonjour\" (mDNS)</string>
   <string name="local_repo_name">Nom de votre dépôt local</string>
   <string name="local_repo_name_summary">Le nom public de votre dépôt local: %s</string>
   <string name="local_repo_https">Utilisez une connexion privée</string>
diff --git a/F-Droid/res/values-it/strings.xml b/F-Droid/res/values-it/strings.xml
index 791c459b1..bb4fa370b 100644
--- a/F-Droid/res/values-it/strings.xml
+++ b/F-Droid/res/values-it/strings.xml
@@ -28,8 +28,6 @@
   <string name="root_installer_on">Richiedi il root per installare,aggiornare e rimuovere i pacchetti</string>
   <string name="system_installer">Installa usando i permessi di sistema</string>
   <string name="system_installer_on">Usa i permessi di sistema per installare,aggiornare e rimuovere i pacchetti</string>
-  <string name="local_repo_bonjour">Condividi la Repo locale</string>
-  <string name="local_repo_bonjour_on">Lancia la tua repo usando Bonjour (mDNS)</string>
   <string name="local_repo_name">Nome della tua Repo Locale</string>
   <string name="local_repo_name_summary">Il testo pubblico della tua repo: %s</string>
   <string name="local_repo_https">Usa una Connessione Privata</string>
diff --git a/F-Droid/res/values-ja/strings.xml b/F-Droid/res/values-ja/strings.xml
index d9a3eb500..cb253a715 100644
--- a/F-Droid/res/values-ja/strings.xml
+++ b/F-Droid/res/values-ja/strings.xml
@@ -28,8 +28,6 @@
   <string name="root_installer_on">パッケージのインストール、更新、および削除に管理者権限を要求する</string>
   <string name="system_installer">システムアクセス許可を使用してインストール</string>
   <string name="system_installer_on">パッケージのインストール、更新、および削除にシステムアクセス許可を使用する</string>
-  <string name="local_repo_bonjour">ローカルリポジトリをブロードキャスト</string>
-  <string name="local_repo_bonjour_on">Bonjour (mDNS) を使用してローカルリポジトリを公開する</string>
   <string name="local_repo_name">ローカルリポジトリの名前</string>
   <string name="local_repo_name_summary">公開するローカルリポジトリの題名: %s</string>
   <string name="local_repo_https">プライベート接続を使用する</string>
diff --git a/F-Droid/res/values-nb/strings.xml b/F-Droid/res/values-nb/strings.xml
index 85305e7ab..360c80c71 100644
--- a/F-Droid/res/values-nb/strings.xml
+++ b/F-Droid/res/values-nb/strings.xml
@@ -28,8 +28,6 @@
   <string name="root_installer_on">Spør etter root tilgang for å installere, oppdatere, og fjerne applikasjoner.</string>
   <string name="system_installer">Installer ved bruk av system-tilgang</string>
   <string name="system_installer_on">Bruk system rettigheter til å installere, oppdatere, og fjerne applikasjoner.</string>
-  <string name="local_repo_bonjour">Kringkast lokal pakkebrønn</string>
-  <string name="local_repo_bonjour_on">Reklamer for din lokale pakkebrønn ved bruk av Bonjour (mDNS)</string>
   <string name="local_repo_name">Navn på lokal pakkebrønn</string>
   <string name="local_repo_name_summary">Offentliggjort tittel for din lokale pakkebrønn: %s</string>
   <string name="local_repo_https">Bruk privat tilkobling</string>
diff --git a/F-Droid/res/values-pl/strings.xml b/F-Droid/res/values-pl/strings.xml
index adf0f2b55..fd1271695 100644
--- a/F-Droid/res/values-pl/strings.xml
+++ b/F-Droid/res/values-pl/strings.xml
@@ -17,8 +17,6 @@
   <string name="root_installer_on">Żądaj dostępu roota do instalacji, aktualizacji i usuwania pakietów</string>
   <string name="system_installer">Instaluj na uprawnieniach systemowych</string>
   <string name="system_installer_on">Używaj uprawnień systemowych do instalacji, aktualizacji i usuwania pakietów</string>
-  <string name="local_repo_bonjour">Widoczność repozytorium</string>
-  <string name="local_repo_bonjour_on">Udostępniaj repozytorium lokalne przez Bonjour (mDNS)</string>
   <string name="local_repo_name">Nazwa lokalnego repozytorium</string>
   <string name="local_repo_name_summary">Wyświetlana nazwa repozytorium lokalnego: %s</string>
   <string name="local_repo_https">Użyj zabezpieczonego połączenia</string>
diff --git a/F-Droid/res/values-pt-rBR/strings.xml b/F-Droid/res/values-pt-rBR/strings.xml
index 73a02fbb3..fc882f770 100644
--- a/F-Droid/res/values-pt-rBR/strings.xml
+++ b/F-Droid/res/values-pt-rBR/strings.xml
@@ -19,8 +19,6 @@
   <string name="root_installer_on">Solicitar acesso root para instalar, atualizar e remover pacotes</string>
   <string name="system_installer">Instalar usando permissões do sistema</string>
   <string name="system_installer_on">Usar permissões do sistema para instalar, atualizar e remover pacotes</string>
-  <string name="local_repo_bonjour">Transmitir repositório local</string>
-  <string name="local_repo_bonjour_on">Anunciar seu repositório local usando Bonjour (mDNS)</string>
   <string name="local_repo_name">Nome do seu repositório local</string>
   <string name="local_repo_name_summary">Título anunciado do seu repositório local: %s</string>
   <string name="local_repo_https">Usar conexão privada</string>
diff --git a/F-Droid/res/values-ru/strings.xml b/F-Droid/res/values-ru/strings.xml
index c4e5f75e0..85fc3ec40 100644
--- a/F-Droid/res/values-ru/strings.xml
+++ b/F-Droid/res/values-ru/strings.xml
@@ -30,8 +30,6 @@
   <string name="root_installer_on">Запрашивать права root пользователя для установки, обновления и удаления приложений</string>
   <string name="system_installer">Устанавливать используя системные привилегии</string>
   <string name="system_installer_on">Использовать системные привилегии для установки, обновления и удаления приложений</string>
-  <string name="local_repo_bonjour">Транслировать локальный репозиторий</string>
-  <string name="local_repo_bonjour_on">Рекламировать ваш репозиторий используя Bonjour (mDNS)</string>
   <string name="local_repo_name">Название вашего локального репозитория</string>
   <string name="local_repo_name_summary">Ваш локальный репозиторий рекламируется под именем: %s</string>
   <string name="local_repo_https">Использовать частное соединение</string>
diff --git a/F-Droid/res/values-sc/strings.xml b/F-Droid/res/values-sc/strings.xml
index 32a8637c9..abb78109e 100644
--- a/F-Droid/res/values-sc/strings.xml
+++ b/F-Droid/res/values-sc/strings.xml
@@ -17,8 +17,6 @@
   <string name="root_installer_on">Pedi s\'atzessu root pro installare, agiornare, e remòvrere pachetos</string>
   <string name="system_installer">Installa impreande sos permissos de sistema</string>
   <string name="system_installer_on">Imprea sos permissos de sistema pro installare, agiornare, e remòvere pachetos</string>
-  <string name="local_repo_bonjour">Cumpartzi su depòsitu locale</string>
-  <string name="local_repo_bonjour_on">Pùblica su depòsitu tuo impreande Bonjour (mDNS)</string>
   <string name="local_repo_name">Nùmene de su Depòsitu Locale tuo</string>
   <string name="local_repo_name_summary">Su nùmene pùblicu de su depòsitu locale tuo: %s</string>
   <string name="local_repo_https">Imprea una cunnessione privada</string>
diff --git a/F-Droid/res/values-sk/strings.xml b/F-Droid/res/values-sk/strings.xml
index 55b0534d6..56cfce583 100644
--- a/F-Droid/res/values-sk/strings.xml
+++ b/F-Droid/res/values-sk/strings.xml
@@ -4,8 +4,6 @@
   <string name="root_installer_on">Žiadať root prístup na inštaláciu, aktualizácie a odstránenie balíkov</string>
   <string name="system_installer">Inštalovať s povoleniami systému</string>
   <string name="system_installer_on">Používať systémové povolenia na inštaláciu, aktualizácie a odstránenie balíkov</string>
-  <string name="local_repo_bonjour">Vysielať miestne repo</string>
-  <string name="local_repo_bonjour_on">Propagovať miesto repo pomocou Bonjour (mDNS)</string>
   <string name="local_repo_name">Meno miestneho repa</string>
   <string name="local_repo_name_summary">Zverejnený názov miestneho repa: %s</string>
   <string name="local_repo_https">Použiť bezpečné pripojenie</string>
diff --git a/F-Droid/res/values-sv/strings.xml b/F-Droid/res/values-sv/strings.xml
index 443a2b38b..5b241259d 100644
--- a/F-Droid/res/values-sv/strings.xml
+++ b/F-Droid/res/values-sv/strings.xml
@@ -28,8 +28,6 @@
   <string name="root_installer_on">Efterfråga root-åtkomst för att installera, uppdatera och ta bort paket</string>
   <string name="system_installer">Installera med systembehörigheter</string>
   <string name="system_installer_on">Använd systembehörigheter för att installera, uppdatera och ta bort paket</string>
-  <string name="local_repo_bonjour">Annonsera lokalt förråd</string>
-  <string name="local_repo_bonjour_on">Annonsera ditt lokala förråd med Bonjour (mDNS)</string>
   <string name="local_repo_name">Namn på ditt lokala förråd</string>
   <string name="local_repo_name_summary">Annonserad titel på ditt lokala förråd: %s</string>
   <string name="local_repo_https">Använd privat anslutning</string>
diff --git a/F-Droid/res/values-tr/strings.xml b/F-Droid/res/values-tr/strings.xml
index a6a079a5a..a737197eb 100644
--- a/F-Droid/res/values-tr/strings.xml
+++ b/F-Droid/res/values-tr/strings.xml
@@ -26,7 +26,6 @@
   <string name="update_history_summ">Uygulamaların yeni sayılacağı gün sayısı: %s</string>
   <string name="root_installer">Root erişimi kullanarak yükle</string>
   <string name="system_installer">Sistem-izinlerini kullanarak yükle</string>
-  <string name="local_repo_bonjour_on">Bonjour (mDNS) kullanarak yerel reponu duyur</string>
   <string name="local_repo_name">Yerel Deponun Adı</string>
   <string name="local_repo_name_summary">Yerel deponun duyrulan adı: %s</string>
   <string name="local_repo_https_on">Yerel depo için güvenli HTTPS:// bağlantı kullan</string>
diff --git a/F-Droid/res/values/strings.xml b/F-Droid/res/values/strings.xml
index 4cb61289e..b07a7a97b 100644
--- a/F-Droid/res/values/strings.xml
+++ b/F-Droid/res/values/strings.xml
@@ -29,8 +29,6 @@
 	<string name="root_installer_on">Request root access to install, update, and remove packages</string>
 	<string name="system_installer">Install using system-permissions</string>
 	<string name="system_installer_on">Use system permissions to install, update, and remove packages</string>
-	<string name="local_repo_bonjour">Broadcast Local Repo</string>
-	<string name="local_repo_bonjour_on">Advertise your local repo using Bonjour (mDNS)</string>
 	<string name="local_repo_name">Name of your Local Repo</string>
 	<string name="local_repo_name_summary">The advertised title of your local repo: %s</string>
 	<string name="local_repo_https">Use Private Connection</string>
diff --git a/F-Droid/res/xml/preferences.xml b/F-Droid/res/xml/preferences.xml
index 9d94bcbc0..5b9dad0c2 100644
--- a/F-Droid/res/xml/preferences.xml
+++ b/F-Droid/res/xml/preferences.xml
@@ -48,10 +48,6 @@
 			android:key="ignoreTouchscreen" />
 	</PreferenceCategory>
 	<PreferenceCategory android:title="@string/local_repo">
-		<CheckBoxPreference
-		    android:defaultValue="true"
-		    android:key="localRepoBonjour"
-		    android:title="@string/local_repo_bonjour" />
 		<EditTextPreference
 		    android:key="localRepoName"
 		    android:title="@string/local_repo_name" />
diff --git a/F-Droid/src/org/fdroid/fdroid/Preferences.java b/F-Droid/src/org/fdroid/fdroid/Preferences.java
index 2502d8eac..100ab149e 100644
--- a/F-Droid/src/org/fdroid/fdroid/Preferences.java
+++ b/F-Droid/src/org/fdroid/fdroid/Preferences.java
@@ -52,7 +52,6 @@ public class Preferences implements SharedPreferences.OnSharedPreferenceChangeLi
     public static final String PREF_UPD_LAST = "lastUpdateCheck";
     public static final String PREF_ROOT_INSTALLER = "rootInstaller";
     public static final String PREF_SYSTEM_INSTALLER = "systemInstaller";
-    public static final String PREF_LOCAL_REPO_BONJOUR = "localRepoBonjour";
     public static final String PREF_LOCAL_REPO_NAME = "localRepoName";
     public static final String PREF_LOCAL_REPO_HTTPS = "localRepoHttps";
     public static final String PREF_LANGUAGE = "language";
@@ -86,7 +85,6 @@ public class Preferences implements SharedPreferences.OnSharedPreferenceChangeLi
     private final List<ChangeListener> compactLayoutListeners = new ArrayList<>();
     private final List<ChangeListener> filterAppsRequiringRootListeners = new ArrayList<>();
     private final List<ChangeListener> updateHistoryListeners = new ArrayList<>();
-    private final List<ChangeListener> localRepoBonjourListeners = new ArrayList<>();
     private final List<ChangeListener> localRepoNameListeners = new ArrayList<>();
     private final List<ChangeListener> localRepoHttpsListeners = new ArrayList<>();
 
@@ -110,10 +108,6 @@ public class Preferences implements SharedPreferences.OnSharedPreferenceChangeLi
         return preferences.getBoolean(PREF_SYSTEM_INSTALLER, DEFAULT_SYSTEM_INSTALLER);
     }
 
-    public boolean isLocalRepoBonjourEnabled() {
-        return preferences.getBoolean(PREF_LOCAL_REPO_BONJOUR, DEFAULT_LOCAL_REPO_BONJOUR);
-    }
-
     public boolean shouldCacheApks() {
         return preferences.getBoolean(PREF_CACHE_APK, DEFAULT_CACHE_APK);
     }
@@ -249,11 +243,6 @@ public class Preferences implements SharedPreferences.OnSharedPreferenceChangeLi
                 listener.onPreferenceChange();
             }
             break;
-        case PREF_LOCAL_REPO_BONJOUR:
-            for (ChangeListener listener : localRepoBonjourListeners) {
-                listener.onPreferenceChange();
-            }
-            break;
         case PREF_LOCAL_REPO_NAME:
             for (ChangeListener listener : localRepoNameListeners) {
                 listener.onPreferenceChange();
@@ -275,14 +264,6 @@ public class Preferences implements SharedPreferences.OnSharedPreferenceChangeLi
         updateHistoryListeners.remove(listener);
     }
 
-    public void registerLocalRepoBonjourListeners(ChangeListener listener) {
-        localRepoBonjourListeners.add(listener);
-    }
-
-    public void unregisterLocalRepoBonjourListeners(ChangeListener listener) {
-        localRepoBonjourListeners.remove(listener);
-    }
-
     public void registerLocalRepoNameListeners(ChangeListener listener) {
         localRepoNameListeners.add(listener);
     }
diff --git a/F-Droid/src/org/fdroid/fdroid/localrepo/SwapService.java b/F-Droid/src/org/fdroid/fdroid/localrepo/SwapService.java
index 49b78ddca..291ce1a60 100644
--- a/F-Droid/src/org/fdroid/fdroid/localrepo/SwapService.java
+++ b/F-Droid/src/org/fdroid/fdroid/localrepo/SwapService.java
@@ -38,10 +38,9 @@ import org.fdroid.fdroid.data.RepoProvider;
 import org.fdroid.fdroid.localrepo.peers.BluetoothFinder;
 import org.fdroid.fdroid.localrepo.peers.BonjourFinder;
 import org.fdroid.fdroid.localrepo.peers.Peer;
-import org.fdroid.fdroid.localrepo.type.BluetoothType;
-import org.fdroid.fdroid.localrepo.type.BonjourType;
+import org.fdroid.fdroid.localrepo.type.BluetoothSwap;
 import org.fdroid.fdroid.localrepo.type.SwapType;
-import org.fdroid.fdroid.localrepo.type.WebServerType;
+import org.fdroid.fdroid.localrepo.type.WifiSwap;
 import org.fdroid.fdroid.net.WifiStateChangeService;
 import org.fdroid.fdroid.views.swap.SwapWorkflowActivity;
 
@@ -361,25 +360,13 @@ public class SwapService extends Service {
      * Ensures that the webserver is running, as are the other services which make swap work.
      * Will only do all this if it is not already running, and will run on a background thread.'
      * TODO: What about an "enabling" status? Not sure if it will be useful or not.
+     *
+     *
+     * TODO: Call this at the relevant time, when wifi or bluetooth is enabled.
      */
-    public void enableSwapping() {
-        if (!enabled) {
-            new AsyncTask<Void, Void, Void>() {
-                @Override
-                protected Void doInBackground(Void... params) {
-                    Log.d(TAG, "Started background task to enable swapping.");
-                    enableSwappingAsynchronous();
-                    return null;
-                }
-
-                @Override
-                protected void onPostExecute(Void aVoid) {
-                    Log.d(TAG, "Moving SwapService to foreground so that it hangs around even when F-Droid is closed.");
-                    startForeground(NOTIFICATION, createNotification());
-                    enabled = true;
-                }
-            }.execute();
-        }
+    private void attachService() {
+        Log.d(TAG, "Moving SwapService to foreground so that it hangs around even when F-Droid is closed.");
+        startForeground(NOTIFICATION, createNotification());
 
         // Regardless of whether it was previously enabled, start the timer again. This ensures that
         // if, e.g. a person views the swap activity again, it will attempt to enable swapping if
@@ -387,46 +374,26 @@ public class SwapService extends Service {
         initTimer();
     }
 
-    public void disableSwapping() {
-        if (enabled) {
-            new AsyncTask<Void, Void, Void>() {
-                @Override
-                protected Void doInBackground(Void... params) {
-                    Log.d(TAG, "Started background task to disable swapping.");
-                    disableSwappingSynchronous();
-                    return null;
-                }
-
-                @Override
-                protected void onPostExecute(Void aVoid) {
-                    Log.d(TAG, "Finished background task to disable swapping.");
-
-                    // TODO: Does this  need to be run before the background task, so that the timer
-                    // can't kick in while we are shutting down everything?
-                    if (timer != null) {
-                        timer.cancel();
-                    }
-
-                    enabled = false;
-
-                    Log.d(TAG, "Moving SwapService to background so that it can be GC'ed if required.");
-                    stopForeground(true);
-                }
-            }.execute();
+    private void detachService() {
+        if (timer != null) {
+            timer.cancel();
         }
+
+        Log.d(TAG, "Moving SwapService to background so that it can be GC'ed if required.");
+        stopForeground(true);
     }
 
     /**
      * Handles checking if the {@link SwapService} is running, and only restarts it if it was running.
      */
-    public void restartIfEnabled() {
-        if (enabled) {
+    public void restartWifiIfEnabled() {
+        if (wifiSwap.isConnected()) {
             new AsyncTask<Void, Void, Void>() {
                 @Override
                 protected Void doInBackground(Void... params) {
-                    Log.d(TAG, "Restarting swap services.");
-                    disableSwappingSynchronous();
-                    enableSwappingAsynchronous();
+                    Log.d(TAG, "Restarting WiFi swap service");
+                    wifiSwap.stop();
+                    wifiSwap.start();
                     return null;
                 }
             }.execute();
@@ -434,7 +401,7 @@ public class SwapService extends Service {
     }
 
     public boolean isEnabled() {
-        return enabled;
+        return bluetoothSwap.isConnected() || wifiSwap.isConnected();
     }
 
     // ==========================================
@@ -442,15 +409,7 @@ public class SwapService extends Service {
     // ==========================================
 
     public boolean isBluetoothDiscoverable() {
-        return bluetoothType.isConnected();
-    }
-
-    public void ensureBluetoothDiscoverable() {
-        bluetoothType.start();
-    }
-
-    public void makeBluetoothNonDiscoverable() {
-        bluetoothType.stop();
+        return bluetoothSwap.isConnected();
     }
 
     private boolean isWifiConnected() {
@@ -461,16 +420,6 @@ public class SwapService extends Service {
         return isWifiConnected() && isEnabled();
     }
 
-    public void ensureBonjourDiscoverable() {
-        if (!isBonjourDiscoverable()) {
-            // TODO: Enable bonjour (currently it is enabled by default when the service starts)
-        }
-    }
-
-    public void makeBonjourNotDiscoverable() {
-        // TODO: Disable bonjour (currently it is enabled by default when the service starts)
-    }
-
     public boolean isScanningForPeers() {
         return bonjourFinder.isScanning() || bluetoothFinder.isScanning();
     }
@@ -492,9 +441,8 @@ public class SwapService extends Service {
     private static final int NOTIFICATION = 1;
 
     private final Binder binder = new Binder();
-    private SwapType bonjourType;
-    private SwapType bluetoothType;
-    private SwapType webServerType;
+    private SwapType bluetoothSwap;
+    private WifiSwap wifiSwap;
 
     private BonjourFinder bonjourFinder;
     private BluetoothFinder bluetoothFinder;
@@ -507,12 +455,12 @@ public class SwapService extends Service {
     @Nullable
     private Timer timer;
 
-    public SwapType getBluetooth() {
-        return bluetoothType;
+    public SwapType getBluetoothSwap() {
+        return bluetoothSwap;
     }
 
-    public SwapType getBonjour() {
-        return bluetoothType;
+    public SwapType getWifiSwap() {
+        return wifiSwap;
     }
 
     public class Binder extends android.os.Binder {
@@ -529,13 +477,11 @@ public class SwapService extends Service {
         SharedPreferences preferences = getSharedPreferences(SHARED_PREFERENCES, Context.MODE_PRIVATE);
 
         appsToSwap.addAll(deserializePackages(preferences.getString(KEY_APPS_TO_SWAP, "")));
-        bonjourType = new BonjourType(this);
-        bluetoothType = BluetoothType.create(this);
-        webServerType = new WebServerType(this);
+        bluetoothSwap = BluetoothSwap.create(this);
+        wifiSwap = new WifiSwap(this);
         bonjourFinder = new BonjourFinder(this);
         bluetoothFinder = new BluetoothFinder(this);
 
-        Preferences.get().registerLocalRepoBonjourListeners(bonjourEnabledListener);
         Preferences.get().registerLocalRepoHttpsListeners(httpsEnabledListener);
 
         LocalBroadcastManager.getInstance(this).registerReceiver(onWifiChange, new IntentFilter(WifiStateChangeService.BROADCAST));
@@ -552,12 +498,23 @@ public class SwapService extends Service {
         return binder;
     }
 
+    public void disableAllSwapping() {
+        new AsyncTask<Void, Void, Void>() {
+            @Override
+            protected Void doInBackground(Void... params) {
+                getBluetoothSwap().stop();
+                getWifiSwap().stop();
+                detachService();
+                return null;
+            }
+        }.execute();
+    }
+
     @Override
     public void onDestroy() {
         super.onDestroy();
         Log.d(TAG, "Destroying service, will disable swapping if required, and unregister listeners.");
-        disableSwapping();
-        Preferences.get().unregisterLocalRepoBonjourListeners(bonjourEnabledListener);
+        disableAllSwapping();
         Preferences.get().unregisterLocalRepoHttpsListeners(httpsEnabledListener);
         LocalBroadcastManager.getInstance(this).unregisterReceiver(onWifiChange);
     }
@@ -574,29 +531,6 @@ public class SwapService extends Service {
                 .build();
     }
 
-    private boolean enabled = false;
-
-    /**
-     * The guts of this class - responsible for enabling the relevant services for swapping.
-     * Doesn't know anything about enabled/disabled state, you should check that before invoking
-     * this method so it doesn't start something that is already started.
-     * Runs asynchronously on several background threads.
-     */
-    private void enableSwappingAsynchronous() {
-        webServerType.startInBackground();
-        bonjourType.startInBackground();
-        bluetoothType.startInBackground();
-    }
-
-    /**
-     * @see SwapService#enableSwappingAsynchronous()
-     */
-    private void disableSwappingSynchronous() {
-        Log.d(TAG, "Disabling SwapService (bonjour, webserver, etc)");
-        bonjourType.stop();
-        webServerType.stop();
-    }
-
     private void initTimer() {
         if (timer != null) {
             Log.d(TAG, "Cancelling existing timer");
@@ -610,31 +544,17 @@ public class SwapService extends Service {
             @Override
             public void run() {
                 Log.d(TAG, "Disabling swap because " + TIMEOUT + "ms passed.");
-                disableSwapping();
+                disableAllSwapping();
             }
         }, TIMEOUT);
     }
 
-    @SuppressWarnings("FieldCanBeLocal") // The constructor will get bloated if these are all local...
-    // TODO: Remove this preference...
-    private final Preferences.ChangeListener bonjourEnabledListener = new Preferences.ChangeListener() {
-        @Override
-        public void onPreferenceChange() {
-            Log.i(TAG, "Use Bonjour while swapping preference changed.");
-            if (enabled)
-                if (Preferences.get().isLocalRepoBonjourEnabled())
-                    bonjourType.start();
-                else
-                    bonjourType.stop();
-        }
-    };
-
     @SuppressWarnings("FieldCanBeLocal") // The constructor will get bloated if these are all local...
     private final Preferences.ChangeListener httpsEnabledListener = new Preferences.ChangeListener() {
         @Override
         public void onPreferenceChange() {
             Log.i(TAG, "Swap over HTTPS preference changed.");
-            restartIfEnabled();
+            restartWifiIfEnabled();
         }
     };
 
@@ -642,7 +562,7 @@ public class SwapService extends Service {
     private final BroadcastReceiver onWifiChange = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent i) {
-            restartIfEnabled();
+            restartWifiIfEnabled();
         }
     };
 
diff --git a/F-Droid/src/org/fdroid/fdroid/localrepo/type/BluetoothType.java b/F-Droid/src/org/fdroid/fdroid/localrepo/type/BluetoothSwap.java
similarity index 94%
rename from F-Droid/src/org/fdroid/fdroid/localrepo/type/BluetoothType.java
rename to F-Droid/src/org/fdroid/fdroid/localrepo/type/BluetoothSwap.java
index f4024fada..3898b1c17 100644
--- a/F-Droid/src/org/fdroid/fdroid/localrepo/type/BluetoothType.java
+++ b/F-Droid/src/org/fdroid/fdroid/localrepo/type/BluetoothSwap.java
@@ -11,7 +11,7 @@ import android.util.Log;
 import org.fdroid.fdroid.localrepo.SwapService;
 import org.fdroid.fdroid.net.bluetooth.BluetoothServer;
 
-public class BluetoothType extends SwapType {
+public class BluetoothSwap extends SwapType {
 
     private static final String TAG = "BluetoothBroadcastType";
 
@@ -25,11 +25,11 @@ public class BluetoothType extends SwapType {
         if (adapter == null) {
             return new NoBluetoothType(context);
         } else {
-            return new BluetoothType(context, adapter);
+            return new BluetoothSwap(context, adapter);
         }
     };
 
-    private BluetoothType(@NonNull Context context, @NonNull BluetoothAdapter adapter) {
+    private BluetoothSwap(@NonNull Context context, @NonNull BluetoothAdapter adapter) {
         super(context);
         this.adapter = adapter;
         this.server = new BluetoothServer(context, context.getFilesDir());
diff --git a/F-Droid/src/org/fdroid/fdroid/localrepo/type/BonjourType.java b/F-Droid/src/org/fdroid/fdroid/localrepo/type/BonjourBroadcast.java
similarity index 88%
rename from F-Droid/src/org/fdroid/fdroid/localrepo/type/BonjourType.java
rename to F-Droid/src/org/fdroid/fdroid/localrepo/type/BonjourBroadcast.java
index f6b6ac099..ab50642a0 100644
--- a/F-Droid/src/org/fdroid/fdroid/localrepo/type/BonjourType.java
+++ b/F-Droid/src/org/fdroid/fdroid/localrepo/type/BonjourBroadcast.java
@@ -18,14 +18,14 @@ import javax.jmdns.ServiceInfo;
 /**
  * Sends a {@link SwapService#BONJOUR_STATE_CHANGE} broadcasts when starting, started or stopped.
  */
-public class BonjourType extends SwapType {
+public class BonjourBroadcast extends SwapType {
 
     private static final String TAG = "BonjourSwapService";
 
     private JmDNS jmdns;
     private ServiceInfo pairService;
 
-    public BonjourType(Context context) {
+    public BonjourBroadcast(Context context) {
         super(context);
     }
 
@@ -33,12 +33,6 @@ public class BonjourType extends SwapType {
     public void start() {
 
         Log.d(TAG, "Preparing to start Bonjour service.");
-        if (!Preferences.get().isLocalRepoBonjourEnabled()) {
-            // TODO: Remove this preference completely, it is now dealt with in the start swap screen.
-            Log.i(TAG, "Not going to start Bonjour swap service because disabled via preferences.");
-            return;
-        }
-
         sendBroadcast(SwapService.EXTRA_STARTING);
 
         /*
diff --git a/F-Droid/src/org/fdroid/fdroid/localrepo/type/SwapType.java b/F-Droid/src/org/fdroid/fdroid/localrepo/type/SwapType.java
index cabcbc660..47b37b3be 100644
--- a/F-Droid/src/org/fdroid/fdroid/localrepo/type/SwapType.java
+++ b/F-Droid/src/org/fdroid/fdroid/localrepo/type/SwapType.java
@@ -70,4 +70,20 @@ public abstract class SwapType {
             }
         }.execute();
     }
+
+    public void ensureRunning() {
+        if (!isConnected()) {
+            start();
+        }
+    }
+
+    public void ensureRunningInBackground() {
+        new AsyncTask<Void, Void, Void>() {
+            @Override
+            protected Void doInBackground(Void... params) {
+                ensureRunning();
+                return null;
+            }
+        }.execute();
+    }
 }
diff --git a/F-Droid/src/org/fdroid/fdroid/localrepo/type/WebServerType.java b/F-Droid/src/org/fdroid/fdroid/localrepo/type/WifiSwap.java
similarity index 92%
rename from F-Droid/src/org/fdroid/fdroid/localrepo/type/WebServerType.java
rename to F-Droid/src/org/fdroid/fdroid/localrepo/type/WifiSwap.java
index 997d5f647..91008ef83 100644
--- a/F-Droid/src/org/fdroid/fdroid/localrepo/type/WebServerType.java
+++ b/F-Droid/src/org/fdroid/fdroid/localrepo/type/WifiSwap.java
@@ -17,15 +17,17 @@ import java.io.IOException;
 import java.net.BindException;
 import java.util.Random;
 
-public class WebServerType extends SwapType {
+public class WifiSwap extends SwapType {
 
     private static final String TAG = "WebServerType";
 
     private Handler webServerThreadHandler = null;
     private LocalHTTPD localHttpd;
+    private final SwapType bonjourBroadcast;
 
-    public WebServerType(Context context) {
+    public WifiSwap(Context context) {
         super(context);
+        bonjourBroadcast = new BonjourBroadcast(context);
     }
 
     @Override
@@ -69,6 +71,7 @@ public class WebServerType extends SwapType {
             }
         };
         new Thread(webServer).start();
+        bonjourBroadcast.start();
     }
 
     @Override
@@ -81,6 +84,7 @@ public class WebServerType extends SwapType {
         Message msg = webServerThreadHandler.obtainMessage();
         msg.obj = webServerThreadHandler.getLooper().getThread().getName() + " says stop";
         webServerThreadHandler.sendMessage(msg);
+        bonjourBroadcast.stop();
     }
 
 }
diff --git a/F-Droid/src/org/fdroid/fdroid/net/WifiStateChangeService.java b/F-Droid/src/org/fdroid/fdroid/net/WifiStateChangeService.java
index dc763ae1a..ae6aeb5e8 100644
--- a/F-Droid/src/org/fdroid/fdroid/net/WifiStateChangeService.java
+++ b/F-Droid/src/org/fdroid/fdroid/net/WifiStateChangeService.java
@@ -166,7 +166,7 @@ public class WifiStateChangeService extends Service {
             bindService(swapService, new ServiceConnection() {
                 @Override
                 public void onServiceConnected(ComponentName name, IBinder service) {
-                    ((SwapService.Binder)service).getService().restartIfEnabled();
+                    ((SwapService.Binder)service).getService().restartWifiIfEnabled();
                     unbindService(this);
                 }
 
diff --git a/F-Droid/src/org/fdroid/fdroid/views/fragments/PreferencesFragment.java b/F-Droid/src/org/fdroid/fdroid/views/fragments/PreferencesFragment.java
index 294733b0d..4f1756ba3 100644
--- a/F-Droid/src/org/fdroid/fdroid/views/fragments/PreferencesFragment.java
+++ b/F-Droid/src/org/fdroid/fdroid/views/fragments/PreferencesFragment.java
@@ -34,7 +34,6 @@ public class PreferencesFragment extends PreferenceFragment
         Preferences.PREF_PERMISSIONS,
         Preferences.PREF_COMPACT_LAYOUT,
         Preferences.PREF_IGN_TOUCH,
-        Preferences.PREF_LOCAL_REPO_BONJOUR,
         Preferences.PREF_LOCAL_REPO_NAME,
         Preferences.PREF_LOCAL_REPO_HTTPS,
         Preferences.PREF_LANGUAGE,
@@ -127,10 +126,6 @@ public class PreferencesFragment extends PreferenceFragment
             checkSummary(key, R.string.ignoreTouch_on);
             break;
 
-        case Preferences.PREF_LOCAL_REPO_BONJOUR:
-            checkSummary(key, R.string.local_repo_bonjour_on);
-            break;
-
         case Preferences.PREF_LOCAL_REPO_NAME:
             textSummary(key, R.string.local_repo_name_summary);
             break;
diff --git a/F-Droid/src/org/fdroid/fdroid/views/swap/StartSwapView.java b/F-Droid/src/org/fdroid/fdroid/views/swap/StartSwapView.java
index 496ca2aa5..fc819f927 100644
--- a/F-Droid/src/org/fdroid/fdroid/views/swap/StartSwapView.java
+++ b/F-Droid/src/org/fdroid/fdroid/views/swap/StartSwapView.java
@@ -216,13 +216,13 @@ public class StartSwapView extends ScrollView implements SwapWorkflowActivity.In
                 @Override
                 public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                     if (isChecked) {
-                        getActivity().connectWithBluetooth();
+                        getActivity().startBluetoothSwap();
                         textBluetoothVisible.setText(R.string.swap_visible_bluetooth);
                         viewBluetoothId.setVisibility(View.VISIBLE);
                         uiUpdatePeersInfo();
                         // TODO: When they deny the request for enabling bluetooth, we need to disable this switch...
                     } else {
-                        getManager().makeBluetoothNonDiscoverable();
+                        getManager().getBluetoothSwap().stop();
                         textBluetoothVisible.setText(R.string.swap_not_visible_bluetooth);
                         viewBluetoothId.setVisibility(View.GONE);
                         uiUpdatePeersInfo();
@@ -266,9 +266,9 @@ public class StartSwapView extends ScrollView implements SwapWorkflowActivity.In
             @Override
             public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                 if (isChecked) {
-                    getManager().ensureBonjourDiscoverable();
+                    getManager().getWifiSwap().ensureRunningInBackground();
                 } else {
-                    getManager().makeBonjourNotDiscoverable();
+                    getManager().getWifiSwap().stop();
                 }
                 uiUpdatePeersInfo();
                 uiUpdateWifi();
@@ -279,16 +279,16 @@ public class StartSwapView extends ScrollView implements SwapWorkflowActivity.In
             @Override
             public void onReceive(Context context, Intent intent) {
                 if (intent.hasExtra(SwapService.EXTRA_STARTING)) {
-                    Log.d(TAG, "Bonjour service is starting...");
+                    Log.d(TAG, "Bonjour/WiFi service is starting...");
                     wifiSwitch.setEnabled(false);
                     wifiSwitch.setChecked(true);
                 } else {
                     wifiSwitch.setEnabled(true);
                     if (intent.hasExtra(SwapService.EXTRA_STARTED)) {
-                        Log.d(TAG, "Bonjour service has started.");
+                        Log.d(TAG, "Bonjour/WiFi service has started.");
                         wifiSwitch.setChecked(true);
                     } else {
-                        Log.d(TAG, "Bonjour service has stopped.");
+                        Log.d(TAG, "Bonjour/WiFi service has stopped.");
                         wifiSwitch.setChecked(false);
                     }
                 }
diff --git a/F-Droid/src/org/fdroid/fdroid/views/swap/SwapWorkflowActivity.java b/F-Droid/src/org/fdroid/fdroid/views/swap/SwapWorkflowActivity.java
index 8cde31216..f9546b394 100644
--- a/F-Droid/src/org/fdroid/fdroid/views/swap/SwapWorkflowActivity.java
+++ b/F-Droid/src/org/fdroid/fdroid/views/swap/SwapWorkflowActivity.java
@@ -272,7 +272,7 @@ public class SwapWorkflowActivity extends AppCompatActivity {
     }
 
     private void onToolbarCancel() {
-        getService().disableSwapping();
+        getService().disableAllSwapping();
         finish();
     }
 
@@ -377,11 +377,6 @@ public class SwapWorkflowActivity extends AppCompatActivity {
         return false;
     }
 
-    public void stopSwapping() {
-        getState().disableSwapping();
-        finish();
-    }
-
     public void swapWith(Peer peer) {
         getService().swapWith(peer);
         showSelectApps();
@@ -431,7 +426,7 @@ public class SwapWorkflowActivity extends AppCompatActivity {
 
             if (resultCode != RESULT_CANCELED) {
                 Log.d(TAG, "User made Bluetooth discoverable, will proceed to start bluetooth server.");
-                startBluetoothServer();
+                getState().getBluetoothSwap().startInBackground();
             } else {
                 Log.d(TAG, "User chose not to make Bluetooth discoverable, so doing nothing (i.e. sticking with wifi).");
             }
@@ -450,14 +445,14 @@ public class SwapWorkflowActivity extends AppCompatActivity {
      * Note that this is a little different than the usual process for bluetooth _clients_, which
      * involves pairing and connecting with other devices.
      */
-    public void connectWithBluetooth() {
+    public void startBluetoothSwap() {
 
-        Log.d(TAG, "Initiating Bluetooth swap instead of wifi.");
+        Log.d(TAG, "Initiating Bluetooth swap, will ensure the Bluetooth devices is enabled and discoverable before starting server.");
         BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
 
         if (adapter != null)
             if (adapter.isEnabled()) {
-                Log.d(TAG, "Bluetooth enabled, will pair with device.");
+                Log.d(TAG, "Bluetooth enabled, will check if device is discoverable with device.");
                 ensureBluetoothDiscoverableThenStart();
             } else {
                 Log.d(TAG, "Bluetooth disabled, asking user to enable it.");
@@ -483,34 +478,13 @@ public class SwapWorkflowActivity extends AppCompatActivity {
             throw new IllegalStateException("Can't start Bluetooth swap because service is null for some strange reason.");
         }
 
-        service.getBluetooth().startInBackground();
+        service.getBluetoothSwap().startInBackground();
     }
 
-    private void startBluetoothServer() {
-        Log.d(TAG, "Starting bluetooth server.");
-        if (service == null) {
-            throw new IllegalStateException("We are attempting to do bluetooth stuff, but the service is not ready.");
-        }
-
-        if (!service.isEnabled()) {
-            service.enableSwapping();
-        }
-
-        new BluetoothServer(this,getFilesDir()).start();
-        showBluetoothDeviceList();
-    }
-
-
     class PrepareInitialSwapRepo extends PrepareSwapRepo {
         public PrepareInitialSwapRepo() {
             super(new HashSet<>(Arrays.asList(new String[] { "org.fdroid.fdroid" })));
         }
-
-        @Override
-        protected void onPreExecute() {
-            getService().enableSwapping();
-            super.onPreExecute();
-        }
     }
 
     class PrepareFullSwapRepo extends PrepareSwapRepo {
diff --git a/F-Droid/src/org/fdroid/fdroid/views/swap/WifiQrView.java b/F-Droid/src/org/fdroid/fdroid/views/swap/WifiQrView.java
index c2e8354d0..2d8741807 100644
--- a/F-Droid/src/org/fdroid/fdroid/views/swap/WifiQrView.java
+++ b/F-Droid/src/org/fdroid/fdroid/views/swap/WifiQrView.java
@@ -85,14 +85,6 @@ public class WifiQrView extends ScrollView implements SwapWorkflowActivity.Inner
             }
         });
 
-        Button cancel = (Button)findViewById(R.id.btn_cancel_swap);
-        cancel.setOnClickListener(new Button.OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                getActivity().stopSwapping();
-            }
-        });
-
         // TODO: As with the JoinWifiView, this should be refactored to be part of the SwapState.
         // Otherwise, we are left with SwapState, LocalRepoService, WifiStateChangeService, and
         // some static variables in FDroidApp all which manage the state for swap.