From 78740a694262b48a79e590178c5fa3ab596470b4 Mon Sep 17 00:00:00 2001
From: Torsten Grote <t@grobox.de>
Date: Thu, 27 Oct 2016 13:30:34 -0200
Subject: [PATCH] Remove content-type and parentId from private messages

and turn them into a regular string.
---
 .../MessageSizeIntegrationTest.java           | 15 +++++-------
 .../SimplexMessagingIntegrationTest.java      |  4 ++--
 .../android/contact/ConversationActivity.java | 14 +++++------
 .../android/sharing/BaseMessageFragment.java  |  2 +-
 .../android/threaded/ThreadListActivity.java  |  2 +-
 .../threaded/ThreadListControllerImpl.java    |  4 ++--
 ...{BaseMessage.java => ThreadedMessage.java} | 20 +++++++++-------
 .../org/briarproject/api/forum/ForumPost.java | 23 ++++++++-----------
 .../api/messaging/MessagingManager.java       |  2 +-
 .../api/messaging/PrivateMessage.java         | 23 +++++++++----------
 .../api/messaging/PrivateMessageFactory.java  |  7 +++---
 .../api/messaging/PrivateMessageHeader.java   |  9 +-------
 .../api/privategroup/GroupMessage.java        | 11 ++++-----
 .../forum/ForumPostFactoryImpl.java           |  2 +-
 .../messaging/MessagingManagerImpl.java       | 18 ++++++---------
 .../messaging/PrivateMessageFactoryImpl.java  | 17 ++++++--------
 .../messaging/PrivateMessageValidator.java    | 18 ++++-----------
 .../org/briarproject/util/StringUtils.java    |  2 +-
 18 files changed, 81 insertions(+), 112 deletions(-)
 rename briar-api/src/org/briarproject/api/clients/{BaseMessage.java => ThreadedMessage.java} (54%)

diff --git a/briar-android-tests/src/test/java/org/briarproject/MessageSizeIntegrationTest.java b/briar-android-tests/src/test/java/org/briarproject/MessageSizeIntegrationTest.java
index 02849dfee8..b63c070dc8 100644
--- a/briar-android-tests/src/test/java/org/briarproject/MessageSizeIntegrationTest.java
+++ b/briar-android-tests/src/test/java/org/briarproject/MessageSizeIntegrationTest.java
@@ -8,12 +8,12 @@ import org.briarproject.api.forum.ForumPost;
 import org.briarproject.api.forum.ForumPostFactory;
 import org.briarproject.api.identity.AuthorFactory;
 import org.briarproject.api.identity.LocalAuthor;
-import org.briarproject.api.messaging.MessagingConstants;
 import org.briarproject.api.messaging.PrivateMessage;
 import org.briarproject.api.messaging.PrivateMessageFactory;
 import org.briarproject.api.sync.GroupId;
 import org.briarproject.api.sync.MessageId;
 import org.briarproject.system.SystemModule;
+import org.briarproject.util.StringUtils;
 import org.junit.Test;
 
 import javax.inject.Inject;
@@ -48,17 +48,14 @@ public class MessageSizeIntegrationTest extends BriarTestCase {
 		// Create a maximum-length private message
 		GroupId groupId = new GroupId(TestUtils.getRandomId());
 		long timestamp = Long.MAX_VALUE;
-		MessageId parent = new MessageId(TestUtils.getRandomId());
-		String contentType = TestUtils.getRandomString(
-				MessagingConstants.MAX_CONTENT_TYPE_LENGTH);
-		byte[] body = new byte[MAX_PRIVATE_MESSAGE_BODY_LENGTH];
+		String body =
+				StringUtils.fromUtf8(new byte[MAX_PRIVATE_MESSAGE_BODY_LENGTH]);
 		PrivateMessage message = privateMessageFactory.createPrivateMessage(
-				groupId, timestamp, parent, contentType, body);
+				groupId, timestamp, body);
 		// Check the size of the serialised message
 		int length = message.getMessage().getRaw().length;
-		assertTrue(length > UniqueId.LENGTH + 8 + UniqueId.LENGTH
-				+ MessagingConstants.MAX_CONTENT_TYPE_LENGTH
-				+ MAX_PRIVATE_MESSAGE_BODY_LENGTH);
+		assertTrue(
+				length > UniqueId.LENGTH + 8 + MAX_PRIVATE_MESSAGE_BODY_LENGTH);
 		assertTrue(length <= MAX_PACKET_PAYLOAD_LENGTH);
 	}
 
diff --git a/briar-android-tests/src/test/java/org/briarproject/SimplexMessagingIntegrationTest.java b/briar-android-tests/src/test/java/org/briarproject/SimplexMessagingIntegrationTest.java
index 661d0465ff..295b41c41b 100644
--- a/briar-android-tests/src/test/java/org/briarproject/SimplexMessagingIntegrationTest.java
+++ b/briar-android-tests/src/test/java/org/briarproject/SimplexMessagingIntegrationTest.java
@@ -97,9 +97,9 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
 
 		// Send Bob a message
 		GroupId groupId = messagingManager.getConversationId(contactId);
-		byte[] body = "Hi Bob!".getBytes("UTF-8");
+		String body = "Hi Bob!";
 		PrivateMessage message = privateMessageFactory.createPrivateMessage(
-				groupId, timestamp, null, "text/plain", body);
+				groupId, timestamp, body);
 		messagingManager.addLocalMessage(message);
 		// Get a stream context
 		StreamContext ctx = keyManager.getStreamContext(contactId,
diff --git a/briar-android/src/org/briarproject/android/contact/ConversationActivity.java b/briar-android/src/org/briarproject/android/contact/ConversationActivity.java
index 7bd1dfc45f..3659a691de 100644
--- a/briar-android/src/org/briarproject/android/contact/ConversationActivity.java
+++ b/briar-android/src/org/briarproject/android/contact/ConversationActivity.java
@@ -450,11 +450,11 @@ public class ConversationActivity extends BriarActivity
 			public void run() {
 				try {
 					long now = System.currentTimeMillis();
-					byte[] body = messagingManager.getMessageBody(m);
+					String body = messagingManager.getMessageBody(m);
 					long duration = System.currentTimeMillis() - now;
 					if (LOG.isLoggable(INFO))
 						LOG.info("Loading body took " + duration + " ms");
-					displayMessageBody(m, StringUtils.fromUtf8(body));
+					displayMessageBody(m, body);
 				} catch (DbException e) {
 					if (LOG.isLoggable(WARNING))
 						LOG.log(WARNING, e.toString(), e);
@@ -656,8 +656,7 @@ public class ConversationActivity extends BriarActivity
 			public void run() {
 				try {
 					storeMessage(privateMessageFactory.createPrivateMessage(
-							groupId, timestamp, null, "text/plain",
-							StringUtils.toUtf8(body)), body);
+							groupId, timestamp, body), body);
 				} catch (FormatException e) {
 					throw new RuntimeException(e);
 				}
@@ -676,9 +675,10 @@ public class ConversationActivity extends BriarActivity
 					if (LOG.isLoggable(INFO))
 						LOG.info("Storing message took " + duration + " ms");
 					MessageId id = m.getMessage().getId();
-					PrivateMessageHeader h = new PrivateMessageHeader(id,
-							groupId, m.getMessage().getTimestamp(),
-							m.getContentType(), true, false, false, false);
+					PrivateMessageHeader h =
+							new PrivateMessageHeader(id, groupId,
+									m.getMessage().getTimestamp(), true, false,
+									false, false);
 					ConversationItem item = ConversationItem.from(h);
 					item.setBody(body);
 					bodyCache.put(id, body);
diff --git a/briar-android/src/org/briarproject/android/sharing/BaseMessageFragment.java b/briar-android/src/org/briarproject/android/sharing/BaseMessageFragment.java
index eb05d19bcf..0e96655404 100644
--- a/briar-android/src/org/briarproject/android/sharing/BaseMessageFragment.java
+++ b/briar-android/src/org/briarproject/android/sharing/BaseMessageFragment.java
@@ -64,7 +64,7 @@ public abstract class BaseMessageFragment extends BaseFragment
 
 	@Override
 	public void onSendClick(String msg) {
-		if (StringUtils.isTooLong(msg, listener.getMaximumMessageLength())) {
+		if (StringUtils.utf8IsTooLong(msg, listener.getMaximumMessageLength())) {
 			Snackbar.make(message, R.string.text_too_long, LENGTH_SHORT).show();
 			return;
 		}
diff --git a/briar-android/src/org/briarproject/android/threaded/ThreadListActivity.java b/briar-android/src/org/briarproject/android/threaded/ThreadListActivity.java
index eff17e175e..28ae81f127 100644
--- a/briar-android/src/org/briarproject/android/threaded/ThreadListActivity.java
+++ b/briar-android/src/org/briarproject/android/threaded/ThreadListActivity.java
@@ -232,7 +232,7 @@ public abstract class ThreadListActivity<G extends NamedGroup, I extends ThreadI
 	public void onSendClick(String text) {
 		if (text.trim().length() == 0)
 			return;
-		if (StringUtils.isTooLong(text, getMaxBodyLength())) {
+		if (StringUtils.utf8IsTooLong(text, getMaxBodyLength())) {
 			displaySnackbarShort(R.string.text_too_long);
 			return;
 		}
diff --git a/briar-android/src/org/briarproject/android/threaded/ThreadListControllerImpl.java b/briar-android/src/org/briarproject/android/threaded/ThreadListControllerImpl.java
index 6ea72c8923..aeb4dcdf6f 100644
--- a/briar-android/src/org/briarproject/android/threaded/ThreadListControllerImpl.java
+++ b/briar-android/src/org/briarproject/android/threaded/ThreadListControllerImpl.java
@@ -6,7 +6,7 @@ import android.support.annotation.CallSuper;
 import org.briarproject.android.api.AndroidNotificationManager;
 import org.briarproject.android.controller.DbControllerImpl;
 import org.briarproject.android.controller.handler.ResultExceptionHandler;
-import org.briarproject.api.clients.BaseMessage;
+import org.briarproject.api.clients.ThreadedMessage;
 import org.briarproject.api.clients.NamedGroup;
 import org.briarproject.api.clients.PostHeader;
 import org.briarproject.api.crypto.CryptoExecutor;
@@ -34,7 +34,7 @@ import java.util.logging.Logger;
 import static java.util.logging.Level.INFO;
 import static java.util.logging.Level.WARNING;
 
-public abstract class ThreadListControllerImpl<G extends NamedGroup, I extends ThreadItem, H extends PostHeader, M extends BaseMessage>
+public abstract class ThreadListControllerImpl<G extends NamedGroup, I extends ThreadItem, H extends PostHeader, M extends ThreadedMessage>
 		extends DbControllerImpl
 		implements ThreadListController<G, I, H>, EventListener {
 
diff --git a/briar-api/src/org/briarproject/api/clients/BaseMessage.java b/briar-api/src/org/briarproject/api/clients/ThreadedMessage.java
similarity index 54%
rename from briar-api/src/org/briarproject/api/clients/BaseMessage.java
rename to briar-api/src/org/briarproject/api/clients/ThreadedMessage.java
index ee3c0319f4..34cd35a2bf 100644
--- a/briar-api/src/org/briarproject/api/clients/BaseMessage.java
+++ b/briar-api/src/org/briarproject/api/clients/ThreadedMessage.java
@@ -1,5 +1,7 @@
 package org.briarproject.api.clients;
 
+import org.briarproject.api.identity.Author;
+import org.briarproject.api.messaging.PrivateMessage;
 import org.briarproject.api.nullsafety.NotNullByDefault;
 import org.briarproject.api.sync.Message;
 import org.briarproject.api.sync.MessageId;
@@ -9,19 +11,17 @@ import javax.annotation.concurrent.Immutable;
 
 @Immutable
 @NotNullByDefault
-public abstract class BaseMessage {
+public abstract class ThreadedMessage extends PrivateMessage {
 
-	private final Message message;
 	@Nullable
 	private final MessageId parent;
+	private final Author author;
 
-	public BaseMessage(Message message, @Nullable MessageId parent) {
-		this.message = message;
+	public ThreadedMessage(Message message, @Nullable MessageId parent,
+			Author author) {
+		super(message);
 		this.parent = parent;
-	}
-
-	public Message getMessage() {
-		return message;
+		this.author = author;
 	}
 
 	@Nullable
@@ -29,4 +29,8 @@ public abstract class BaseMessage {
 		return parent;
 	}
 
+	public Author getAuthor() {
+		return author;
+	}
+
 }
diff --git a/briar-api/src/org/briarproject/api/forum/ForumPost.java b/briar-api/src/org/briarproject/api/forum/ForumPost.java
index bbc23e9db0..205b4c6ecd 100644
--- a/briar-api/src/org/briarproject/api/forum/ForumPost.java
+++ b/briar-api/src/org/briarproject/api/forum/ForumPost.java
@@ -1,26 +1,21 @@
 package org.briarproject.api.forum;
 
-import org.briarproject.api.clients.BaseMessage;
+import org.briarproject.api.clients.ThreadedMessage;
 import org.briarproject.api.identity.Author;
+import org.briarproject.api.nullsafety.NotNullByDefault;
 import org.briarproject.api.sync.Message;
 import org.briarproject.api.sync.MessageId;
-import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
-public class ForumPost extends BaseMessage {
+import javax.annotation.concurrent.Immutable;
 
-	@Nullable
-	private final Author author;
+@Immutable
+@NotNullByDefault
+public class ForumPost extends ThreadedMessage {
 
-	public ForumPost(@NotNull Message message, @Nullable MessageId parent,
-			@Nullable Author author) {
-		super(message, parent);
-		this.author = author;
-	}
-
-	@Nullable
-	public Author getAuthor() {
-		return author;
+	public ForumPost(Message message, @Nullable MessageId parent,
+			Author author) {
+		super(message, parent, author);
 	}
 
 }
diff --git a/briar-api/src/org/briarproject/api/messaging/MessagingManager.java b/briar-api/src/org/briarproject/api/messaging/MessagingManager.java
index 627f5ceb6d..bf03e188c2 100644
--- a/briar-api/src/org/briarproject/api/messaging/MessagingManager.java
+++ b/briar-api/src/org/briarproject/api/messaging/MessagingManager.java
@@ -30,6 +30,6 @@ public interface MessagingManager extends MessageTracker {
 			throws DbException;
 
 	/** Returns the body of the private message with the given ID. */
-	byte[] getMessageBody(MessageId m) throws DbException;
+	String getMessageBody(MessageId m) throws DbException;
 
 }
diff --git a/briar-api/src/org/briarproject/api/messaging/PrivateMessage.java b/briar-api/src/org/briarproject/api/messaging/PrivateMessage.java
index b9354566a3..90c14e54ad 100644
--- a/briar-api/src/org/briarproject/api/messaging/PrivateMessage.java
+++ b/briar-api/src/org/briarproject/api/messaging/PrivateMessage.java
@@ -1,23 +1,22 @@
 package org.briarproject.api.messaging;
 
-import org.briarproject.api.clients.BaseMessage;
+import org.briarproject.api.nullsafety.NotNullByDefault;
 import org.briarproject.api.sync.Message;
-import org.briarproject.api.sync.MessageId;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
 
-public class PrivateMessage extends BaseMessage {
+import javax.annotation.concurrent.Immutable;
 
-	private final String contentType;
+@Immutable
+@NotNullByDefault
+public class PrivateMessage {
 
-	public PrivateMessage(@NotNull Message message, @Nullable MessageId parent,
-			@NotNull String contentType) {
-		super(message, parent);
-		this.contentType = contentType;
+	private final Message message;
+
+	public PrivateMessage(Message message) {
+		this.message = message;
 	}
 
-	public String getContentType() {
-		return contentType;
+	public Message getMessage() {
+		return message;
 	}
 
 }
diff --git a/briar-api/src/org/briarproject/api/messaging/PrivateMessageFactory.java b/briar-api/src/org/briarproject/api/messaging/PrivateMessageFactory.java
index 0c30b6e612..0191ce61a6 100644
--- a/briar-api/src/org/briarproject/api/messaging/PrivateMessageFactory.java
+++ b/briar-api/src/org/briarproject/api/messaging/PrivateMessageFactory.java
@@ -1,12 +1,13 @@
 package org.briarproject.api.messaging;
 
 import org.briarproject.api.FormatException;
+import org.briarproject.api.nullsafety.NotNullByDefault;
 import org.briarproject.api.sync.GroupId;
-import org.briarproject.api.sync.MessageId;
 
+@NotNullByDefault
 public interface PrivateMessageFactory {
 
 	PrivateMessage createPrivateMessage(GroupId groupId, long timestamp,
-			MessageId parent, String contentType, byte[] body)
-			throws FormatException;
+			String body) throws FormatException;
+
 }
diff --git a/briar-api/src/org/briarproject/api/messaging/PrivateMessageHeader.java b/briar-api/src/org/briarproject/api/messaging/PrivateMessageHeader.java
index 9fd76de6c8..706e453732 100644
--- a/briar-api/src/org/briarproject/api/messaging/PrivateMessageHeader.java
+++ b/briar-api/src/org/briarproject/api/messaging/PrivateMessageHeader.java
@@ -6,17 +6,10 @@ import org.briarproject.api.sync.MessageId;
 
 public class PrivateMessageHeader extends BaseMessageHeader {
 
-	private final String contentType;
-
 	public PrivateMessageHeader(MessageId id, GroupId groupId, long timestamp,
-			String contentType, boolean local, boolean read, boolean sent,
-			boolean seen) {
+			boolean local, boolean read, boolean sent, boolean seen) {
 
 		super(id, groupId, timestamp, local, read, sent, seen);
-		this.contentType = contentType;
 	}
 
-	public String getContentType() {
-		return contentType;
-	}
 }
diff --git a/briar-api/src/org/briarproject/api/privategroup/GroupMessage.java b/briar-api/src/org/briarproject/api/privategroup/GroupMessage.java
index 4de6bbbb0a..513f80c7be 100644
--- a/briar-api/src/org/briarproject/api/privategroup/GroupMessage.java
+++ b/briar-api/src/org/briarproject/api/privategroup/GroupMessage.java
@@ -1,6 +1,6 @@
 package org.briarproject.api.privategroup;
 
-import org.briarproject.api.clients.BaseMessage;
+import org.briarproject.api.clients.ThreadedMessage;
 import org.briarproject.api.identity.Author;
 import org.briarproject.api.nullsafety.NotNullByDefault;
 import org.briarproject.api.sync.Message;
@@ -11,18 +11,15 @@ import javax.annotation.concurrent.Immutable;
 
 @Immutable
 @NotNullByDefault
-public class GroupMessage extends BaseMessage {
-
-	private final Author member;
+public class GroupMessage extends ThreadedMessage {
 
 	public GroupMessage(Message message, @Nullable MessageId parent,
 			Author member) {
-		super(message, parent);
-		this.member = member;
+		super(message, parent, member);
 	}
 
 	public Author getMember() {
-		return member;
+		return super.getAuthor();
 	}
 
 }
diff --git a/briar-core/src/org/briarproject/forum/ForumPostFactoryImpl.java b/briar-core/src/org/briarproject/forum/ForumPostFactoryImpl.java
index 56c3a61b28..f4ddfad0f0 100644
--- a/briar-core/src/org/briarproject/forum/ForumPostFactoryImpl.java
+++ b/briar-core/src/org/briarproject/forum/ForumPostFactoryImpl.java
@@ -31,7 +31,7 @@ class ForumPostFactoryImpl implements ForumPostFactory {
 			MessageId parent, LocalAuthor author, String body)
 			throws FormatException, GeneralSecurityException {
 		// Validate the arguments
-		if (StringUtils.isTooLong(body, MAX_FORUM_POST_BODY_LENGTH))
+		if (StringUtils.utf8IsTooLong(body, MAX_FORUM_POST_BODY_LENGTH))
 			throw new IllegalArgumentException();
 		// Serialise the data to be signed
 		BdfList authorList =
diff --git a/briar-core/src/org/briarproject/messaging/MessagingManagerImpl.java b/briar-core/src/org/briarproject/messaging/MessagingManagerImpl.java
index a8fa365cb7..cc4c1040fd 100644
--- a/briar-core/src/org/briarproject/messaging/MessagingManagerImpl.java
+++ b/briar-core/src/org/briarproject/messaging/MessagingManagerImpl.java
@@ -98,12 +98,10 @@ class MessagingManagerImpl extends ConversationClientImpl
 
 		GroupId groupId = m.getGroupId();
 		long timestamp = meta.getLong("timestamp");
-		String contentType = meta.getString("contentType");
 		boolean local = meta.getBoolean("local");
 		boolean read = meta.getBoolean(MSG_KEY_READ);
 		PrivateMessageHeader header = new PrivateMessageHeader(
-				m.getId(), groupId, timestamp, contentType, local, read,
-				false, false);
+				m.getId(), groupId, timestamp, local, read, false, false);
 		ContactId contactId = getContactId(txn, groupId);
 		PrivateMessageReceivedEvent event = new PrivateMessageReceivedEvent(
 				header, contactId, groupId);
@@ -120,8 +118,6 @@ class MessagingManagerImpl extends ConversationClientImpl
 		try {
 			BdfDictionary meta = new BdfDictionary();
 			meta.put("timestamp", m.getMessage().getTimestamp());
-			if (m.getParent() != null) meta.put("parent", m.getParent());
-			meta.put("contentType", m.getContentType());
 			meta.put("local", true);
 			meta.put("read", true);
 			clientHelper.addLocalMessage(txn, m.getMessage(), meta, true);
@@ -193,11 +189,11 @@ class MessagingManagerImpl extends ConversationClientImpl
 			if (meta == null) continue;
 			try {
 				long timestamp = meta.getLong("timestamp");
-				String contentType = meta.getString("contentType");
 				boolean local = meta.getBoolean("local");
 				boolean read = meta.getBoolean("read");
-				headers.add(new PrivateMessageHeader(id, g, timestamp,
-						contentType, local, read, s.isSent(), s.isSeen()));
+				headers.add(
+						new PrivateMessageHeader(id, g, timestamp, local, read,
+								s.isSent(), s.isSeen()));
 			} catch (FormatException e) {
 				throw new DbException(e);
 			}
@@ -206,11 +202,11 @@ class MessagingManagerImpl extends ConversationClientImpl
 	}
 
 	@Override
-	public byte[] getMessageBody(MessageId m) throws DbException {
+	public String getMessageBody(MessageId m) throws DbException {
 		try {
-			// Parent ID, content type, private message body
+			// 0: private message body
 			BdfList message = clientHelper.getMessageAsList(m);
-			return message.getRaw(2);
+			return message.getString(0);
 		} catch (FormatException e) {
 			throw new DbException(e);
 		}
diff --git a/briar-core/src/org/briarproject/messaging/PrivateMessageFactoryImpl.java b/briar-core/src/org/briarproject/messaging/PrivateMessageFactoryImpl.java
index 98349bcbba..cb68389c7b 100644
--- a/briar-core/src/org/briarproject/messaging/PrivateMessageFactoryImpl.java
+++ b/briar-core/src/org/briarproject/messaging/PrivateMessageFactoryImpl.java
@@ -5,16 +5,16 @@ 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.nullsafety.NotNullByDefault;
 import org.briarproject.api.sync.GroupId;
 import org.briarproject.api.sync.Message;
-import org.briarproject.api.sync.MessageId;
-import org.briarproject.util.StringUtils;
 
 import javax.inject.Inject;
 
-import static org.briarproject.api.messaging.MessagingConstants.MAX_CONTENT_TYPE_LENGTH;
 import static org.briarproject.api.messaging.MessagingConstants.MAX_PRIVATE_MESSAGE_BODY_LENGTH;
+import static org.briarproject.util.StringUtils.utf8IsTooLong;
 
+@NotNullByDefault
 class PrivateMessageFactoryImpl implements PrivateMessageFactory {
 
 	private final ClientHelper clientHelper;
@@ -26,16 +26,13 @@ class PrivateMessageFactoryImpl implements PrivateMessageFactory {
 
 	@Override
 	public PrivateMessage createPrivateMessage(GroupId groupId, long timestamp,
-			MessageId parent, String contentType, byte[] body)
-			throws FormatException {
+			String body) 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)
+		if (utf8IsTooLong(body, MAX_PRIVATE_MESSAGE_BODY_LENGTH))
 			throw new IllegalArgumentException();
 		// Serialise the message
-		BdfList message = BdfList.of(parent, contentType, body);
+		BdfList message = BdfList.of(body);
 		Message m = clientHelper.createMessage(groupId, timestamp, message);
-		return new PrivateMessage(m, parent, contentType);
+		return new PrivateMessage(m);
 	}
 }
diff --git a/briar-core/src/org/briarproject/messaging/PrivateMessageValidator.java b/briar-core/src/org/briarproject/messaging/PrivateMessageValidator.java
index fec178b607..209a4b2466 100644
--- a/briar-core/src/org/briarproject/messaging/PrivateMessageValidator.java
+++ b/briar-core/src/org/briarproject/messaging/PrivateMessageValidator.java
@@ -1,9 +1,8 @@
 package org.briarproject.messaging;
 
 import org.briarproject.api.FormatException;
-import org.briarproject.api.UniqueId;
-import org.briarproject.api.clients.ClientHelper;
 import org.briarproject.api.clients.BdfMessageContext;
+import org.briarproject.api.clients.ClientHelper;
 import org.briarproject.api.data.BdfDictionary;
 import org.briarproject.api.data.BdfList;
 import org.briarproject.api.data.MetadataEncoder;
@@ -12,7 +11,6 @@ import org.briarproject.api.sync.Message;
 import org.briarproject.api.system.Clock;
 import org.briarproject.clients.BdfMessageValidator;
 
-import static org.briarproject.api.messaging.MessagingConstants.MAX_CONTENT_TYPE_LENGTH;
 import static org.briarproject.api.messaging.MessagingConstants.MAX_PRIVATE_MESSAGE_BODY_LENGTH;
 import static org.briarproject.clients.BdfConstants.MSG_KEY_READ;
 
@@ -26,22 +24,14 @@ class PrivateMessageValidator extends BdfMessageValidator {
 	@Override
 	protected BdfMessageContext validateMessage(Message m, Group g,
 			BdfList body) throws FormatException {
-		// Parent ID, content type, private message body
-		checkSize(body, 3);
-		// Parent ID is optional
-		byte[] parentId = body.getOptionalRaw(0);
-		checkLength(parentId, UniqueId.LENGTH);
-		// Content type
-		String contentType = body.getString(1);
-		checkLength(contentType, 0, MAX_CONTENT_TYPE_LENGTH);
+		// private message body
+		checkSize(body, 1);
 		// Private message body
-		byte[] privateMessageBody = body.getRaw(2);
+		String privateMessageBody = body.getString(0);
 		checkLength(privateMessageBody, 0, MAX_PRIVATE_MESSAGE_BODY_LENGTH);
 		// Return the metadata
 		BdfDictionary meta = new BdfDictionary();
 		meta.put("timestamp", m.getTimestamp());
-		if (parentId != null) meta.put("parent", parentId);
-		meta.put("contentType", contentType);
 		meta.put("local", false);
 		meta.put(MSG_KEY_READ, false);
 		return new BdfMessageContext(meta);
diff --git a/briar-core/src/org/briarproject/util/StringUtils.java b/briar-core/src/org/briarproject/util/StringUtils.java
index 610880265f..5acedc34e4 100644
--- a/briar-core/src/org/briarproject/util/StringUtils.java
+++ b/briar-core/src/org/briarproject/util/StringUtils.java
@@ -104,7 +104,7 @@ public class StringUtils {
 	/**
 	 * Returns true if the string is longer than maxLength
 	 */
-	public static boolean isTooLong(String s, int maxLength) {
+	public static boolean utf8IsTooLong(String s, int maxLength) {
 		return toUtf8(s).length > maxLength;
 	}
 }
-- 
GitLab