diff --git a/components/net/sf/briar/plugins/file/FilePlugin.java b/components/net/sf/briar/plugins/file/FilePlugin.java
index 56e3d5bb054caf5a434f73b0899f91271a61a2bb..abe37fac527cd659dde2413ee13962ab2f1715cb 100644
--- a/components/net/sf/briar/plugins/file/FilePlugin.java
+++ b/components/net/sf/briar/plugins/file/FilePlugin.java
@@ -6,6 +6,7 @@ import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.OutputStream;
 import java.util.Map;
+import java.util.concurrent.Executor;
 
 import net.sf.briar.api.ContactId;
 import net.sf.briar.api.db.DbException;
@@ -23,6 +24,7 @@ import org.apache.commons.io.FileSystemUtils;
 abstract class FilePlugin implements BatchTransportPlugin {
 
 	private final ConnectionRecogniser recogniser;
+	private final Executor executor;
 
 	protected Map<String, String> localProperties = null;
 	protected Map<ContactId, Map<String, String>> remoteProperties = null;
@@ -34,8 +36,9 @@ abstract class FilePlugin implements BatchTransportPlugin {
 	protected abstract File chooseOutputDirectory();
 	protected abstract void writerFinished(File f);
 
-	FilePlugin(ConnectionRecogniser recogniser) {
+	FilePlugin(ConnectionRecogniser recogniser, Executor executor) {
 		this.recogniser = recogniser;
+		this.executor = executor;
 	}
 
 	public synchronized void start(Map<String, String> localProperties,
@@ -117,42 +120,55 @@ abstract class FilePlugin implements BatchTransportPlugin {
 		return FileSystemUtils.freeSpaceKb(path) * 1024L;
 	}
 
-	protected void createReaderFromFile(File f) {
+	protected void createReaderFromFile(final File f) {
 		if(!started) throw new IllegalStateException();
-		if(!isPossibleConnectionFilename(f.getName())) return;
-		if(f.length() < TransportConstants.MIN_CONNECTION_LENGTH) return;
-		try {
-			FileInputStream in = new FileInputStream(f);
-			byte[] iv = new byte[TransportConstants.IV_LENGTH];
-			int offset = 0;
-			while(offset < iv.length) {
-				int read = in.read(iv, offset, iv.length - offset);
-				if(read == -1) break;
-				offset += read;
-			}
-			if(offset < iv.length) {
-				// The file was truncated
-				in.close();
-				return;
-			}
-			ContactId c = recogniser.acceptConnection(iv);
-			if(c == null) {
-				// Nobody there
-				in.close();
-				return;
-			}
-			FileTransportReader reader = new FileTransportReader(f, in);
-			callback.readerCreated(c, iv, reader);
-		} catch(DbException e) {
-			// FIXME: At least log it
-			return;
-		} catch(IOException e) {
-			// FIXME: At least log it
-			return;
-		}
+		executor.execute(new ReaderCreator(f));
 	}
 
 	protected boolean isPossibleConnectionFilename(String filename) {
 		return filename.toLowerCase().matches("[a-z]{8}\\.dat");
 	}
+
+	private class ReaderCreator implements Runnable {
+
+		private final File f;
+
+		private ReaderCreator(File f) {
+			this.f = f;
+		}
+
+		public void run() {
+			if(!isPossibleConnectionFilename(f.getName())) return;
+			if(f.length() < TransportConstants.MIN_CONNECTION_LENGTH) return;
+			try {
+				FileInputStream in = new FileInputStream(f);
+				byte[] iv = new byte[TransportConstants.IV_LENGTH];
+				int offset = 0;
+				while(offset < iv.length) {
+					int read = in.read(iv, offset, iv.length - offset);
+					if(read == -1) break;
+					offset += read;
+				}
+				if(offset < iv.length) {
+					// The file was truncated
+					in.close();
+					return;
+				}
+				ContactId c = recogniser.acceptConnection(iv);
+				if(c == null) {
+					// Nobody there
+					in.close();
+					return;
+				}
+				FileTransportReader reader = new FileTransportReader(f, in);
+				callback.readerCreated(c, iv, reader);
+			} catch(DbException e) {
+				// FIXME: At least log it
+				return;
+			} catch(IOException e) {
+				// FIXME: At least log it
+				return;
+			}
+		}
+	}
 }
diff --git a/components/net/sf/briar/plugins/file/RemovableDrivePlugin.java b/components/net/sf/briar/plugins/file/RemovableDrivePlugin.java
index bd959c219c598befbd268e110e3152c0b1440141..29041633eb2e5174b6a714adca1d9733e28518ed 100644
--- a/components/net/sf/briar/plugins/file/RemovableDrivePlugin.java
+++ b/components/net/sf/briar/plugins/file/RemovableDrivePlugin.java
@@ -4,6 +4,7 @@ import java.io.File;
 import java.io.IOException;
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.Executor;
 
 import net.sf.briar.api.ContactId;
 import net.sf.briar.api.TransportId;
@@ -22,9 +23,9 @@ implements RemovableDriveMonitor.Callback {
 	private final RemovableDriveFinder finder;
 	private final RemovableDriveMonitor monitor;
 
-	RemovableDrivePlugin(ConnectionRecogniser recogniser,
+	RemovableDrivePlugin(ConnectionRecogniser recogniser, Executor executor,
 			RemovableDriveFinder finder, RemovableDriveMonitor monitor) {
-		super(recogniser);
+		super(recogniser, executor);
 		this.finder = finder;
 		this.monitor = monitor;
 	}
diff --git a/test/net/sf/briar/plugins/file/RemovableDrivePluginTest.java b/test/net/sf/briar/plugins/file/RemovableDrivePluginTest.java
index 625a7de03354634a9ad391d59985d1eda119e3a3..0792589ccfdf31151e21bb2715eca271058d05a5 100644
--- a/test/net/sf/briar/plugins/file/RemovableDrivePluginTest.java
+++ b/test/net/sf/briar/plugins/file/RemovableDrivePluginTest.java
@@ -6,6 +6,7 @@ import java.io.OutputStream;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
+import java.util.concurrent.Executor;
 
 import junit.framework.TestCase;
 import net.sf.briar.TestUtils;
@@ -36,6 +37,7 @@ public class RemovableDrivePluginTest extends TestCase {
 	@Test
 	public void testGetId() {
 		Mockery context = new Mockery();
+		final Executor executor = context.mock(Executor.class);
 		final ConnectionRecogniser recogniser =
 			context.mock(ConnectionRecogniser.class);
 		final RemovableDriveFinder finder =
@@ -44,7 +46,7 @@ public class RemovableDrivePluginTest extends TestCase {
 			context.mock(RemovableDriveMonitor.class);
 
 		RemovableDrivePlugin plugin = new RemovableDrivePlugin(recogniser,
-				finder, monitor);
+				executor, finder, monitor);
 
 		assertEquals(RemovableDrivePlugin.TRANSPORT_ID,
 				plugin.getId().getInt());
@@ -57,6 +59,7 @@ public class RemovableDrivePluginTest extends TestCase {
 		final List<File> drives = Collections.emptyList();
 
 		Mockery context = new Mockery();
+		final Executor executor = context.mock(Executor.class);
 		final ConnectionRecogniser recogniser =
 			context.mock(ConnectionRecogniser.class);
 		final RemovableDriveFinder finder =
@@ -73,7 +76,7 @@ public class RemovableDrivePluginTest extends TestCase {
 		}});
 
 		RemovableDrivePlugin plugin = new RemovableDrivePlugin(recogniser,
-				finder, monitor);
+				executor, finder, monitor);
 		plugin.start(null, null, null, callback);
 
 		assertNull(plugin.createWriter(contactId));
@@ -90,6 +93,7 @@ public class RemovableDrivePluginTest extends TestCase {
 		drives.add(drive2);
 
 		Mockery context = new Mockery();
+		final Executor executor = context.mock(Executor.class);
 		final ConnectionRecogniser recogniser =
 			context.mock(ConnectionRecogniser.class);
 		final RemovableDriveFinder finder =
@@ -109,7 +113,7 @@ public class RemovableDrivePluginTest extends TestCase {
 		}});
 
 		RemovableDrivePlugin plugin = new RemovableDrivePlugin(recogniser,
-				finder, monitor);
+				executor, finder, monitor);
 		plugin.start(null, null, null, callback);
 
 		assertNull(plugin.createWriter(contactId));
@@ -128,6 +132,7 @@ public class RemovableDrivePluginTest extends TestCase {
 		drives.add(drive2);
 
 		Mockery context = new Mockery();
+		final Executor executor = context.mock(Executor.class);
 		final ConnectionRecogniser recogniser =
 			context.mock(ConnectionRecogniser.class);
 		final RemovableDriveFinder finder =
@@ -147,7 +152,7 @@ public class RemovableDrivePluginTest extends TestCase {
 		}});
 
 		RemovableDrivePlugin plugin = new RemovableDrivePlugin(recogniser,
-				finder, monitor);
+				executor, finder, monitor);
 		plugin.start(null, null, null, callback);
 
 		assertNull(plugin.createWriter(contactId));
@@ -168,6 +173,7 @@ public class RemovableDrivePluginTest extends TestCase {
 		assertTrue(drive1.createNewFile());
 
 		Mockery context = new Mockery();
+		final Executor executor = context.mock(Executor.class);
 		final ConnectionRecogniser recogniser =
 			context.mock(ConnectionRecogniser.class);
 		final RemovableDriveFinder finder =
@@ -187,7 +193,7 @@ public class RemovableDrivePluginTest extends TestCase {
 		}});
 
 		RemovableDrivePlugin plugin = new RemovableDrivePlugin(recogniser,
-				finder, monitor);
+				executor, finder, monitor);
 		plugin.start(null, null, null, callback);
 
 		assertNull(plugin.createWriter(contactId));
@@ -208,6 +214,7 @@ public class RemovableDrivePluginTest extends TestCase {
 		assertTrue(drive1.mkdir());
 
 		Mockery context = new Mockery();
+		final Executor executor = context.mock(Executor.class);
 		final ConnectionRecogniser recogniser =
 			context.mock(ConnectionRecogniser.class);
 		final RemovableDriveFinder finder =
@@ -227,7 +234,7 @@ public class RemovableDrivePluginTest extends TestCase {
 		}});
 
 		RemovableDrivePlugin plugin = new RemovableDrivePlugin(recogniser,
-				finder, monitor);
+				executor, finder, monitor);
 		plugin.start(null, null, null, callback);
 
 		assertNotNull(plugin.createWriter(contactId));
@@ -251,6 +258,7 @@ public class RemovableDrivePluginTest extends TestCase {
 		assertTrue(drive1.mkdir());
 
 		Mockery context = new Mockery();
+		final Executor executor = context.mock(Executor.class);
 		final ConnectionRecogniser recogniser =
 			context.mock(ConnectionRecogniser.class);
 		final RemovableDriveFinder finder =
@@ -271,7 +279,7 @@ public class RemovableDrivePluginTest extends TestCase {
 		}});
 
 		RemovableDrivePlugin plugin = new RemovableDrivePlugin(recogniser,
-				finder, monitor);
+				executor, finder, monitor);
 		plugin.start(null, null, null, callback);
 
 		BatchTransportWriter writer = plugin.createWriter(contactId);
@@ -299,6 +307,7 @@ public class RemovableDrivePluginTest extends TestCase {
 	@Test
 	public void testEmptyDriveIsIgnored() throws Exception {
 		Mockery context = new Mockery();
+		final Executor executor = context.mock(Executor.class);
 		final ConnectionRecogniser recogniser =
 			context.mock(ConnectionRecogniser.class);
 		final RemovableDriveFinder finder =
@@ -313,7 +322,7 @@ public class RemovableDrivePluginTest extends TestCase {
 		}});
 
 		RemovableDrivePlugin plugin = new RemovableDrivePlugin(recogniser,
-				finder, monitor);
+				executor, finder, monitor);
 		plugin.start(null, null, null, callback);
 
 		plugin.driveInserted(testDir);
@@ -324,6 +333,7 @@ public class RemovableDrivePluginTest extends TestCase {
 	@Test
 	public void testFilenames() {
 		Mockery context = new Mockery();
+		final Executor executor = context.mock(Executor.class);
 		final ConnectionRecogniser recogniser =
 			context.mock(ConnectionRecogniser.class);
 		final RemovableDriveFinder finder =
@@ -332,7 +342,7 @@ public class RemovableDrivePluginTest extends TestCase {
 			context.mock(RemovableDriveMonitor.class);
 
 		RemovableDrivePlugin plugin = new RemovableDrivePlugin(recogniser,
-				finder, monitor);
+				executor, finder, monitor);
 
 		assertFalse(plugin.isPossibleConnectionFilename("abcdefg.dat"));
 		assertFalse(plugin.isPossibleConnectionFilename("abcdefghi.dat"));
@@ -361,7 +371,7 @@ public class RemovableDrivePluginTest extends TestCase {
 		}});
 
 		RemovableDrivePlugin plugin = new RemovableDrivePlugin(recogniser,
-				finder, monitor);
+				new ImmediateExecutor(), finder, monitor);
 		plugin.start(null, null, null, callback);
 
 		File f = new File(testDir, "abcdefgh.dat");
@@ -394,7 +404,7 @@ public class RemovableDrivePluginTest extends TestCase {
 		}});
 
 		RemovableDrivePlugin plugin = new RemovableDrivePlugin(recogniser,
-				finder, monitor);
+				new ImmediateExecutor(), finder, monitor);
 		plugin.start(null, null, null, callback);
 
 		File f = new File(testDir, "abcdefgh.dat");
@@ -430,7 +440,7 @@ public class RemovableDrivePluginTest extends TestCase {
 		}});
 
 		RemovableDrivePlugin plugin = new RemovableDrivePlugin(recogniser,
-				finder, monitor);
+				new ImmediateExecutor(), finder, monitor);
 		plugin.start(null, null, null, callback);
 
 		File f = new File(testDir, "abcdefgh.dat");
@@ -448,4 +458,11 @@ public class RemovableDrivePluginTest extends TestCase {
 	public void tearDown() {
 		TestUtils.deleteTestDirectory(testDir);
 	}
+
+	private static class ImmediateExecutor implements Executor {
+
+		public void execute(Runnable r) {
+			r.run();
+		}
+	}
 }