diff --git a/briar-api/src/org/briarproject/api/messaging/MessagingSessionFactory.java b/briar-api/src/org/briarproject/api/messaging/MessagingSessionFactory.java
index a014fe92f9d6d34149dbac84504ef31c7ad46248..24f74f04406d00ad217ad4eb1d7c45ec6c36c5fa 100644
--- a/briar-api/src/org/briarproject/api/messaging/MessagingSessionFactory.java
+++ b/briar-api/src/org/briarproject/api/messaging/MessagingSessionFactory.java
@@ -1,14 +1,15 @@
 package org.briarproject.api.messaging;
 
-import org.briarproject.api.plugins.TransportConnectionReader;
-import org.briarproject.api.plugins.TransportConnectionWriter;
-import org.briarproject.api.transport.StreamContext;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.briarproject.api.ContactId;
+import org.briarproject.api.TransportId;
 
 public interface MessagingSessionFactory {
 
-	MessagingSession createIncomingSession(StreamContext ctx,
-			TransportConnectionReader r);
+	MessagingSession createIncomingSession(ContactId c, InputStream in);
 
-	MessagingSession createOutgoingSession(StreamContext ctx,
-			TransportConnectionWriter w, boolean duplex);
+	MessagingSession createOutgoingSession(ContactId c, TransportId t,
+			long maxLatency, OutputStream out, boolean duplex);
 }
diff --git a/briar-core/src/org/briarproject/messaging/IncomingSession.java b/briar-core/src/org/briarproject/messaging/IncomingSession.java
index 37547d3cd9ce774fa16b0dd19a0dba4f26b1fd70..ee427b9a750bcf27e59cb60c42d088aa2037adc4 100644
--- a/briar-core/src/org/briarproject/messaging/IncomingSession.java
+++ b/briar-core/src/org/briarproject/messaging/IncomingSession.java
@@ -25,10 +25,6 @@ import org.briarproject.api.messaging.SubscriptionUpdate;
 import org.briarproject.api.messaging.TransportAck;
 import org.briarproject.api.messaging.TransportUpdate;
 import org.briarproject.api.messaging.UnverifiedMessage;
-import org.briarproject.api.plugins.TransportConnectionReader;
-import org.briarproject.api.transport.StreamContext;
-import org.briarproject.api.transport.StreamReader;
-import org.briarproject.api.transport.StreamReaderFactory;
 
 /**
  * An incoming {@link org.briarproject.api.messaging.MessagingSession
@@ -42,36 +38,26 @@ class IncomingSession implements MessagingSession {
 	private final DatabaseComponent db;
 	private final Executor dbExecutor, cryptoExecutor;
 	private final MessageVerifier messageVerifier;
-	private final StreamReaderFactory streamReaderFactory;
 	private final PacketReaderFactory packetReaderFactory;
-	private final StreamContext ctx;
-	private final TransportConnectionReader transportReader;
 	private final ContactId contactId;
+	private final InputStream in;
 
 	private volatile boolean interrupted = false;
 
 	IncomingSession(DatabaseComponent db, Executor dbExecutor,
 			Executor cryptoExecutor, MessageVerifier messageVerifier,
-			StreamReaderFactory streamReaderFactory,
-			PacketReaderFactory packetReaderFactory, StreamContext ctx,
-			TransportConnectionReader transportReader) {
+			PacketReaderFactory packetReaderFactory, ContactId contactId,
+			InputStream in) {
 		this.db = db;
 		this.dbExecutor = dbExecutor;
 		this.cryptoExecutor = cryptoExecutor;
 		this.messageVerifier = messageVerifier;
-		this.streamReaderFactory = streamReaderFactory;
 		this.packetReaderFactory = packetReaderFactory;
-		this.ctx = ctx;
-		this.transportReader = transportReader;
-		contactId = ctx.getContactId();
+		this.contactId = contactId;
+		this.in = in;
 	}
 
 	public void run() throws IOException {
-		InputStream in = transportReader.getInputStream();
-		int maxFrameLength = transportReader.getMaxFrameLength();
-		StreamReader streamReader = streamReaderFactory.createStreamReader(in,
-				maxFrameLength, ctx);
-		in = streamReader.getInputStream();
 		PacketReader packetReader = packetReaderFactory.createPacketReader(in);
 		// Read packets until interrupted or EOF
 		while(!interrupted && !packetReader.eof()) {
diff --git a/briar-core/src/org/briarproject/messaging/MessagingSessionFactoryImpl.java b/briar-core/src/org/briarproject/messaging/MessagingSessionFactoryImpl.java
index f8b3792a41af7bd8dae2b530a15cd832090146b4..20813c27d4aec3ade5150825027b589ab9af235f 100644
--- a/briar-core/src/org/briarproject/messaging/MessagingSessionFactoryImpl.java
+++ b/briar-core/src/org/briarproject/messaging/MessagingSessionFactoryImpl.java
@@ -1,23 +1,22 @@
 package org.briarproject.messaging;
 
+import java.io.InputStream;
+import java.io.OutputStream;
 import java.util.concurrent.Executor;
 
 import javax.inject.Inject;
 
+import org.briarproject.api.ContactId;
+import org.briarproject.api.TransportId;
 import org.briarproject.api.crypto.CryptoExecutor;
 import org.briarproject.api.db.DatabaseComponent;
 import org.briarproject.api.db.DatabaseExecutor;
 import org.briarproject.api.event.EventBus;
 import org.briarproject.api.messaging.MessageVerifier;
 import org.briarproject.api.messaging.MessagingSession;
+import org.briarproject.api.messaging.MessagingSessionFactory;
 import org.briarproject.api.messaging.PacketReaderFactory;
 import org.briarproject.api.messaging.PacketWriterFactory;
-import org.briarproject.api.messaging.MessagingSessionFactory;
-import org.briarproject.api.plugins.TransportConnectionReader;
-import org.briarproject.api.plugins.TransportConnectionWriter;
-import org.briarproject.api.transport.StreamContext;
-import org.briarproject.api.transport.StreamReaderFactory;
-import org.briarproject.api.transport.StreamWriterFactory;
 
 class MessagingSessionFactoryImpl implements MessagingSessionFactory {
 
@@ -25,8 +24,6 @@ class MessagingSessionFactoryImpl implements MessagingSessionFactory {
 	private final Executor dbExecutor, cryptoExecutor;
 	private final MessageVerifier messageVerifier;
 	private final EventBus eventBus;
-	private final StreamReaderFactory streamReaderFactory;
-	private final StreamWriterFactory streamWriterFactory;
 	private final PacketReaderFactory packetReaderFactory;
 	private final PacketWriterFactory packetWriterFactory;
 
@@ -35,8 +32,6 @@ class MessagingSessionFactoryImpl implements MessagingSessionFactory {
 			@DatabaseExecutor Executor dbExecutor,
 			@CryptoExecutor Executor cryptoExecutor,
 			MessageVerifier messageVerifier, EventBus eventBus,
-			StreamReaderFactory streamReaderFactory,
-			StreamWriterFactory streamWriterFactory,
 			PacketReaderFactory packetReaderFactory,
 			PacketWriterFactory packetWriterFactory) {
 		this.db = db;
@@ -44,24 +39,20 @@ class MessagingSessionFactoryImpl implements MessagingSessionFactory {
 		this.cryptoExecutor = cryptoExecutor;
 		this.messageVerifier = messageVerifier;
 		this.eventBus = eventBus;
-		this.streamReaderFactory = streamReaderFactory;
-		this.streamWriterFactory = streamWriterFactory;
 		this.packetReaderFactory = packetReaderFactory;
 		this.packetWriterFactory = packetWriterFactory;
 	}
 
-	public MessagingSession createIncomingSession(StreamContext ctx,
-			TransportConnectionReader r) {
+	public MessagingSession createIncomingSession(ContactId c, InputStream in) {
 		return new IncomingSession(db, dbExecutor, cryptoExecutor,
-				messageVerifier, streamReaderFactory, packetReaderFactory,
-				ctx, r);
+				messageVerifier, packetReaderFactory, c, in);
 	}
 
-	public MessagingSession createOutgoingSession(StreamContext ctx,
-			TransportConnectionWriter w, boolean duplex) {
+	public MessagingSession createOutgoingSession(ContactId c, TransportId t,
+			long maxLatency, OutputStream out, boolean duplex) {
 		if(duplex) return new ReactiveOutgoingSession(db, dbExecutor, eventBus,
-				streamWriterFactory, packetWriterFactory, ctx, w);
+				packetWriterFactory, c, t, maxLatency, out);
 		else return new SinglePassOutgoingSession(db, dbExecutor,
-				streamWriterFactory, packetWriterFactory, ctx, w);
+				packetWriterFactory, c, maxLatency, out);
 	}
 }
diff --git a/briar-core/src/org/briarproject/messaging/ReactiveOutgoingSession.java b/briar-core/src/org/briarproject/messaging/ReactiveOutgoingSession.java
index caf87129ffb080eac63086a8a86d2af1e44b7907..9f233275a119b81ecd7fd106bd847edc24249407 100644
--- a/briar-core/src/org/briarproject/messaging/ReactiveOutgoingSession.java
+++ b/briar-core/src/org/briarproject/messaging/ReactiveOutgoingSession.java
@@ -13,6 +13,7 @@ import java.util.concurrent.LinkedBlockingQueue;
 import java.util.logging.Logger;
 
 import org.briarproject.api.ContactId;
+import org.briarproject.api.TransportId;
 import org.briarproject.api.db.DatabaseComponent;
 import org.briarproject.api.db.DbException;
 import org.briarproject.api.event.ContactRemovedEvent;
@@ -42,10 +43,6 @@ import org.briarproject.api.messaging.SubscriptionAck;
 import org.briarproject.api.messaging.SubscriptionUpdate;
 import org.briarproject.api.messaging.TransportAck;
 import org.briarproject.api.messaging.TransportUpdate;
-import org.briarproject.api.plugins.TransportConnectionWriter;
-import org.briarproject.api.transport.StreamContext;
-import org.briarproject.api.transport.StreamWriter;
-import org.briarproject.api.transport.StreamWriterFactory;
 
 /**
  * An outgoing {@link org.briarproject.api.messaging.MessagingSession
@@ -65,41 +62,34 @@ class ReactiveOutgoingSession implements MessagingSession, EventListener {
 	private final DatabaseComponent db;
 	private final Executor dbExecutor;
 	private final EventBus eventBus;
-	private final StreamWriterFactory streamWriterFactory;
 	private final PacketWriterFactory packetWriterFactory;
-	private final StreamContext ctx;
-	private final TransportConnectionWriter transportWriter;
 	private final ContactId contactId;
+	private final TransportId transportId;
 	private final long maxLatency;
+	private final OutputStream out;
 	private final BlockingQueue<ThrowingRunnable<IOException>> writerTasks;
 
 	private volatile PacketWriter packetWriter = null;
 	private volatile boolean interrupted = false;
 
 	ReactiveOutgoingSession(DatabaseComponent db, Executor dbExecutor,
-			EventBus eventBus, StreamWriterFactory streamWriterFactory,
-			PacketWriterFactory packetWriterFactory, StreamContext ctx,
-			TransportConnectionWriter transportWriter) {
+			EventBus eventBus, PacketWriterFactory packetWriterFactory,
+			ContactId contactId, TransportId transportId, long maxLatency,
+			OutputStream out) {
 		this.db = db;
 		this.dbExecutor = dbExecutor;
 		this.eventBus = eventBus;
-		this.streamWriterFactory = streamWriterFactory;
 		this.packetWriterFactory = packetWriterFactory;
-		this.ctx = ctx;
-		this.transportWriter = transportWriter;
-		contactId = ctx.getContactId();
-		maxLatency = transportWriter.getMaxLatency();
+		this.contactId = contactId;
+		this.transportId = transportId;
+		this.maxLatency = maxLatency;
+		this.out = out;
 		writerTasks = new LinkedBlockingQueue<ThrowingRunnable<IOException>>();
 	}
 
 	public void run() throws IOException {
 		eventBus.addListener(this);
 		try {
-			OutputStream out = transportWriter.getOutputStream();
-			int maxFrameLength = transportWriter.getMaxFrameLength();
-			StreamWriter streamWriter = streamWriterFactory.createStreamWriter(
-					out, maxFrameLength, ctx);
-			out = streamWriter.getOutputStream();
 			packetWriter = packetWriterFactory.createPacketWriter(out);
 			// Start a query for each type of packet, in order of urgency
 			dbExecutor.execute(new GenerateTransportAcks());
@@ -183,7 +173,7 @@ class ReactiveOutgoingSession implements MessagingSession, EventListener {
 				dbExecutor.execute(new GenerateTransportAcks());
 		} else if(e instanceof TransportRemovedEvent) {
 			TransportRemovedEvent t = (TransportRemovedEvent) e;
-			if(ctx.getTransportId().equals(t.getTransportId())) {
+			if(t.getTransportId().equals(transportId)) {
 				LOG.info("Transport removed, closing");
 				interrupt();
 			}
diff --git a/briar-core/src/org/briarproject/messaging/SinglePassOutgoingSession.java b/briar-core/src/org/briarproject/messaging/SinglePassOutgoingSession.java
index f4c3195ae93145f4ca8b79193805aed0c52e7eda..c0b5bba59a53055597ab6515f7f876adfbf40fb1 100644
--- a/briar-core/src/org/briarproject/messaging/SinglePassOutgoingSession.java
+++ b/briar-core/src/org/briarproject/messaging/SinglePassOutgoingSession.java
@@ -26,10 +26,6 @@ import org.briarproject.api.messaging.SubscriptionAck;
 import org.briarproject.api.messaging.SubscriptionUpdate;
 import org.briarproject.api.messaging.TransportAck;
 import org.briarproject.api.messaging.TransportUpdate;
-import org.briarproject.api.plugins.TransportConnectionWriter;
-import org.briarproject.api.transport.StreamContext;
-import org.briarproject.api.transport.StreamWriter;
-import org.briarproject.api.transport.StreamWriterFactory;
 
 /**
  * An outgoing {@link org.briarproject.api.messaging.MessagingSession
@@ -48,41 +44,30 @@ class SinglePassOutgoingSession implements MessagingSession {
 
 	private final DatabaseComponent db;
 	private final Executor dbExecutor;
-	private final StreamWriterFactory streamWriterFactory;
 	private final PacketWriterFactory packetWriterFactory;
-	private final StreamContext ctx;
-	private final TransportConnectionWriter transportWriter;
 	private final ContactId contactId;
 	private final long maxLatency;
+	private final OutputStream out;
 	private final AtomicInteger outstandingQueries;
 	private final BlockingQueue<ThrowingRunnable<IOException>> writerTasks;
 
-	private volatile StreamWriter streamWriter = null;
 	private volatile PacketWriter packetWriter = null;
 	private volatile boolean interrupted = false;
 
 	SinglePassOutgoingSession(DatabaseComponent db, Executor dbExecutor,
-			StreamWriterFactory streamWriterFactory,
-			PacketWriterFactory packetWriterFactory, StreamContext ctx,
-			TransportConnectionWriter transportWriter) {
+			PacketWriterFactory packetWriterFactory, ContactId contactId,
+			long maxLatency, OutputStream out) {
 		this.db = db;
 		this.dbExecutor = dbExecutor;
-		this.streamWriterFactory = streamWriterFactory;
 		this.packetWriterFactory = packetWriterFactory;
-		this.ctx = ctx;
-		this.transportWriter = transportWriter;
-		contactId = ctx.getContactId();
-		maxLatency = transportWriter.getMaxLatency();
+		this.contactId = contactId;
+		this.maxLatency = maxLatency;
+		this.out = out;
 		outstandingQueries = new AtomicInteger(8); // One per type of packet
 		writerTasks = new LinkedBlockingQueue<ThrowingRunnable<IOException>>();
 	}
 
 	public void run() throws IOException {
-		OutputStream out = transportWriter.getOutputStream();
-		int maxFrameLength = transportWriter.getMaxFrameLength();
-		streamWriter = streamWriterFactory.createStreamWriter(out,
-				maxFrameLength, ctx);
-		out = streamWriter.getOutputStream();
 		packetWriter = packetWriterFactory.createPacketWriter(out);
 		// Start a query for each type of packet, in order of urgency
 		dbExecutor.execute(new GenerateTransportAcks());
diff --git a/briar-core/src/org/briarproject/transport/ConnectionDispatcherImpl.java b/briar-core/src/org/briarproject/transport/ConnectionDispatcherImpl.java
index 63f0503f6dcbbdc975a549fd6aaadd8a090801e7..bd073e7275104384f8f6a5c3b929271a867bc2f6 100644
--- a/briar-core/src/org/briarproject/transport/ConnectionDispatcherImpl.java
+++ b/briar-core/src/org/briarproject/transport/ConnectionDispatcherImpl.java
@@ -6,6 +6,7 @@ import static org.briarproject.api.transport.TransportConstants.TAG_LENGTH;
 import java.io.EOFException;
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.OutputStream;
 import java.util.concurrent.Executor;
 import java.util.logging.Logger;
 
@@ -24,6 +25,10 @@ import org.briarproject.api.plugins.duplex.DuplexTransportConnection;
 import org.briarproject.api.transport.ConnectionDispatcher;
 import org.briarproject.api.transport.ConnectionRegistry;
 import org.briarproject.api.transport.StreamContext;
+import org.briarproject.api.transport.StreamReader;
+import org.briarproject.api.transport.StreamReaderFactory;
+import org.briarproject.api.transport.StreamWriter;
+import org.briarproject.api.transport.StreamWriterFactory;
 import org.briarproject.api.transport.TagRecogniser;
 
 class ConnectionDispatcherImpl implements ConnectionDispatcher {
@@ -34,17 +39,23 @@ class ConnectionDispatcherImpl implements ConnectionDispatcher {
 	private final Executor ioExecutor;
 	private final KeyManager keyManager;
 	private final TagRecogniser tagRecogniser;
+	private final StreamReaderFactory streamReaderFactory;
+	private final StreamWriterFactory streamWriterFactory;
 	private final MessagingSessionFactory messagingSessionFactory;
 	private final ConnectionRegistry connectionRegistry;
 
 	@Inject
 	ConnectionDispatcherImpl(@IoExecutor Executor ioExecutor,
 			KeyManager keyManager, TagRecogniser tagRecogniser,
+			StreamReaderFactory streamReaderFactory,
+			StreamWriterFactory streamWriterFactory,
 			MessagingSessionFactory messagingSessionFactory,
 			ConnectionRegistry connectionRegistry) {
 		this.ioExecutor = ioExecutor;
 		this.keyManager = keyManager;
 		this.tagRecogniser = tagRecogniser;
+		this.streamReaderFactory = streamReaderFactory;
+		this.streamWriterFactory = streamWriterFactory;
 		this.messagingSessionFactory = messagingSessionFactory;
 		this.connectionRegistry = connectionRegistry;
 	}
@@ -83,6 +94,25 @@ class ConnectionDispatcherImpl implements ConnectionDispatcher {
 		return tag;
 	}
 
+	private MessagingSession createIncomingSession(StreamContext ctx,
+			TransportConnectionReader r) throws IOException {
+		InputStream in = r.getInputStream();
+		StreamReader streamReader = streamReaderFactory.createStreamReader(in,
+				r.getMaxFrameLength(), ctx);
+		return messagingSessionFactory.createIncomingSession(ctx.getContactId(),
+				streamReader.getInputStream());
+	}
+
+	private MessagingSession createOutgoingSession(StreamContext ctx,
+			TransportConnectionWriter w, boolean duplex) throws IOException {
+		OutputStream out = w.getOutputStream();
+		StreamWriter streamWriter = streamWriterFactory.createStreamWriter(out,
+				w.getMaxFrameLength(), ctx);
+		return messagingSessionFactory.createOutgoingSession(ctx.getContactId(),
+				ctx.getTransportId(), w.getMaxLatency(),
+				streamWriter.getOutputStream(), duplex);
+	}
+
 	private class DispatchIncomingSimplexConnection implements Runnable {
 
 		private final TransportId transportId;
@@ -116,11 +146,9 @@ class ConnectionDispatcherImpl implements ConnectionDispatcher {
 			}
 			ContactId contactId = ctx.getContactId();
 			connectionRegistry.registerConnection(contactId, transportId);
-			// Run the incoming session
-			MessagingSession incomingSession =
-					messagingSessionFactory.createIncomingSession(ctx, reader);
 			try {
-				incomingSession.run();
+				// Create and run the incoming session
+				createIncomingSession(ctx, reader).run();
 				disposeReader(false, true);
 			} catch(IOException e) {
 				if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
@@ -162,12 +190,9 @@ class ConnectionDispatcherImpl implements ConnectionDispatcher {
 				return;
 			}
 			connectionRegistry.registerConnection(contactId, transportId);
-			// Run the outgoing session
-			MessagingSession outgoingSession =
-					messagingSessionFactory.createOutgoingSession(ctx,
-							writer, false);
 			try {
-				outgoingSession.run();
+				// Create and run the outgoing session
+				createOutgoingSession(ctx, writer, false).run();
 				disposeWriter(false);
 			} catch(IOException e) {
 				if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
@@ -231,10 +256,9 @@ class ConnectionDispatcherImpl implements ConnectionDispatcher {
 					runOutgoingSession();
 				}
 			});
-			// Run the incoming session
-			incomingSession = messagingSessionFactory.createIncomingSession(ctx,
-					reader);
 			try {
+				// Create and run the incoming session
+				incomingSession = createIncomingSession(ctx, reader);
 				incomingSession.run();
 				disposeReader(false, true);
 			} catch(IOException e) {
@@ -254,10 +278,9 @@ class ConnectionDispatcherImpl implements ConnectionDispatcher {
 				disposeWriter(true);
 				return;
 			}
-			// Run the outgoing session
-			outgoingSession = messagingSessionFactory.createOutgoingSession(ctx,
-					writer, true);
 			try {
+				// Create and run the outgoing session
+				outgoingSession = createOutgoingSession(ctx, writer, true);
 				outgoingSession.run();
 				disposeWriter(false);
 			} catch(IOException e) {
@@ -321,10 +344,9 @@ class ConnectionDispatcherImpl implements ConnectionDispatcher {
 					runIncomingSession();
 				}
 			});
-			// Run the outgoing session
-			outgoingSession = messagingSessionFactory.createOutgoingSession(ctx,
-					writer, true);
 			try {
+				// Create and run the outgoing session
+				outgoingSession = createOutgoingSession(ctx, writer, true);
 				outgoingSession.run();
 				disposeWriter(false);
 			} catch(IOException e) {
@@ -362,10 +384,9 @@ class ConnectionDispatcherImpl implements ConnectionDispatcher {
 				disposeReader(true, true);
 				return;
 			}
-			// Run the incoming session
-			incomingSession = messagingSessionFactory.createIncomingSession(ctx,
-					reader);
 			try {
+				// Create and run the incoming session
+				incomingSession = createIncomingSession(ctx, reader);
 				incomingSession.run();
 				disposeReader(false, true);
 			} catch(IOException e) {
diff --git a/briar-tests/src/org/briarproject/messaging/SimplexMessagingIntegrationTest.java b/briar-tests/src/org/briarproject/messaging/SimplexMessagingIntegrationTest.java
index 834eba129f1fab9435a762b584749e9652ebc475..e89d86edde01769db08470ae2139e3ef4799a64a 100644
--- a/briar-tests/src/org/briarproject/messaging/SimplexMessagingIntegrationTest.java
+++ b/briar-tests/src/org/briarproject/messaging/SimplexMessagingIntegrationTest.java
@@ -2,6 +2,7 @@ package org.briarproject.messaging;
 
 import static org.briarproject.api.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
 import static org.briarproject.api.messaging.MessagingConstants.GROUP_SALT_LENGTH;
+import static org.briarproject.api.transport.TransportConstants.MAX_FRAME_LENGTH;
 import static org.briarproject.api.transport.TransportConstants.TAG_LENGTH;
 
 import java.io.ByteArrayInputStream;
@@ -35,7 +36,9 @@ import org.briarproject.api.messaging.PacketReaderFactory;
 import org.briarproject.api.messaging.PacketWriterFactory;
 import org.briarproject.api.transport.Endpoint;
 import org.briarproject.api.transport.StreamContext;
+import org.briarproject.api.transport.StreamReader;
 import org.briarproject.api.transport.StreamReaderFactory;
+import org.briarproject.api.transport.StreamWriter;
 import org.briarproject.api.transport.StreamWriterFactory;
 import org.briarproject.api.transport.TagRecogniser;
 import org.briarproject.crypto.CryptoModule;
@@ -137,22 +140,22 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
 		Message message = messageFactory.createAnonymousMessage(null, group,
 				contentType, timestamp, body);
 		db.addLocalMessage(message);
-		// Create an outgoing messaging session
+		// Create a stream writer
 		ByteArrayOutputStream out = new ByteArrayOutputStream();
 		StreamWriterFactory streamWriterFactory =
 				alice.getInstance(StreamWriterFactory.class);
-		PacketWriterFactory packetWriterFactory =
-				alice.getInstance(PacketWriterFactory.class);
-		TestTransportConnectionWriter transport =
-				new TestTransportConnectionWriter(out);
 		StreamContext ctx = km.getStreamContext(contactId, transportId);
 		assertNotNull(ctx);
+		StreamWriter streamWriter = streamWriterFactory.createStreamWriter(out,
+				MAX_FRAME_LENGTH, ctx);
+		// Create an outgoing messaging session
+		PacketWriterFactory packetWriterFactory =
+				alice.getInstance(PacketWriterFactory.class);
 		MessagingSession session = new SinglePassOutgoingSession(db,
-				new ImmediateExecutor(), streamWriterFactory,
-				packetWriterFactory, ctx, transport);
+				new ImmediateExecutor(), packetWriterFactory, contactId,
+				Long.MAX_VALUE, streamWriter.getOutputStream());
 		// Write whatever needs to be written
 		session.run();
-		transport.dispose(false);
 		// Clean up
 		km.stop();
 		db.close();
@@ -198,24 +201,24 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
 		assertEquals(tag.length, read);
 		StreamContext ctx = rec.recogniseTag(transportId, tag);
 		assertNotNull(ctx);
+		// Create a stream reader
+		StreamReaderFactory streamReaderFactory =
+				bob.getInstance(StreamReaderFactory.class);
+		StreamReader streamReader = streamReaderFactory.createStreamReader(in,
+				MAX_FRAME_LENGTH, ctx);
 		// Create an incoming messaging session
 		MessageVerifier messageVerifier =
 				bob.getInstance(MessageVerifier.class);
-		StreamReaderFactory streamReaderFactory =
-				bob.getInstance(StreamReaderFactory.class);
 		PacketReaderFactory packetReaderFactory =
 				bob.getInstance(PacketReaderFactory.class);
-		TestTransportConnectionReader transport =
-				new TestTransportConnectionReader(in);
 		MessagingSession session = new IncomingSession(db,
 				new ImmediateExecutor(), new ImmediateExecutor(),
-				messageVerifier, streamReaderFactory, packetReaderFactory,
-				ctx, transport);
+				messageVerifier, packetReaderFactory, contactId,
+				streamReader.getInputStream());
 		// No messages should have been added yet
 		assertFalse(listener.messageAdded);
 		// Read whatever needs to be read
 		session.run();
-		transport.dispose(false, true);
 		// The private message from Alice should have been added
 		assertTrue(listener.messageAdded);
 		// Clean up
diff --git a/briar-tests/src/org/briarproject/messaging/SinglePassOutgoingSessionTest.java b/briar-tests/src/org/briarproject/messaging/SinglePassOutgoingSessionTest.java
index 27f03296f1439519023432c34bbaa5de448aeae3..80d0b2524bda11df58d22e27449921cbef952a32 100644
--- a/briar-tests/src/org/briarproject/messaging/SinglePassOutgoingSessionTest.java
+++ b/briar-tests/src/org/briarproject/messaging/SinglePassOutgoingSessionTest.java
@@ -1,9 +1,5 @@
 package org.briarproject.messaging;
 
-import static org.briarproject.api.transport.TransportConstants.HEADER_LENGTH;
-import static org.briarproject.api.transport.TransportConstants.MAC_LENGTH;
-import static org.briarproject.api.transport.TransportConstants.TAG_LENGTH;
-
 import java.io.ByteArrayOutputStream;
 import java.util.Arrays;
 import java.util.Random;
@@ -15,7 +11,6 @@ import org.briarproject.TestLifecycleModule;
 import org.briarproject.TestSystemModule;
 import org.briarproject.TestUtils;
 import org.briarproject.api.ContactId;
-import org.briarproject.api.TransportId;
 import org.briarproject.api.UniqueId;
 import org.briarproject.api.db.DatabaseComponent;
 import org.briarproject.api.db.DatabaseExecutor;
@@ -23,8 +18,6 @@ import org.briarproject.api.messaging.Ack;
 import org.briarproject.api.messaging.MessageId;
 import org.briarproject.api.messaging.MessagingSession;
 import org.briarproject.api.messaging.PacketWriterFactory;
-import org.briarproject.api.transport.StreamContext;
-import org.briarproject.api.transport.StreamWriterFactory;
 import org.briarproject.crypto.CryptoModule;
 import org.briarproject.event.EventModule;
 import org.briarproject.serial.SerialModule;
@@ -45,11 +38,9 @@ public class SinglePassOutgoingSessionTest extends BriarTestCase {
 	private final Mockery context;
 	private final DatabaseComponent db;
 	private final Executor dbExecutor;
-	private final StreamWriterFactory streamWriterFactory;
 	private final PacketWriterFactory packetWriterFactory;
 	private final ContactId contactId;
 	private final MessageId messageId;
-	private final TransportId transportId;
 	private final byte[] secret;
 
 	public SinglePassOutgoingSessionTest() {
@@ -68,11 +59,9 @@ public class SinglePassOutgoingSessionTest extends BriarTestCase {
 				new TestLifecycleModule(), new TestSystemModule(),
 				new CryptoModule(), new EventModule(), new MessagingModule(),
 				new SerialModule(), new TransportModule());
-		streamWriterFactory = i.getInstance(StreamWriterFactory.class);
 		packetWriterFactory = i.getInstance(PacketWriterFactory.class);
 		contactId = new ContactId(234);
 		messageId = new MessageId(TestUtils.getRandomId());
-		transportId = new TransportId("id");
 		secret = new byte[32];
 		new Random().nextBytes(secret);
 	}
@@ -80,12 +69,8 @@ public class SinglePassOutgoingSessionTest extends BriarTestCase {
 	@Test
 	public void testNothingToSend() throws Exception {
 		ByteArrayOutputStream out = new ByteArrayOutputStream();
-		TestTransportConnectionWriter writer =
-				new TestTransportConnectionWriter(out);
-		StreamContext ctx = new StreamContext(contactId, transportId,
-				secret, 0, true);
 		MessagingSession session = new SinglePassOutgoingSession(db, dbExecutor,
-				streamWriterFactory, packetWriterFactory, ctx, writer);
+				packetWriterFactory, contactId, Long.MAX_VALUE, out);
 		context.checking(new Expectations() {{
 			// No transport acks to send
 			oneOf(db).generateTransportAcks(contactId);
@@ -117,21 +102,16 @@ public class SinglePassOutgoingSessionTest extends BriarTestCase {
 			will(returnValue(null));
 		}});
 		session.run();
-		// Only the tag and an empty final frame should have been written
-		assertEquals(TAG_LENGTH + HEADER_LENGTH + MAC_LENGTH, out.size());
+		// Nothing should have been written
+		assertEquals(0, out.size());
 		context.assertIsSatisfied();
 	}
 
 	@Test
 	public void testSomethingToSend() throws Exception {
 		ByteArrayOutputStream out = new ByteArrayOutputStream();
-		TestTransportConnectionWriter writer =
-				new TestTransportConnectionWriter(out);
-		StreamContext ctx = new StreamContext(contactId, transportId,
-				secret, 0, true);
 		MessagingSession session = new SinglePassOutgoingSession(db, dbExecutor,
-				streamWriterFactory, packetWriterFactory,
-				ctx, writer);
+				packetWriterFactory, contactId, Long.MAX_VALUE, out);
 		final byte[] raw = new byte[1234];
 		context.checking(new Expectations() {{
 			// No transport acks to send
@@ -172,8 +152,7 @@ public class SinglePassOutgoingSessionTest extends BriarTestCase {
 		}});
 		session.run();
 		// Something should have been written
-		int overhead = TAG_LENGTH + HEADER_LENGTH + MAC_LENGTH;
-		assertTrue(out.size() > overhead + UniqueId.LENGTH + raw.length);
+		assertTrue(out.size() > UniqueId.LENGTH + raw.length);
 		context.assertIsSatisfied();
 	}
 }
diff --git a/briar-tests/src/org/briarproject/messaging/TestTransportConnectionReader.java b/briar-tests/src/org/briarproject/messaging/TestTransportConnectionReader.java
deleted file mode 100644
index 246c0920d0989eea47159c666e5fd897f2640bd3..0000000000000000000000000000000000000000
--- a/briar-tests/src/org/briarproject/messaging/TestTransportConnectionReader.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package org.briarproject.messaging;
-
-import static org.briarproject.api.transport.TransportConstants.MAX_FRAME_LENGTH;
-
-import java.io.InputStream;
-
-import org.briarproject.api.plugins.TransportConnectionReader;
-
-class TestTransportConnectionReader implements TransportConnectionReader {
-
-	private final InputStream in;
-
-	private boolean disposed = false;
-
-	TestTransportConnectionReader(InputStream in) {
-		this.in = in;
-	}
-
-	public int getMaxFrameLength() {
-		return MAX_FRAME_LENGTH;
-	}
-
-	public long getMaxLatency() {
-		return Long.MAX_VALUE;
-	}
-
-	public InputStream getInputStream() {
-		return in;
-	}
-
-	public void dispose(boolean exception, boolean recognised) {
-		assert !disposed;
-		disposed = true;
-	}
-}
\ No newline at end of file
diff --git a/briar-tests/src/org/briarproject/messaging/TestTransportConnectionWriter.java b/briar-tests/src/org/briarproject/messaging/TestTransportConnectionWriter.java
deleted file mode 100644
index ab4e4077ecee1e2a4c77dc5cb5ccfa6f91315d20..0000000000000000000000000000000000000000
--- a/briar-tests/src/org/briarproject/messaging/TestTransportConnectionWriter.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package org.briarproject.messaging;
-
-import static org.briarproject.api.transport.TransportConstants.MAX_FRAME_LENGTH;
-
-import java.io.ByteArrayOutputStream;
-import java.io.OutputStream;
-
-import org.briarproject.api.plugins.TransportConnectionWriter;
-
-class TestTransportConnectionWriter implements TransportConnectionWriter {
-
-	private final ByteArrayOutputStream out;
-
-	private boolean disposed = false;
-
-	TestTransportConnectionWriter(ByteArrayOutputStream out) {
-		this.out = out;
-	}
-
-	public long getCapacity() {
-		return Long.MAX_VALUE;
-	}
-
-	public int getMaxFrameLength() {
-		return MAX_FRAME_LENGTH;
-	}
-
-	public long getMaxLatency() {
-		return Long.MAX_VALUE;
-	}
-
-	public OutputStream getOutputStream() {
-		return out;
-	}
-
-	public void dispose(boolean exception) {
-		assert !disposed;
-		disposed = true;
-	}
-}
\ No newline at end of file