From f2d80825bc3b604afb2737ba2eb066efd40cf600 Mon Sep 17 00:00:00 2001
From: akwizgran <akwizgran@users.sourceforge.net>
Date: Fri, 21 Oct 2011 18:25:25 +0100
Subject: [PATCH] Separated the subject line from the message body.

---
 api/net/sf/briar/api/protocol/Message.java    |  6 ++++
 .../sf/briar/api/protocol/MessageEncoder.java | 17 ++++-----
 .../sf/briar/protocol/MessageEncoderImpl.java | 33 ++++++++++-------
 .../net/sf/briar/protocol/MessageImpl.java    |  8 ++++-
 .../net/sf/briar/protocol/MessageReader.java  |  5 ++-
 .../net/sf/briar/ProtocolIntegrationTest.java | 11 +++---
 .../sf/briar/db/DatabaseComponentTest.java    | 10 +++---
 test/net/sf/briar/db/H2DatabaseTest.java      | 36 ++++++++++---------
 test/net/sf/briar/db/TestMessage.java         |  8 ++++-
 .../briar/protocol/ProtocolReadWriteTest.java |  3 +-
 .../briar/protocol/writers/ConstantsTest.java |  9 +++--
 .../batch/BatchConnectionReadWriteTest.java   |  3 +-
 12 files changed, 95 insertions(+), 54 deletions(-)

diff --git a/api/net/sf/briar/api/protocol/Message.java b/api/net/sf/briar/api/protocol/Message.java
index 5af513d283..6b056700aa 100644
--- a/api/net/sf/briar/api/protocol/Message.java
+++ b/api/net/sf/briar/api/protocol/Message.java
@@ -10,6 +10,9 @@ public interface Message {
 	static final int MAX_BODY_LENGTH =
 		ProtocolConstants.MAX_PACKET_LENGTH - 1024;
 
+	/** The maximum length of a subject line in UTF-8 bytes. */
+	static final int MAX_SUBJECT_LENGTH = 100;
+
 	/** The maximum length of a signature in bytes. */
 	static final int MAX_SIGNATURE_LENGTH = 100;
 
@@ -31,6 +34,9 @@ public interface Message {
 	/** Returns the message's author. */
 	AuthorId getAuthor();
 
+	/** Returns the message's subject line. */
+	String getSubject();
+
 	/** Returns the timestamp created by the message's author. */
 	long getTimestamp();
 
diff --git a/api/net/sf/briar/api/protocol/MessageEncoder.java b/api/net/sf/briar/api/protocol/MessageEncoder.java
index e1322cbedc..d01f5f0a9d 100644
--- a/api/net/sf/briar/api/protocol/MessageEncoder.java
+++ b/api/net/sf/briar/api/protocol/MessageEncoder.java
@@ -7,24 +7,25 @@ import java.security.PrivateKey;
 public interface MessageEncoder {
 
 	/** Encodes a private message. */
-	Message encodeMessage(MessageId parent, byte[] body) throws IOException,
-	GeneralSecurityException;
+	Message encodeMessage(MessageId parent, String subject, byte[] body)
+	throws IOException, GeneralSecurityException;
 
 	/** Encodes an anonymous message to an unrestricted group. */
-	Message encodeMessage(MessageId parent, Group group, byte[] body)
-	throws IOException, GeneralSecurityException;
+	Message encodeMessage(MessageId parent, Group group, String subject,
+			byte[] body) throws IOException, GeneralSecurityException;
 
 	/** Encodes an anonymous message to a restricted group. */
 	Message encodeMessage(MessageId parent, Group group, PrivateKey groupKey,
-			byte[] body) throws IOException, GeneralSecurityException;
+			String subject, byte[] body) throws IOException,
+			GeneralSecurityException;
 
 	/** Encodes a pseudonymous message to an unrestricted group. */
 	Message encodeMessage(MessageId parent, Group group, Author author,
-			PrivateKey authorKey, byte[] body) throws IOException,
-			GeneralSecurityException;
+			PrivateKey authorKey, String subject, byte[] body)
+	throws IOException, GeneralSecurityException;
 
 	/** Encode a pseudonymous message to a restricted group. */
 	Message encodeMessage(MessageId parent, Group group, PrivateKey groupKey,
-			Author author, PrivateKey authorKey, byte[] body)
+			Author author, PrivateKey authorKey, String subject, byte[] body)
 	throws IOException, GeneralSecurityException;
 }
diff --git a/components/net/sf/briar/protocol/MessageEncoderImpl.java b/components/net/sf/briar/protocol/MessageEncoderImpl.java
index acf1aeebf0..39ab3b47f3 100644
--- a/components/net/sf/briar/protocol/MessageEncoderImpl.java
+++ b/components/net/sf/briar/protocol/MessageEncoderImpl.java
@@ -39,37 +39,42 @@ class MessageEncoderImpl implements MessageEncoder {
 		this.writerFactory = writerFactory;
 	}
 
-	public Message encodeMessage(MessageId parent, byte[] body)
+	public Message encodeMessage(MessageId parent, String subject, byte[] body)
 	throws IOException, GeneralSecurityException {
-		return encodeMessage(parent, null, null, null, null, body);
+		return encodeMessage(parent, null, null, null, null, subject, body);
 	}
 
-	public Message encodeMessage(MessageId parent, Group group, byte[] body)
-	throws IOException, GeneralSecurityException {
-		return encodeMessage(parent, group, null, null, null, body);
+	public Message encodeMessage(MessageId parent, Group group, String subject,
+			byte[] body) throws IOException, GeneralSecurityException {
+		return encodeMessage(parent, group, null, null, null, subject, body);
 	}
 
 	public Message encodeMessage(MessageId parent, Group group,
-			PrivateKey groupKey, byte[] body) throws IOException,
-			GeneralSecurityException {
-		return encodeMessage(parent, group, groupKey, null, null, body);
+			PrivateKey groupKey, String subject, byte[] body)
+	throws IOException, GeneralSecurityException {
+		return encodeMessage(parent, group, groupKey, null, null, subject,
+				body);
 	}
 
 	public Message encodeMessage(MessageId parent, Group group, Author author,
-			PrivateKey authorKey, byte[] body) throws IOException,
-			GeneralSecurityException {
-		return encodeMessage(parent, group, null, author, authorKey, body);
+			PrivateKey authorKey, String subject, byte[] body)
+	throws IOException, GeneralSecurityException {
+		return encodeMessage(parent, group, null, author, authorKey, subject,
+				body);
 	}
 
 	public Message encodeMessage(MessageId parent, Group group,
 			PrivateKey groupKey, Author author, PrivateKey authorKey,
-			byte[] body) throws IOException, GeneralSecurityException {
+			String subject, byte[] body) throws IOException,
+			GeneralSecurityException {
 
 		if((author == null) != (authorKey == null))
 			throw new IllegalArgumentException();
 		if((group == null || group.getPublicKey() == null) !=
 			(groupKey == null))
 			throw new IllegalArgumentException();
+		if(subject.getBytes("UTF-8").length > Message.MAX_SUBJECT_LENGTH)
+			throw new IllegalArgumentException();
 		if(body.length > Message.MAX_BODY_LENGTH)
 			throw new IllegalArgumentException();
 
@@ -98,6 +103,7 @@ class MessageEncoderImpl implements MessageEncoder {
 		else group.writeTo(w);
 		if(author == null) w.writeNull();
 		else author.writeTo(w);
+		w.writeString(subject);
 		long timestamp = System.currentTimeMillis();
 		w.writeInt64(timestamp);
 		byte[] salt = new byte[Message.SALT_LENGTH];
@@ -130,6 +136,7 @@ class MessageEncoderImpl implements MessageEncoder {
 		MessageId id = new MessageId(messageDigest.digest());
 		GroupId groupId = group == null ? null : group.getId();
 		AuthorId authorId = author == null ? null : author.getId();
-		return new MessageImpl(id, parent, groupId, authorId, timestamp, raw);
+		return new MessageImpl(id, parent, groupId, authorId, subject,
+				timestamp, raw);
 	}
 }
diff --git a/components/net/sf/briar/protocol/MessageImpl.java b/components/net/sf/briar/protocol/MessageImpl.java
index a8360a7ed8..e8e54e1eb4 100644
--- a/components/net/sf/briar/protocol/MessageImpl.java
+++ b/components/net/sf/briar/protocol/MessageImpl.java
@@ -11,15 +11,17 @@ class MessageImpl implements Message {
 	private final MessageId id, parent;
 	private final GroupId group;
 	private final AuthorId author;
+	private final String subject;
 	private final long timestamp;
 	private final byte[] raw;
 
 	public MessageImpl(MessageId id, MessageId parent, GroupId group,
-			AuthorId author, long timestamp, byte[] raw) {
+			AuthorId author, String subject, long timestamp, byte[] raw) {
 		this.id = id;
 		this.parent = parent;
 		this.group = group;
 		this.author = author;
+		this.subject = subject;
 		this.timestamp = timestamp;
 		this.raw = raw;
 	}
@@ -40,6 +42,10 @@ class MessageImpl implements Message {
 		return author;
 	}
 
+	public String getSubject() {
+		return subject;
+	}
+
 	public long getTimestamp() {
 		return timestamp;
 	}
diff --git a/components/net/sf/briar/protocol/MessageReader.java b/components/net/sf/briar/protocol/MessageReader.java
index 30339c2453..52e398a1c4 100644
--- a/components/net/sf/briar/protocol/MessageReader.java
+++ b/components/net/sf/briar/protocol/MessageReader.java
@@ -76,6 +76,8 @@ class MessageReader implements ObjectReader<Message> {
 			author = r.readUserDefined(Types.AUTHOR, Author.class);
 			r.removeObjectReader(Types.AUTHOR);
 		}
+		// Read the subject
+		String subject = r.readString(Message.MAX_SUBJECT_LENGTH);
 		// Read the timestamp
 		long timestamp = r.readInt64();
 		if(timestamp < 0L) throw new FormatException();
@@ -128,6 +130,7 @@ class MessageReader implements ObjectReader<Message> {
 		MessageId id = new MessageId(messageDigest.digest());
 		GroupId groupId = group == null ? null : group.getId();
 		AuthorId authorId = author == null ? null : author.getId();
-		return new MessageImpl(id, parent, groupId, authorId, timestamp, raw);
+		return new MessageImpl(id, parent, groupId, authorId, subject,
+				timestamp, raw);
 	}
 }
diff --git a/test/net/sf/briar/ProtocolIntegrationTest.java b/test/net/sf/briar/ProtocolIntegrationTest.java
index 2ce0a1077c..e57d649f3c 100644
--- a/test/net/sf/briar/ProtocolIntegrationTest.java
+++ b/test/net/sf/briar/ProtocolIntegrationTest.java
@@ -75,6 +75,7 @@ public class ProtocolIntegrationTest extends TestCase {
 	private final Group group, group1;
 	private final Message message, message1, message2, message3;
 	private final String authorName = "Alice";
+	private final String subject = "Hello";
 	private final String messageBody = "Hello world";
 	private final Map<TransportId, TransportProperties> transports;
 
@@ -108,15 +109,17 @@ public class ProtocolIntegrationTest extends TestCase {
 				authorKeyPair.getPublic().getEncoded());
 		// Create two messages to each group: one anonymous, one pseudonymous
 		MessageEncoder messageEncoder = i.getInstance(MessageEncoder.class);
-		message = messageEncoder.encodeMessage(null, group,
+		message = messageEncoder.encodeMessage(null, group, subject,
 				messageBody.getBytes("UTF-8"));
 		message1 = messageEncoder.encodeMessage(null, group1,
-				groupKeyPair.getPrivate(), messageBody.getBytes("UTF-8"));
+				groupKeyPair.getPrivate(), subject,
+				messageBody.getBytes("UTF-8"));
 		message2 = messageEncoder.encodeMessage(null, group, author,
-				authorKeyPair.getPrivate(), messageBody.getBytes("UTF-8"));
+				authorKeyPair.getPrivate(), subject,
+				messageBody.getBytes("UTF-8"));
 		message3 = messageEncoder.encodeMessage(null, group1,
 				groupKeyPair.getPrivate(), author, authorKeyPair.getPrivate(),
-				messageBody.getBytes("UTF-8"));
+				subject, messageBody.getBytes("UTF-8"));
 		TransportProperties p =
 			new TransportProperties(Collections.singletonMap("bar", "baz"));
 		transports = Collections.singletonMap(transportId, p);
diff --git a/test/net/sf/briar/db/DatabaseComponentTest.java b/test/net/sf/briar/db/DatabaseComponentTest.java
index fecd3f4183..bc846980bd 100644
--- a/test/net/sf/briar/db/DatabaseComponentTest.java
+++ b/test/net/sf/briar/db/DatabaseComponentTest.java
@@ -52,6 +52,7 @@ public abstract class DatabaseComponentTest extends TestCase {
 	protected final ContactId contactId;
 	protected final GroupId groupId;
 	protected final MessageId messageId, parentId;
+	private final String subject;
 	private final long timestamp;
 	private final int size;
 	private final byte[] raw;
@@ -70,13 +71,14 @@ public abstract class DatabaseComponentTest extends TestCase {
 		groupId = new GroupId(TestUtils.getRandomId());
 		messageId = new MessageId(TestUtils.getRandomId());
 		parentId = new MessageId(TestUtils.getRandomId());
+		subject = "Foo";
 		timestamp = System.currentTimeMillis();
 		size = 1234;
 		raw = new byte[size];
-		message =
-			new TestMessage(messageId, null, groupId, authorId, timestamp, raw);
-		privateMessage =
-			new TestMessage(messageId, null, null, null, timestamp, raw);
+		message = new TestMessage(messageId, null, groupId, authorId, subject,
+				timestamp, raw);
+		privateMessage = new TestMessage(messageId, null, null, null, subject,
+				timestamp, raw);
 		group = new TestGroup(groupId, "The really exciting group", null);
 		transportId = new TransportId(123);
 		TransportProperties p =
diff --git a/test/net/sf/briar/db/H2DatabaseTest.java b/test/net/sf/briar/db/H2DatabaseTest.java
index f293677ef6..9f26ce7528 100644
--- a/test/net/sf/briar/db/H2DatabaseTest.java
+++ b/test/net/sf/briar/db/H2DatabaseTest.java
@@ -66,6 +66,7 @@ public class H2DatabaseTest extends TestCase {
 	private final ContactId contactId;
 	private final GroupId groupId;
 	private final MessageId messageId, privateMessageId;
+	private final String subject;
 	private final long timestamp;
 	private final int size;
 	private final byte[] raw;
@@ -91,14 +92,15 @@ public class H2DatabaseTest extends TestCase {
 		groupId = new GroupId(TestUtils.getRandomId());
 		messageId = new MessageId(TestUtils.getRandomId());
 		privateMessageId = new MessageId(TestUtils.getRandomId());
+		subject = "Foo";
 		timestamp = System.currentTimeMillis();
 		size = 1234;
 		raw = new byte[size];
 		random.nextBytes(raw);
-		message =
-			new TestMessage(messageId, null, groupId, authorId, timestamp, raw);
-		privateMessage =
-			new TestMessage(privateMessageId, null, null, null, timestamp, raw);
+		message = new TestMessage(messageId, null, groupId, authorId, subject,
+				timestamp, raw);
+		privateMessage = new TestMessage(privateMessageId, null, null, null,
+				subject, timestamp, raw);
 		group = groupFactory.createGroup(groupId, "Group name", null);
 		transportId = new TransportId(0);
 		properties = new TransportProperties(
@@ -797,7 +799,7 @@ public class H2DatabaseTest extends TestCase {
 		AuthorId authorId1 = new AuthorId(TestUtils.getRandomId());
 		MessageId messageId1 = new MessageId(TestUtils.getRandomId());
 		Message message1 = new TestMessage(messageId1, null, groupId, authorId1,
-				timestamp, raw);
+				subject, timestamp, raw);
 		Database<Connection> db = open(false);
 		Connection txn = db.startTransaction();
 
@@ -830,12 +832,12 @@ public class H2DatabaseTest extends TestCase {
 		Group group1 = groupFactory.createGroup(groupId1, "Another group name",
 				null);
 		Message child1 = new TestMessage(childId1, messageId, groupId,
-				authorId, timestamp, raw);
+				authorId, subject, timestamp, raw);
 		Message child2 = new TestMessage(childId2, messageId, groupId,
-				authorId, timestamp, raw);
+				authorId, subject, timestamp, raw);
 		// The third child is in a different group
 		Message child3 = new TestMessage(childId3, messageId, groupId1,
-				authorId, timestamp, raw);
+				authorId, subject, timestamp, raw);
 		Database<Connection> db = open(false);
 		Connection txn = db.startTransaction();
 
@@ -866,7 +868,7 @@ public class H2DatabaseTest extends TestCase {
 	public void testGetOldMessages() throws Exception {
 		MessageId messageId1 = new MessageId(TestUtils.getRandomId());
 		Message message1 = new TestMessage(messageId1, null, groupId, authorId,
-				timestamp + 1000, raw);
+				subject, timestamp + 1000, raw);
 		Database<Connection> db = open(false);
 		Connection txn = db.startTransaction();
 
@@ -897,7 +899,7 @@ public class H2DatabaseTest extends TestCase {
 		byte[] largeBody = new byte[ONE_MEGABYTE];
 		for(int i = 0; i < largeBody.length; i++) largeBody[i] = (byte) i;
 		Message message1 = new TestMessage(messageId, null, groupId, authorId,
-				timestamp, largeBody);
+				subject, timestamp, largeBody);
 		Database<Connection> db = open(false);
 
 		// Sanity check: there should be enough space on disk for this test
@@ -1463,7 +1465,7 @@ public class H2DatabaseTest extends TestCase {
 
 		// A message with no parent should return null
 		MessageId childId = new MessageId(TestUtils.getRandomId());
-		Message child = new TestMessage(childId, null, groupId, null,
+		Message child = new TestMessage(childId, null, groupId, null, subject,
 				timestamp, raw);
 		db.addGroupMessage(txn, child);
 		assertTrue(db.containsMessage(txn, childId));
@@ -1485,7 +1487,7 @@ public class H2DatabaseTest extends TestCase {
 		MessageId childId = new MessageId(TestUtils.getRandomId());
 		MessageId parentId = new MessageId(TestUtils.getRandomId());
 		Message child = new TestMessage(childId, parentId, groupId, null,
-				timestamp, raw);
+				subject, timestamp, raw);
 		db.addGroupMessage(txn, child);
 		assertTrue(db.containsMessage(txn, childId));
 		assertFalse(db.containsMessage(txn, parentId));
@@ -1511,9 +1513,9 @@ public class H2DatabaseTest extends TestCase {
 		MessageId childId = new MessageId(TestUtils.getRandomId());
 		MessageId parentId = new MessageId(TestUtils.getRandomId());
 		Message child = new TestMessage(childId, parentId, groupId, null,
-				timestamp, raw);
+				subject, timestamp, raw);
 		Message parent = new TestMessage(parentId, null, groupId1, null,
-				timestamp, raw);
+				subject, timestamp, raw);
 		db.addGroupMessage(txn, child);
 		db.addGroupMessage(txn, parent);
 		assertTrue(db.containsMessage(txn, childId));
@@ -1537,7 +1539,7 @@ public class H2DatabaseTest extends TestCase {
 		// A message with a private parent should return null
 		MessageId childId = new MessageId(TestUtils.getRandomId());
 		Message child = new TestMessage(childId, privateMessageId, groupId,
-				null, timestamp, raw);
+				null, subject, timestamp, raw);
 		db.addGroupMessage(txn, child);
 		db.addPrivateMessage(txn, privateMessage, contactId);
 		assertTrue(db.containsMessage(txn, childId));
@@ -1561,9 +1563,9 @@ public class H2DatabaseTest extends TestCase {
 		MessageId childId = new MessageId(TestUtils.getRandomId());
 		MessageId parentId = new MessageId(TestUtils.getRandomId());
 		Message child = new TestMessage(childId, parentId, groupId, null,
-				timestamp, raw);
+				subject, timestamp, raw);
 		Message parent = new TestMessage(parentId, null, groupId, null,
-				timestamp, raw);
+				subject, timestamp, raw);
 		db.addGroupMessage(txn, child);
 		db.addGroupMessage(txn, parent);
 		assertTrue(db.containsMessage(txn, childId));
diff --git a/test/net/sf/briar/db/TestMessage.java b/test/net/sf/briar/db/TestMessage.java
index 6b0b017815..c118dd7157 100644
--- a/test/net/sf/briar/db/TestMessage.java
+++ b/test/net/sf/briar/db/TestMessage.java
@@ -10,15 +10,17 @@ class TestMessage implements Message {
 	private final MessageId id, parent;
 	private final GroupId group;
 	private final AuthorId author;
+	private final String subject;
 	private final long timestamp;
 	private final byte[] raw;
 
 	public TestMessage(MessageId id, MessageId parent, GroupId group,
-			AuthorId author, long timestamp, byte[] raw) {
+			AuthorId author, String subject, long timestamp, byte[] raw) {
 		this.id = id;
 		this.parent = parent;
 		this.group = group;
 		this.author = author;
+		this.subject = subject;
 		this.timestamp = timestamp;
 		this.raw = raw;
 	}
@@ -39,6 +41,10 @@ class TestMessage implements Message {
 		return author;
 	}
 
+	public String getSubject() {
+		return subject;
+	}
+
 	public long getTimestamp() {
 		return timestamp;
 	}
diff --git a/test/net/sf/briar/protocol/ProtocolReadWriteTest.java b/test/net/sf/briar/protocol/ProtocolReadWriteTest.java
index f98a61504c..43598bc483 100644
--- a/test/net/sf/briar/protocol/ProtocolReadWriteTest.java
+++ b/test/net/sf/briar/protocol/ProtocolReadWriteTest.java
@@ -46,6 +46,7 @@ public class ProtocolReadWriteTest extends TestCase {
 	private final BatchId batchId;
 	private final Group group;
 	private final Message message;
+	private final String subject = "Hello";
 	private final String messageBody = "Hello world";
 	private final BitSet bitSet;
 	private final Map<Group, Long> subscriptions;
@@ -64,7 +65,7 @@ public class ProtocolReadWriteTest extends TestCase {
 		GroupFactory groupFactory = i.getInstance(GroupFactory.class);
 		group = groupFactory.createGroup("Unrestricted group", null);
 		MessageEncoder messageEncoder = i.getInstance(MessageEncoder.class);
-		message = messageEncoder.encodeMessage(null, group,
+		message = messageEncoder.encodeMessage(null, group, subject,
 				messageBody.getBytes("UTF-8"));
 		bitSet = new BitSet();
 		bitSet.set(3);
diff --git a/test/net/sf/briar/protocol/writers/ConstantsTest.java b/test/net/sf/briar/protocol/writers/ConstantsTest.java
index 84c30ebc0d..694cc5a3a8 100644
--- a/test/net/sf/briar/protocol/writers/ConstantsTest.java
+++ b/test/net/sf/briar/protocol/writers/ConstantsTest.java
@@ -104,9 +104,10 @@ public class ConstantsTest extends TestCase {
 		// Create a maximum-length message
 		PrivateKey groupPrivate = crypto.generateKeyPair().getPrivate();
 		PrivateKey authorPrivate = crypto.generateKeyPair().getPrivate();
+		String subject = createRandomString(Message.MAX_SUBJECT_LENGTH);
 		byte[] body = new byte[Message.MAX_BODY_LENGTH];
 		Message message = messageEncoder.encodeMessage(null, group,
-				groupPrivate, author, authorPrivate, body);
+				groupPrivate, author, authorPrivate, subject, body);
 		// Add the message to a batch
 		ByteArrayOutputStream out = new ByteArrayOutputStream(
 				ProtocolConstants.MAX_PACKET_LENGTH);
@@ -216,12 +217,14 @@ public class ConstantsTest extends TestCase {
 		assertTrue(out.size() <= ProtocolConstants.MAX_PACKET_LENGTH);
 	}
 
-	private static String createRandomString(int length) {
+	private static String createRandomString(int length) throws Exception {
 		StringBuilder s = new StringBuilder(length);
 		for(int i = 0; i < length; i++) {
 			int digit = (int) (Math.random() * 10);
 			s.append((char) ('0' + digit));
 		}
-		return s.toString();
+		String string = s.toString();
+		assertEquals(length, string.getBytes("UTF-8").length);
+		return string;
 	}
 }
diff --git a/test/net/sf/briar/transport/batch/BatchConnectionReadWriteTest.java b/test/net/sf/briar/transport/batch/BatchConnectionReadWriteTest.java
index df42455298..b6d0ab5e80 100644
--- a/test/net/sf/briar/transport/batch/BatchConnectionReadWriteTest.java
+++ b/test/net/sf/briar/transport/batch/BatchConnectionReadWriteTest.java
@@ -97,9 +97,10 @@ public class BatchConnectionReadWriteTest extends TestCase {
 		db.open(false);
 		// Add Bob as a contact and send him a message
 		ContactId contactId = db.addContact(transports, aliceSecret);
+		String subject = "Hello";
 		byte[] messageBody = "Hi Bob!".getBytes("UTF-8");
 		MessageEncoder encoder = alice.getInstance(MessageEncoder.class);
-		Message message = encoder.encodeMessage(null, messageBody);
+		Message message = encoder.encodeMessage(null, subject, messageBody);
 		db.addLocalPrivateMessage(message, contactId);
 		// Create an outgoing batch connection
 		ByteArrayOutputStream out = new ByteArrayOutputStream();
-- 
GitLab