diff --git a/src/net/sf/briar/api/plugins/duplex/DuplexPluginFactory.java b/src/net/sf/briar/api/plugins/duplex/DuplexPluginFactory.java
index 047e4584617ec0089ce6b968b4f9a03457f2c9ae..9acaa56756b597dd0b875da097be91ab45080ef3 100644
--- a/src/net/sf/briar/api/plugins/duplex/DuplexPluginFactory.java
+++ b/src/net/sf/briar/api/plugins/duplex/DuplexPluginFactory.java
@@ -4,11 +4,13 @@ import java.util.concurrent.Executor;
 
 import net.sf.briar.api.android.AndroidExecutor;
 import net.sf.briar.api.lifecycle.ShutdownManager;
-
+import net.sf.briar.api.protocol.TransportId;
 import android.content.Context;
 
 public interface DuplexPluginFactory {
 
+	TransportId getId();
+
 	DuplexPlugin createPlugin(Executor pluginExecutor,
 			AndroidExecutor androidExecutor, Context appContext,
 			ShutdownManager shutdownManager, DuplexPluginCallback callback);
diff --git a/src/net/sf/briar/api/plugins/simplex/SimplexPluginFactory.java b/src/net/sf/briar/api/plugins/simplex/SimplexPluginFactory.java
index 6460d45a2161abcc05280c7ebbb88a34944b82a6..9970db4e0f4a7b0bab75c7cd48272c354d827967 100644
--- a/src/net/sf/briar/api/plugins/simplex/SimplexPluginFactory.java
+++ b/src/net/sf/briar/api/plugins/simplex/SimplexPluginFactory.java
@@ -4,11 +4,13 @@ import java.util.concurrent.Executor;
 
 import net.sf.briar.api.android.AndroidExecutor;
 import net.sf.briar.api.lifecycle.ShutdownManager;
-
+import net.sf.briar.api.protocol.TransportId;
 import android.content.Context;
 
 public interface SimplexPluginFactory {
 
+	TransportId getId();
+
 	SimplexPlugin createPlugin(Executor pluginExecutor,
 			AndroidExecutor androidExecutor, Context appContext,
 			ShutdownManager shutdownManager, SimplexPluginCallback callback);
diff --git a/src/net/sf/briar/plugins/PluginManagerImpl.java b/src/net/sf/briar/plugins/PluginManagerImpl.java
index ce9799afc26421945c07d338ffd186a3cf821a05..66fa356993d072d19559133abd386d382dd2a2c6 100644
--- a/src/net/sf/briar/plugins/PluginManagerImpl.java
+++ b/src/net/sf/briar/plugins/PluginManagerImpl.java
@@ -103,7 +103,13 @@ class PluginManagerImpl implements PluginManager {
 				Class<?> c = Class.forName(s);
 				SimplexPluginFactory factory =
 						(SimplexPluginFactory) c.newInstance();
-				SimplexCallback callback = new SimplexCallback();
+				TransportId id = factory.getId();
+				if(!ids.add(id)) {
+					if(LOG.isLoggable(WARNING))
+						LOG.warning("Duplicate transport ID: " + id);
+					continue;
+				}
+				SimplexCallback callback = new SimplexCallback(id);
 				SimplexPlugin plugin = factory.createPlugin(pluginExecutor,
 						androidExecutor, appContext, shutdownManager, callback);
 				if(plugin == null) {
@@ -113,15 +119,13 @@ class PluginManagerImpl implements PluginManager {
 					}
 					continue;
 				}
-				TransportId id = plugin.getId();
-				if(!ids.add(id)) {
-					if(LOG.isLoggable(WARNING))
-						LOG.warning("Duplicate transport ID: " + id);
-					continue;
+				if(plugin.start()) {
+					simplexPlugins.add(plugin);
+				} else {
+					if(LOG.isLoggable(INFO))
+						LOG.info(plugin.getClass().getSimpleName()
+								+ " did not start");
 				}
-				callback.init(id);
-				plugin.start();
-				simplexPlugins.add(plugin);
 			} catch(ClassCastException e) {
 				if(LOG.isLoggable(WARNING)) LOG.warning(e.toString());
 				continue;
@@ -137,7 +141,13 @@ class PluginManagerImpl implements PluginManager {
 				Class<?> c = Class.forName(s);
 				DuplexPluginFactory factory =
 						(DuplexPluginFactory) c.newInstance();
-				DuplexCallback callback = new DuplexCallback();
+				TransportId id = factory.getId();
+				if(!ids.add(id)) {
+					if(LOG.isLoggable(WARNING))
+						LOG.warning("Duplicate transport ID: " + id);
+					continue;
+				}
+				DuplexCallback callback = new DuplexCallback(id);
 				DuplexPlugin plugin = factory.createPlugin(pluginExecutor,
 						androidExecutor, appContext, shutdownManager, callback);
 				if(plugin == null) {
@@ -147,15 +157,13 @@ class PluginManagerImpl implements PluginManager {
 					}
 					continue;
 				}
-				TransportId id = plugin.getId();
-				if(!ids.add(id)) {
-					if(LOG.isLoggable(WARNING))
-						LOG.warning("Duplicate transport ID: " + id);
-					continue;
+				if(plugin.start()) {
+					duplexPlugins.add(plugin);
+				} else {
+					if(LOG.isLoggable(INFO))
+						LOG.info(plugin.getClass().getSimpleName()
+								+ " did not start");
 				}
-				callback.init(id);
-				plugin.start();
-				duplexPlugins.add(plugin);
 			} catch(ClassCastException e) {
 				if(LOG.isLoggable(WARNING)) LOG.warning(e.toString());
 				continue;
@@ -174,12 +182,12 @@ class PluginManagerImpl implements PluginManager {
 		return simplexPlugins.size() + duplexPlugins.size();
 	}
 
-	private String[] getSimplexPluginFactoryNames() {
+	private static String[] getSimplexPluginFactoryNames() {
 		if(OsUtils.isAndroid()) return ANDROID_SIMPLEX_FACTORIES;
 		return J2SE_SIMPLEX_FACTORIES;
 	}
 
-	private String[] getDuplexPluginFactoryNames() {
+	private static String[] getDuplexPluginFactoryNames() {
 		if(OsUtils.isAndroid()) return ANDROID_DUPLEX_FACTORIES;
 		return J2SE_DUPLEX_FACTORIES;
 	}
@@ -219,27 +227,22 @@ class PluginManagerImpl implements PluginManager {
 		return stopped;
 	}
 
-	public Collection<DuplexPlugin> getInvitationPlugins() {
+	public synchronized Collection<DuplexPlugin> getInvitationPlugins() {
 		Collection<DuplexPlugin> supported = new ArrayList<DuplexPlugin>();
-		synchronized(this) {
-			for(DuplexPlugin d : duplexPlugins) {
-				if(d.supportsInvitations()) supported.add(d);
-			}
-		}
+		for(DuplexPlugin d : duplexPlugins)
+			if(d.supportsInvitations()) supported.add(d);
 		return supported;
 	}
 
 	private abstract class PluginCallbackImpl implements PluginCallback {
 
-		protected volatile TransportId id = null;
+		protected final TransportId id;
 
-		protected void init(TransportId id) {
-			assert this.id == null;
+		protected PluginCallbackImpl(TransportId id) {
 			this.id = id;
 		}
 
 		public TransportConfig getConfig() {
-			assert id != null;
 			try {
 				return db.getConfig(id);
 			} catch(DbException e) {
@@ -249,7 +252,6 @@ class PluginManagerImpl implements PluginManager {
 		}
 
 		public TransportProperties getLocalProperties() {
-			assert id != null;
 			try {
 				TransportProperties p = db.getLocalProperties(id);
 				return p == null ? new TransportProperties() : p;
@@ -260,7 +262,6 @@ class PluginManagerImpl implements PluginManager {
 		}
 
 		public Map<ContactId, TransportProperties> getRemoteProperties() {
-			assert id != null;
 			try {
 				return db.getRemoteProperties(id);
 			} catch(DbException e) {
@@ -270,7 +271,6 @@ class PluginManagerImpl implements PluginManager {
 		}
 
 		public void mergeConfig(TransportConfig c) {
-			assert id != null;
 			try {
 				db.mergeConfig(id, c);
 			} catch(DbException e) {
@@ -279,7 +279,6 @@ class PluginManagerImpl implements PluginManager {
 		}
 
 		public void mergeLocalProperties(TransportProperties p) {
-			assert id != null;
 			try {
 				db.mergeLocalProperties(id, p);
 			} catch(DbException e) {
@@ -303,8 +302,11 @@ class PluginManagerImpl implements PluginManager {
 	private class SimplexCallback extends PluginCallbackImpl
 	implements SimplexPluginCallback {
 
+		private SimplexCallback(TransportId id) {
+			super(id);
+		}
+
 		public void readerCreated(SimplexTransportReader r) {
-			assert id != null;
 			dispatcher.dispatchReader(id, r);
 		}
 
@@ -316,8 +318,11 @@ class PluginManagerImpl implements PluginManager {
 	private class DuplexCallback extends PluginCallbackImpl
 	implements DuplexPluginCallback {
 
+		private DuplexCallback(TransportId id) {
+			super(id);
+		}
+
 		public void incomingConnectionCreated(DuplexTransportConnection d) {
-			assert id != null;
 			dispatcher.dispatchIncomingConnection(id, d);
 		}
 
diff --git a/src/net/sf/briar/plugins/bluetooth/BluetoothPlugin.java b/src/net/sf/briar/plugins/bluetooth/BluetoothPlugin.java
index 5fac5810c34649c686f65ec0a6800188cf17c1c8..7eb6ebb321379af70dfbfdd4edcd71d9e961548f 100644
--- a/src/net/sf/briar/plugins/bluetooth/BluetoothPlugin.java
+++ b/src/net/sf/briar/plugins/bluetooth/BluetoothPlugin.java
@@ -38,11 +38,12 @@ import net.sf.briar.util.StringUtils;
 class BluetoothPlugin implements DuplexPlugin {
 
 	// Share an ID with the Android Bluetooth plugin
-	private static final byte[] TRANSPORT_ID =
+	static final byte[] TRANSPORT_ID =
 			StringUtils.fromHexString("d99c9313c04417dcf22fc60d12a187ea"
 					+ "00a539fd260f08a13a0d8a900cde5e49"
 					+ "1b4df2ffd42e40c408f2db7868f518aa");
-	private static final TransportId ID = new TransportId(TRANSPORT_ID);
+	static final TransportId ID = new TransportId(TRANSPORT_ID);
+
 	private static final Logger LOG =
 			Logger.getLogger(BluetoothPlugin.class.getName());
 
diff --git a/src/net/sf/briar/plugins/bluetooth/BluetoothPluginFactory.java b/src/net/sf/briar/plugins/bluetooth/BluetoothPluginFactory.java
index 2d9754fde9c1062d0987654924fdced5b30399ae..20f07008d8a4e5a5753367221e90e13246ce4260 100644
--- a/src/net/sf/briar/plugins/bluetooth/BluetoothPluginFactory.java
+++ b/src/net/sf/briar/plugins/bluetooth/BluetoothPluginFactory.java
@@ -9,12 +9,17 @@ import net.sf.briar.api.plugins.PluginExecutor;
 import net.sf.briar.api.plugins.duplex.DuplexPlugin;
 import net.sf.briar.api.plugins.duplex.DuplexPluginCallback;
 import net.sf.briar.api.plugins.duplex.DuplexPluginFactory;
+import net.sf.briar.api.protocol.TransportId;
 import android.content.Context;
 
 public class BluetoothPluginFactory implements DuplexPluginFactory {
 
 	private static final long POLLING_INTERVAL = 3L * 60L * 1000L; // 3 mins
 
+	public TransportId getId() {
+		return BluetoothPlugin.ID;
+	}
+
 	public DuplexPlugin createPlugin(@PluginExecutor Executor pluginExecutor,
 			AndroidExecutor androidExecutor, Context appContext,
 			ShutdownManager shutdownManager, DuplexPluginCallback callback) {
diff --git a/src/net/sf/briar/plugins/droidtooth/DroidtoothPlugin.java b/src/net/sf/briar/plugins/droidtooth/DroidtoothPlugin.java
index 9f134200b51134ef6a66eae9196b7de3bff14fa6..120bb09c4cfd1b42eaa8ccb66df31476fa7a642c 100644
--- a/src/net/sf/briar/plugins/droidtooth/DroidtoothPlugin.java
+++ b/src/net/sf/briar/plugins/droidtooth/DroidtoothPlugin.java
@@ -44,11 +44,12 @@ import android.content.IntentFilter;
 class DroidtoothPlugin implements DuplexPlugin {
 
 	// Share an ID with the J2SE Bluetooth plugin
-	private static final byte[] TRANSPORT_ID =
+	static final byte[] TRANSPORT_ID =
 			StringUtils.fromHexString("d99c9313c04417dcf22fc60d12a187ea"
 					+ "00a539fd260f08a13a0d8a900cde5e49"
 					+ "1b4df2ffd42e40c408f2db7868f518aa");
-	private static final TransportId ID = new TransportId(TRANSPORT_ID);
+	static final TransportId ID = new TransportId(TRANSPORT_ID);
+
 	private static final Logger LOG =
 			Logger.getLogger(DroidtoothPlugin.class.getName());
 	private static final String FOUND = "android.bluetooth.device.action.FOUND";
diff --git a/src/net/sf/briar/plugins/droidtooth/DroidtoothPluginFactory.java b/src/net/sf/briar/plugins/droidtooth/DroidtoothPluginFactory.java
index 7e438c5483555d609a898e9276fa64b147dd79f9..86244f0a1a9031178c390522f640d64d7b268967 100644
--- a/src/net/sf/briar/plugins/droidtooth/DroidtoothPluginFactory.java
+++ b/src/net/sf/briar/plugins/droidtooth/DroidtoothPluginFactory.java
@@ -8,12 +8,17 @@ import net.sf.briar.api.plugins.PluginExecutor;
 import net.sf.briar.api.plugins.duplex.DuplexPlugin;
 import net.sf.briar.api.plugins.duplex.DuplexPluginCallback;
 import net.sf.briar.api.plugins.duplex.DuplexPluginFactory;
+import net.sf.briar.api.protocol.TransportId;
 import android.content.Context;
 
 public class DroidtoothPluginFactory implements DuplexPluginFactory {
 
 	private static final long POLLING_INTERVAL = 3L * 60L * 1000L; // 3 mins
 
+	public TransportId getId() {
+		return DroidtoothPlugin.ID;
+	}
+
 	public DuplexPlugin createPlugin(@PluginExecutor Executor pluginExecutor,
 			AndroidExecutor androidExecutor, Context appContext,
 			ShutdownManager shutdownManager, DuplexPluginCallback callback) {
diff --git a/src/net/sf/briar/plugins/file/RemovableDrivePlugin.java b/src/net/sf/briar/plugins/file/RemovableDrivePlugin.java
index 15914a70d6f3175d307cdc2af3a7d96fb5cdbf7a..3657ee8518cd3fb94014ec9e1c77af7ee0064dfa 100644
--- a/src/net/sf/briar/plugins/file/RemovableDrivePlugin.java
+++ b/src/net/sf/briar/plugins/file/RemovableDrivePlugin.java
@@ -20,11 +20,12 @@ import net.sf.briar.util.StringUtils;
 class RemovableDrivePlugin extends FilePlugin
 implements RemovableDriveMonitor.Callback {
 
-	private static final byte[] TRANSPORT_ID =
+	static final byte[] TRANSPORT_ID =
 			StringUtils.fromHexString("7c81bf5c9b1cd557685548c85f976bbd"
 					+ "e633d2418ea2e230e5710fb43c6f8cc0"
 					+ "68abca3a9d0edb13bcea13b851725c5d");
-	private static final TransportId ID = new TransportId(TRANSPORT_ID);
+	static final TransportId ID = new TransportId(TRANSPORT_ID);
+
 	private static final Logger LOG =
 			Logger.getLogger(RemovableDrivePlugin.class.getName());
 
diff --git a/src/net/sf/briar/plugins/file/RemovableDrivePluginFactory.java b/src/net/sf/briar/plugins/file/RemovableDrivePluginFactory.java
index 26ecec3675743b1c700ce819145b680a9ecf47d1..833e131bae31acc712a390dca6134a7de139ee8f 100644
--- a/src/net/sf/briar/plugins/file/RemovableDrivePluginFactory.java
+++ b/src/net/sf/briar/plugins/file/RemovableDrivePluginFactory.java
@@ -8,6 +8,7 @@ import net.sf.briar.api.plugins.PluginExecutor;
 import net.sf.briar.api.plugins.simplex.SimplexPlugin;
 import net.sf.briar.api.plugins.simplex.SimplexPluginCallback;
 import net.sf.briar.api.plugins.simplex.SimplexPluginFactory;
+import net.sf.briar.api.protocol.TransportId;
 import net.sf.briar.util.OsUtils;
 import android.content.Context;
 
@@ -15,6 +16,10 @@ public class RemovableDrivePluginFactory implements SimplexPluginFactory {
 
 	private static final long POLLING_INTERVAL = 10L * 1000L; // 10 seconds
 
+	public TransportId getId() {
+		return RemovableDrivePlugin.ID;
+	}
+
 	public SimplexPlugin createPlugin(@PluginExecutor Executor pluginExecutor,
 			AndroidExecutor androidExecutor, Context appContext,
 			ShutdownManager shutdownManager, SimplexPluginCallback callback) {
diff --git a/src/net/sf/briar/plugins/modem/ModemPlugin.java b/src/net/sf/briar/plugins/modem/ModemPlugin.java
index d97d6232ee4ed5c2cba91c8f31dd34a99ce8eb8f..bb4065dbf2dfc2daf5d627d1fb39b1f90340f2a8 100644
--- a/src/net/sf/briar/plugins/modem/ModemPlugin.java
+++ b/src/net/sf/briar/plugins/modem/ModemPlugin.java
@@ -16,11 +16,12 @@ import net.sf.briar.util.StringUtils;
 
 class ModemPlugin implements DuplexPlugin {
 
-	private static final byte[] TRANSPORT_ID =
+	static final byte[] TRANSPORT_ID =
 			StringUtils.fromHexString("8f573867bedf54884b5868ee5d902832" +
 					"ee5e522da84d0d431712bd672fbd2f79" +
 					"262d27b93879b94ee9afbb80e7fc87fb");
-	private static final TransportId ID = new TransportId(TRANSPORT_ID);
+	static final TransportId ID = new TransportId(TRANSPORT_ID);
+
 	private static final Logger LOG =
 			Logger.getLogger(ModemPlugin.class.getName());
 
diff --git a/src/net/sf/briar/plugins/modem/ModemPluginFactory.java b/src/net/sf/briar/plugins/modem/ModemPluginFactory.java
index 5b2c4fab1de7f0490b3d8519d159d8707a5a5f1f..3b7e81588be2e7682b242fd6e4dccb03ddfdc0d1 100644
--- a/src/net/sf/briar/plugins/modem/ModemPluginFactory.java
+++ b/src/net/sf/briar/plugins/modem/ModemPluginFactory.java
@@ -2,20 +2,26 @@ package net.sf.briar.plugins.modem;
 
 import java.util.concurrent.Executor;
 
-import org.h2.util.StringUtils;
-
 import net.sf.briar.api.android.AndroidExecutor;
 import net.sf.briar.api.lifecycle.ShutdownManager;
 import net.sf.briar.api.plugins.PluginExecutor;
 import net.sf.briar.api.plugins.duplex.DuplexPlugin;
 import net.sf.briar.api.plugins.duplex.DuplexPluginCallback;
 import net.sf.briar.api.plugins.duplex.DuplexPluginFactory;
+import net.sf.briar.api.protocol.TransportId;
+
+import org.h2.util.StringUtils;
+
 import android.content.Context;
 
 public class ModemPluginFactory implements DuplexPluginFactory {
 
 	private static final long POLLING_INTERVAL = 60L * 60L * 1000L; // 1 hour
 
+	public TransportId getId() {
+		return ModemPlugin.ID;
+	}
+
 	public DuplexPlugin createPlugin(@PluginExecutor Executor pluginExecutor,
 			AndroidExecutor androidExecutor, Context appContext,
 			ShutdownManager shutdownManager, DuplexPluginCallback callback) {
diff --git a/src/net/sf/briar/plugins/tcp/LanTcpPlugin.java b/src/net/sf/briar/plugins/tcp/LanTcpPlugin.java
index ecfbfcb3f92c08fc903d2dfda46ed896d793e3c1..3a710ae6ca91da3ad231574d824f2d7751a4e6ad 100644
--- a/src/net/sf/briar/plugins/tcp/LanTcpPlugin.java
+++ b/src/net/sf/briar/plugins/tcp/LanTcpPlugin.java
@@ -33,11 +33,12 @@ import net.sf.briar.util.StringUtils;
 /** A socket plugin that supports exchanging invitations over a LAN. */
 class LanTcpPlugin extends TcpPlugin {
 
-	private static final byte[] TRANSPORT_ID =
+	static final byte[] TRANSPORT_ID =
 			StringUtils.fromHexString("0d79357fd7f74d66c2f6f6ad0f7fff81"
 					+ "d21c53a43b90b0507ed0683872d8e2fc"
 					+ "5a88e8f953638228dc26669639757bbf");
-	private static final TransportId ID = new TransportId(TRANSPORT_ID);
+	static final TransportId ID = new TransportId(TRANSPORT_ID);
+
 	private static final Logger LOG =
 			Logger.getLogger(LanTcpPlugin.class.getName());
 
diff --git a/src/net/sf/briar/plugins/tcp/LanTcpPluginFactory.java b/src/net/sf/briar/plugins/tcp/LanTcpPluginFactory.java
index 6abcba8997c9aa9ba808998577e562270d04f761..d3ff4eca2488728a271177d5a5e9bd5b4c519e7b 100644
--- a/src/net/sf/briar/plugins/tcp/LanTcpPluginFactory.java
+++ b/src/net/sf/briar/plugins/tcp/LanTcpPluginFactory.java
@@ -8,12 +8,17 @@ import net.sf.briar.api.plugins.PluginExecutor;
 import net.sf.briar.api.plugins.duplex.DuplexPlugin;
 import net.sf.briar.api.plugins.duplex.DuplexPluginCallback;
 import net.sf.briar.api.plugins.duplex.DuplexPluginFactory;
+import net.sf.briar.api.protocol.TransportId;
 import android.content.Context;
 
 public class LanTcpPluginFactory implements DuplexPluginFactory {
 
 	private static final long POLLING_INTERVAL = 60L * 1000L; // 1 minute
 
+	public TransportId getId() {
+		return LanTcpPlugin.ID;
+	}
+
 	public DuplexPlugin createPlugin(@PluginExecutor Executor pluginExecutor,
 			AndroidExecutor androidExecutor, Context appContext,
 			ShutdownManager shutdownManager, DuplexPluginCallback callback) {
diff --git a/src/net/sf/briar/plugins/tcp/WanTcpPlugin.java b/src/net/sf/briar/plugins/tcp/WanTcpPlugin.java
index 4fcca98908de1c3402335fe20734ae14c0cbd586..3b8a6a9c03496e4ebf8f900d115818c2d6b9e21b 100644
--- a/src/net/sf/briar/plugins/tcp/WanTcpPlugin.java
+++ b/src/net/sf/briar/plugins/tcp/WanTcpPlugin.java
@@ -24,11 +24,12 @@ import net.sf.briar.util.StringUtils;
 
 class WanTcpPlugin extends TcpPlugin {
 
-	private static final byte[] TRANSPORT_ID =
+	static final byte[] TRANSPORT_ID =
 			StringUtils.fromHexString("58c66d999e492b85065924acfd739d80"
 					+ "c65a62f87e5a4fc6c284f95908b9007d"
 					+ "512a93ebf89bf68f50a29e96eebf97b6");
-	private static final TransportId ID = new TransportId(TRANSPORT_ID);
+	static final TransportId ID = new TransportId(TRANSPORT_ID);
+
 	private static final Logger LOG =
 			Logger.getLogger(WanTcpPlugin.class.getName());
 
diff --git a/src/net/sf/briar/plugins/tcp/WanTcpPluginFactory.java b/src/net/sf/briar/plugins/tcp/WanTcpPluginFactory.java
index d4f89475bcdb94ea02a079f8a9621b928d6ed5bc..d280a23f774b4a71922e2a5eba431252eac2db69 100644
--- a/src/net/sf/briar/plugins/tcp/WanTcpPluginFactory.java
+++ b/src/net/sf/briar/plugins/tcp/WanTcpPluginFactory.java
@@ -8,12 +8,17 @@ import net.sf.briar.api.plugins.PluginExecutor;
 import net.sf.briar.api.plugins.duplex.DuplexPlugin;
 import net.sf.briar.api.plugins.duplex.DuplexPluginCallback;
 import net.sf.briar.api.plugins.duplex.DuplexPluginFactory;
+import net.sf.briar.api.protocol.TransportId;
 import android.content.Context;
 
 public class WanTcpPluginFactory implements DuplexPluginFactory {
 
 	private static final long POLLING_INTERVAL = 5L * 60L * 1000L; // 5 minutes
 
+	public TransportId getId() {
+		return WanTcpPlugin.ID;
+	}
+
 	public DuplexPlugin createPlugin(@PluginExecutor Executor pluginExecutor,
 			AndroidExecutor androidExecutor, Context appContext,
 			ShutdownManager shutdownManager, DuplexPluginCallback callback) {
diff --git a/src/net/sf/briar/plugins/tor/TorPlugin.java b/src/net/sf/briar/plugins/tor/TorPlugin.java
index 034603232fb1c43ca37b46a33409b654c57085f9..b4127d735fe9532cc80810378eeec10274196252 100644
--- a/src/net/sf/briar/plugins/tor/TorPlugin.java
+++ b/src/net/sf/briar/plugins/tor/TorPlugin.java
@@ -35,11 +35,12 @@ import org.silvertunnel.netlib.layer.tor.util.RSAKeyPair;
 
 class TorPlugin implements DuplexPlugin {
 
-	private static final byte[] TRANSPORT_ID =
+	static final byte[] TRANSPORT_ID =
 			StringUtils.fromHexString("f264721575cb7ee710772f35abeb3db4"
 					+ "a91f474e14de346be296c2efc99effdd"
 					+ "f35921e6ed87a25c201f044da4767981");
-	private static final TransportId ID = new TransportId(TRANSPORT_ID);
+	static final TransportId ID = new TransportId(TRANSPORT_ID);
+
 	private static final Logger LOG =
 			Logger.getLogger(TorPlugin.class.getName());
 
diff --git a/src/net/sf/briar/plugins/tor/TorPluginFactory.java b/src/net/sf/briar/plugins/tor/TorPluginFactory.java
index c6ff581443b5a67f58ba214644bdc093c27d42c1..8430fd9a27603fc59976ce82cd4e98f349513770 100644
--- a/src/net/sf/briar/plugins/tor/TorPluginFactory.java
+++ b/src/net/sf/briar/plugins/tor/TorPluginFactory.java
@@ -2,20 +2,26 @@ package net.sf.briar.plugins.tor;
 
 import java.util.concurrent.Executor;
 
-import org.h2.util.StringUtils;
-
 import net.sf.briar.api.android.AndroidExecutor;
 import net.sf.briar.api.lifecycle.ShutdownManager;
 import net.sf.briar.api.plugins.PluginExecutor;
 import net.sf.briar.api.plugins.duplex.DuplexPlugin;
 import net.sf.briar.api.plugins.duplex.DuplexPluginCallback;
 import net.sf.briar.api.plugins.duplex.DuplexPluginFactory;
+import net.sf.briar.api.protocol.TransportId;
+
+import org.h2.util.StringUtils;
+
 import android.content.Context;
 
 public class TorPluginFactory implements DuplexPluginFactory {
 
 	private static final long POLLING_INTERVAL = 15L * 60L * 1000L; // 15 mins
 
+	public TransportId getId() {
+		return TorPlugin.ID;
+	}
+
 	public DuplexPlugin createPlugin(@PluginExecutor Executor pluginExecutor,
 			AndroidExecutor androidExecutor, Context appContext,
 			ShutdownManager shutdownManager, DuplexPluginCallback callback) {