diff --git a/briar-android/src/org/briarproject/android/contact/ConversationActivity.java b/briar-android/src/org/briarproject/android/contact/ConversationActivity.java
index dc96bd47fb7e6bb51d1dfb480ff2b25a53df0e21..b3f562949b34658b1f690376dd7f83c0b091f9b6 100644
--- a/briar-android/src/org/briarproject/android/contact/ConversationActivity.java
+++ b/briar-android/src/org/briarproject/android/contact/ConversationActivity.java
@@ -19,6 +19,7 @@ import android.widget.Toast;
 import org.briarproject.R;
 import org.briarproject.android.BriarActivity;
 import org.briarproject.android.util.BriarRecyclerView;
+import org.briarproject.api.FormatException;
 import org.briarproject.api.android.AndroidNotificationManager;
 import org.briarproject.api.contact.Contact;
 import org.briarproject.api.contact.ContactId;
@@ -47,8 +48,6 @@ import org.briarproject.api.sync.Message;
 import org.briarproject.api.sync.MessageId;
 import org.briarproject.util.StringUtils;
 
-import java.io.IOException;
-import java.security.GeneralSecurityException;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -430,9 +429,7 @@ public class ConversationActivity extends BriarActivity
 				try {
 					storeMessage(privateMessageFactory.createPrivateMessage(
 							groupId, timestamp, null, "text/plain", body));
-				} catch (GeneralSecurityException e) {
-					throw new RuntimeException(e);
-				} catch (IOException e) {
+				} catch (FormatException e) {
 					throw new RuntimeException(e);
 				}
 			}
diff --git a/briar-api/src/org/briarproject/api/messaging/PrivateMessageFactory.java b/briar-api/src/org/briarproject/api/messaging/PrivateMessageFactory.java
index 72fded05b20215a0d16e617c2cb7cda26c1b9113..0c30b6e6125753c9906186f6608913e8238daf08 100644
--- a/briar-api/src/org/briarproject/api/messaging/PrivateMessageFactory.java
+++ b/briar-api/src/org/briarproject/api/messaging/PrivateMessageFactory.java
@@ -1,14 +1,12 @@
 package org.briarproject.api.messaging;
 
+import org.briarproject.api.FormatException;
 import org.briarproject.api.sync.GroupId;
 import org.briarproject.api.sync.MessageId;
 
-import java.io.IOException;
-import java.security.GeneralSecurityException;
-
 public interface PrivateMessageFactory {
 
 	PrivateMessage createPrivateMessage(GroupId groupId, long timestamp,
 			MessageId parent, String contentType, byte[] body)
-			throws IOException, GeneralSecurityException;
+			throws FormatException;
 }
diff --git a/briar-core/src/org/briarproject/messaging/PrivateMessageFactoryImpl.java b/briar-core/src/org/briarproject/messaging/PrivateMessageFactoryImpl.java
index da8112c95f8b7cb9f02fc394504cc3124e57850e..98349bcbba290e08b4ef4c0e14c0f2b63f18cd3d 100644
--- a/briar-core/src/org/briarproject/messaging/PrivateMessageFactoryImpl.java
+++ b/briar-core/src/org/briarproject/messaging/PrivateMessageFactoryImpl.java
@@ -1,19 +1,15 @@
 package org.briarproject.messaging;
 
-import org.briarproject.api.data.BdfWriter;
-import org.briarproject.api.data.BdfWriterFactory;
+import org.briarproject.api.FormatException;
+import org.briarproject.api.clients.ClientHelper;
+import org.briarproject.api.data.BdfList;
 import org.briarproject.api.messaging.PrivateMessage;
 import org.briarproject.api.messaging.PrivateMessageFactory;
 import org.briarproject.api.sync.GroupId;
 import org.briarproject.api.sync.Message;
-import org.briarproject.api.sync.MessageFactory;
 import org.briarproject.api.sync.MessageId;
 import org.briarproject.util.StringUtils;
 
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.security.GeneralSecurityException;
-
 import javax.inject.Inject;
 
 import static org.briarproject.api.messaging.MessagingConstants.MAX_CONTENT_TYPE_LENGTH;
@@ -21,36 +17,25 @@ import static org.briarproject.api.messaging.MessagingConstants.MAX_PRIVATE_MESS
 
 class PrivateMessageFactoryImpl implements PrivateMessageFactory {
 
-	private final MessageFactory messageFactory;
-	private final BdfWriterFactory bdfWriterFactory;
+	private final ClientHelper clientHelper;
 
 	@Inject
-	PrivateMessageFactoryImpl(MessageFactory messageFactory,
-			BdfWriterFactory bdfWriterFactory) {
-		this.messageFactory = messageFactory;
-		this.bdfWriterFactory = bdfWriterFactory;
+	PrivateMessageFactoryImpl(ClientHelper clientHelper) {
+		this.clientHelper = clientHelper;
 	}
 
 	@Override
 	public PrivateMessage createPrivateMessage(GroupId groupId, long timestamp,
 			MessageId parent, String contentType, byte[] body)
-			throws IOException, GeneralSecurityException {
+			throws FormatException {
 		// Validate the arguments
 		if (StringUtils.toUtf8(contentType).length > MAX_CONTENT_TYPE_LENGTH)
 			throw new IllegalArgumentException();
 		if (body.length > MAX_PRIVATE_MESSAGE_BODY_LENGTH)
 			throw new IllegalArgumentException();
 		// Serialise the message
-		ByteArrayOutputStream out = new ByteArrayOutputStream();
-		BdfWriter w = bdfWriterFactory.createWriter(out);
-		w.writeListStart();
-		if (parent == null) w.writeNull();
-		else w.writeRaw(parent.getBytes());
-		w.writeString(contentType);
-		w.writeRaw(body);
-		w.writeListEnd();
-		Message m = messageFactory.createMessage(groupId, timestamp,
-				out.toByteArray());
+		BdfList message = BdfList.of(parent, contentType, body);
+		Message m = clientHelper.createMessage(groupId, timestamp, message);
 		return new PrivateMessage(m, parent, contentType);
 	}
 }