diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/mailbox/MailboxManager.java b/bramble-api/src/main/java/org/briarproject/bramble/api/mailbox/MailboxManager.java
index aa11967a63ac3a13c1f4e30acb226e6a82900248..14480c3f6eb44bff3c9e08053ccbc33a4d1acd12 100644
--- a/bramble-api/src/main/java/org/briarproject/bramble/api/mailbox/MailboxManager.java
+++ b/bramble-api/src/main/java/org/briarproject/bramble/api/mailbox/MailboxManager.java
@@ -7,26 +7,40 @@ import org.briarproject.bramble.api.plugin.TransportId;
 import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection;
 import org.briarproject.bramble.api.transport.StreamContext;
 
-public interface MailboxManager {
+import javax.annotation.Nullable;
 
+public interface MailboxManager {
+	/**
+	 * Connection to a contact's mailbox
+	 */
 	void handleOutgoingContactMailboxConnection(ContactId contactId,
-			DuplexTransportConnection connection, TransportId transportId);
+			ContactId mailboxId, DuplexTransportConnection connection,
+			TransportId transportId);
 
+	/**
+	 * Connection to private mailbox
+	 */
 	void handleOutgoingPrivateMailboxConnection(ContactId contactId,
 			DuplexTransportConnection connection, TransportId transportId);
 
 	/**
-	 *  Handle and incoming mailbox owner connection
-	 *  NOTE: Before calling the tag MUST be read from the stream!
-	 *  (Otherwise we wouldn't know that it's a MailboxOwner connection)
+	 * Connection from Owner to mailbox
 	 */
 	void handleIncomingMailboxOwnerConnection(StreamContext ctx,
 			TransportId transportId, TransportConnectionReader reader,
 			TransportConnectionWriter writer);
 
+	/**
+	 * Connection from contact (of owner) to mailbox
+	 */
 	void handleInomingOwnerContactConnection(StreamContext ctx,
 			TransportId transportId, TransportConnectionReader reader,
 			TransportConnectionWriter writer);
 
-	void handleOwnerContactWithoutMailbox(MailboxInfo mailboxInfo);
+	/**
+	 * Contacts without private mailbox which have been introduced
+	 * to private mailbox
+	 */
+	void handleContactWithoutMailbox(MailboxInfo mailboxInfo);
 }
+
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxManagerImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxManagerImpl.java
index 8c9c76223536826f12be5908d6ec1e32b23a612e..f5b3da2f693d19ec2f8d1ec470c92812d9193fa1 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxManagerImpl.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxManagerImpl.java
@@ -8,7 +8,6 @@ import org.briarproject.bramble.api.data.BdfWriter;
 import org.briarproject.bramble.api.data.BdfWriterFactory;
 import org.briarproject.bramble.api.db.DbException;
 import org.briarproject.bramble.api.lifecycle.IoExecutor;
-import org.briarproject.bramble.api.mailbox.MailboxConstants;
 import org.briarproject.bramble.api.mailbox.MailboxInfo;
 import org.briarproject.bramble.api.mailbox.MailboxManager;
 import org.briarproject.bramble.api.mailbox.MailboxSession;
@@ -31,12 +30,13 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.util.concurrent.Executor;
+import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.logging.Logger;
 
 import javax.inject.Inject;
 
-import static java.util.logging.Level.INFO;
 import static java.util.logging.Level.WARNING;
+import static org.briarproject.bramble.api.contact.ContactType.*;
 import static org.briarproject.bramble.api.transport.TransportConstants.TAG_LENGTH;
 import static org.briarproject.bramble.util.LogUtils.logException;
 
@@ -52,7 +52,8 @@ public class MailboxManagerImpl implements MailboxManager {
 	private final BdfWriterFactory bdfWriterFactory;
 	private KeyManager keyManager;
 
-	private PrivateMailboxSession privateMailboxSession = null;
+	private AtomicBoolean hasPrivateMailboxSession = new AtomicBoolean(false);
+	private PrivateMailboxSession privateMailboxSession;
 
 	@Inject
 	public MailboxManagerImpl(@IoExecutor Executor ioExecutor,
@@ -74,21 +75,19 @@ public class MailboxManagerImpl implements MailboxManager {
 
 	@Override
 	public void handleOutgoingContactMailboxConnection(ContactId contactId,
-			DuplexTransportConnection connection, TransportId transportId) {
+			ContactId mailboxId, DuplexTransportConnection connection,
+			TransportId transportId) {
 		ioExecutor.execute(
 				new ManageMailboxConnection(transportId, connection,
-						ContactType.CONTACT_MAILBOX, contactId));
+						CONTACT_MAILBOX, contactId, mailboxId));
 	}
 
 	@Override
 	public void handleOutgoingPrivateMailboxConnection(ContactId contactId,
 			DuplexTransportConnection connection, TransportId transportId) {
-		if (LOG.isLoggable(INFO)) {
-			LOG.info("Handling Outgoing PrivateMailbox connection");
-		}
 		ioExecutor.execute(
 				new ManageMailboxConnection(transportId, connection,
-						ContactType.PRIVATE_MAILBOX, contactId));
+						PRIVATE_MAILBOX, contactId));
 	}
 
 	@Override
@@ -98,28 +97,29 @@ public class MailboxManagerImpl implements MailboxManager {
 
 		ioExecutor.execute(
 				new ManageMailboxConnection(ctx, transportId, reader, writer,
-						ContactType.MAILBOX_OWNER));
+						MAILBOX_OWNER));
 	}
 
 	@Override
 	public void handleInomingOwnerContactConnection(StreamContext ctx,
 			TransportId transportId, TransportConnectionReader reader,
-			TransportConnectionWriter writer){
+			TransportConnectionWriter writer) {
 		ioExecutor.execute(
 				new ManageMailboxConnection(ctx, transportId, reader, writer,
-						ContactType.MAILBOX_CONTACT)
+						MAILBOX_CONTACT)
 		);
 	}
 
+
 	@Override
-	public void handleOwnerContactWithoutMailbox(MailboxInfo mailboxInfo) {
-		if (null == privateMailboxSession)
+	public void handleContactWithoutMailbox(MailboxInfo mailboxInfo) {
+		if (!hasPrivateMailboxSession.get())
 			return;
-		ioExecutor.execute(
-				() -> privateMailboxSession.handleContactWithoutPrivateMailbox(mailboxInfo));
-	}
-
 
+		ioExecutor.execute(() ->
+				privateMailboxSession
+						.handleContactWithoutPrivateMailbox(mailboxInfo));
+	}
 
 	private class ManageMailboxConnection implements Runnable {
 		private boolean incoming;
@@ -130,6 +130,8 @@ public class MailboxManagerImpl implements MailboxManager {
 		private final TransportConnectionReader reader;
 
 		private final ContactId contactId;
+		private final ContactId connectionContactId;
+
 		private BdfWriter mailboxBdfWriter;
 		private BdfReader mailboxBdfReader;
 		private StreamContext incomingCtx = null;
@@ -144,6 +146,7 @@ public class MailboxManagerImpl implements MailboxManager {
 			incoming = true;
 			incomingCtx = ctx;
 			contactId = ctx.getContactId();
+			connectionContactId = contactId;
 			this.transportId = transportId;
 			this.contactType = contactType;
 			this.writer = writer;
@@ -151,7 +154,7 @@ public class MailboxManagerImpl implements MailboxManager {
 		}
 
 		/**
-		 * For Outgoing connections
+		 * For Outgoing connection to private mailbox
 		 */
 		public ManageMailboxConnection(TransportId transportId,
 				DuplexTransportConnection connection,
@@ -159,6 +162,23 @@ public class MailboxManagerImpl implements MailboxManager {
 			this.transportId = transportId;
 			this.incoming = false;
 			this.contactId = contactId;
+			this.connectionContactId = contactId;
+			this.contactType = contactType;
+			writer = connection.getWriter();
+			reader = connection.getReader();
+		}
+
+		/**
+		 * For Outgoing connection to contact mailbox
+		 */
+		public ManageMailboxConnection(TransportId transportId,
+				DuplexTransportConnection connection,
+				ContactType contactType, ContactId contactId,
+				ContactId mailboxId) {
+			this.transportId = transportId;
+			this.incoming = false;
+			this.contactId = contactId;
+			this.connectionContactId = mailboxId;
 			this.contactType = contactType;
 			writer = connection.getWriter();
 			reader = connection.getReader();
@@ -171,7 +191,8 @@ public class MailboxManagerImpl implements MailboxManager {
 				// and write tag
 				handleOutgoingStream();
 
-				// Read tag from connection
+				// Read tag from connection (For incoming connections,
+				// the tag is read by the connection manager)
 				if (!incoming)
 					readTag();
 
@@ -185,30 +206,40 @@ public class MailboxManagerImpl implements MailboxManager {
 			}
 
 			connectionRegistry
-					.registerConnection(contactId, MailboxConstants.ID,
+					.registerConnection(connectionContactId, transportId,
 							incoming);
 
 			MailboxProtocol mailboxProtocol =
 					new MailboxProtocol(ioExecutor, mailboxBdfWriter,
 							mailboxBdfReader);
 
+			// Create mailbox session (register MailboxRequestHandlers)
 			MailboxSession mailboxSession = mailboxSessionFactory
 					.createMailboxSession(mailboxProtocol, contactId,
 							contactType, writer.getMaxLatency(),
 							writer.getMaxIdleTime());
 
+			// Run MailboxProtocol after session is created and handlers
+			// have been registered
 			ioExecutor.execute(mailboxProtocol);
 
-			//TODO: Too hacky?
-			if (contactType == ContactType.PRIVATE_MAILBOX)
+
+			if (contactType == PRIVATE_MAILBOX) {
 				privateMailboxSession = (PrivateMailboxSession) mailboxSession;
+				hasPrivateMailboxSession.getAndSet(true);
+			}
 
 			mailboxSession.run();
-			disposeConnection(false);
 
+			if (contactType == PRIVATE_MAILBOX) {
+				hasPrivateMailboxSession.getAndSet(false);
+				privateMailboxSession = null;
+			}
+
+			disposeConnection(false);
 
 			connectionRegistry
-					.unregisterConnection(contactId, MailboxConstants.ID,
+					.unregisterConnection(connectionContactId, transportId,
 							incoming);
 
 		}
@@ -217,7 +248,8 @@ public class MailboxManagerImpl implements MailboxManager {
 				throws DbException, IOException {
 			// Allocate a stream context
 			StreamContext ctx =
-					keyManager.getStreamContext(contactId, transportId);
+					keyManager
+							.getStreamContext(connectionContactId, transportId);
 
 			if (ctx == null)
 				throw new IOException("Unable to allocate stream context");
@@ -228,7 +260,7 @@ public class MailboxManagerImpl implements MailboxManager {
 
 			OutputStream os = mailboxStreamWriter.getOutputStream();
 
-			// Write Tag to stream to allow recipient to identify the connection
+			// Write Tag to stream allowing the recipient to identify the connection
 			os.flush();
 
 			mailboxBdfWriter = bdfWriterFactory.createWriter(os);
@@ -249,7 +281,7 @@ public class MailboxManagerImpl implements MailboxManager {
 				throw new IOException(
 						"Unrecognised tag for returning stream");
 
-			if (!incomingCtx.getContactId().equals(contactId))
+			if (!incomingCtx.getContactId().equals(connectionContactId))
 				throw new IOException(
 						"ContactId for Incoming stream does not match expected ContactId");