diff --git a/api/net/sf/briar/api/plugins/BatchPluginFactory.java b/api/net/sf/briar/api/plugins/BatchPluginFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..e8c665b216b6d248a5f233f5eee96e36bda48f62
--- /dev/null
+++ b/api/net/sf/briar/api/plugins/BatchPluginFactory.java
@@ -0,0 +1,9 @@
+package net.sf.briar.api.plugins;
+
+import java.util.concurrent.Executor;
+
+public interface BatchPluginFactory {
+
+	BatchPlugin createPlugin(Executor executor,
+			BatchPluginCallback callback);
+}
diff --git a/api/net/sf/briar/api/plugins/StreamPluginFactory.java b/api/net/sf/briar/api/plugins/StreamPluginFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..97246ffc5ebc0f2ac99bfe041053d22b9b65da8b
--- /dev/null
+++ b/api/net/sf/briar/api/plugins/StreamPluginFactory.java
@@ -0,0 +1,9 @@
+package net.sf.briar.api.plugins;
+
+import java.util.concurrent.Executor;
+
+public interface StreamPluginFactory {
+
+	StreamPlugin createPlugin(Executor executor,
+			StreamPluginCallback callback);
+}
diff --git a/components/net/sf/briar/plugins/bluetooth/BluetoothPluginFactory.java b/components/net/sf/briar/plugins/bluetooth/BluetoothPluginFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..ed9dfa8657e9a55df795648faa9e9a3c5cc908e7
--- /dev/null
+++ b/components/net/sf/briar/plugins/bluetooth/BluetoothPluginFactory.java
@@ -0,0 +1,17 @@
+package net.sf.briar.plugins.bluetooth;
+
+import java.util.concurrent.Executor;
+
+import net.sf.briar.api.plugins.StreamPluginCallback;
+import net.sf.briar.api.plugins.StreamPlugin;
+import net.sf.briar.api.plugins.StreamPluginFactory;
+
+public class BluetoothPluginFactory implements StreamPluginFactory {
+
+	private static final long POLLING_INTERVAL = 3L * 60L * 1000L; // 3 mins
+
+	public StreamPlugin createPlugin(Executor executor,
+			StreamPluginCallback callback) {
+		return new BluetoothPlugin(executor, callback, POLLING_INTERVAL);
+	}
+}
diff --git a/components/net/sf/briar/plugins/file/RemovableDrivePluginFactory.java b/components/net/sf/briar/plugins/file/RemovableDrivePluginFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..f42d322c7753e51a1f40e69ba57584e6c03b2d00
--- /dev/null
+++ b/components/net/sf/briar/plugins/file/RemovableDrivePluginFactory.java
@@ -0,0 +1,33 @@
+package net.sf.briar.plugins.file;
+
+import java.util.concurrent.Executor;
+
+import net.sf.briar.api.plugins.BatchPluginCallback;
+import net.sf.briar.api.plugins.BatchPlugin;
+import net.sf.briar.api.plugins.BatchPluginFactory;
+import net.sf.briar.util.OsUtils;
+
+public class RemovableDrivePluginFactory implements BatchPluginFactory {
+
+	private static final long POLLING_INTERVAL = 10L * 1000L; // 10 seconds
+
+	public BatchPlugin createPlugin(Executor executor,
+			BatchPluginCallback callback) {
+		RemovableDriveFinder finder;
+		RemovableDriveMonitor monitor;
+		if(OsUtils.isLinux()) {
+			finder = new LinuxRemovableDriveFinder();
+			monitor = new LinuxRemovableDriveMonitor();
+		} else if(OsUtils.isMac()) {
+			finder = new MacRemovableDriveFinder();
+			monitor = new MacRemovableDriveMonitor();
+		} else if(OsUtils.isWindows()) {
+			finder = new WindowsRemovableDriveFinder();
+			monitor = new PollingRemovableDriveMonitor(finder,
+					POLLING_INTERVAL);
+		} else {
+			return null;
+		}
+		return new RemovableDrivePlugin(executor, callback, finder, monitor);
+	}
+}
diff --git a/components/net/sf/briar/plugins/socket/SimpleSocketPluginFactory.java b/components/net/sf/briar/plugins/socket/SimpleSocketPluginFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..c96de3c196b15c1a3590a2f0f1711a1986243791
--- /dev/null
+++ b/components/net/sf/briar/plugins/socket/SimpleSocketPluginFactory.java
@@ -0,0 +1,17 @@
+package net.sf.briar.plugins.socket;
+
+import java.util.concurrent.Executor;
+
+import net.sf.briar.api.plugins.StreamPluginCallback;
+import net.sf.briar.api.plugins.StreamPlugin;
+import net.sf.briar.api.plugins.StreamPluginFactory;
+
+public class SimpleSocketPluginFactory implements StreamPluginFactory {
+
+	private static final long POLLING_INTERVAL = 5L * 60L * 1000L; // 5 mins
+
+	public StreamPlugin createPlugin(Executor executor,
+			StreamPluginCallback callback) {
+		return new SimpleSocketPlugin(executor, callback, POLLING_INTERVAL);
+	}
+}