diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/client/ClientHelper.java b/bramble-api/src/main/java/org/briarproject/bramble/api/client/ClientHelper.java
index 0ddd7f9d949eb18ca86227156075b681da3edd16..dd60bb610077338a63d1bebf15f5106f9194e886 100644
--- a/bramble-api/src/main/java/org/briarproject/bramble/api/client/ClientHelper.java
+++ b/bramble-api/src/main/java/org/briarproject/bramble/api/client/ClientHelper.java
@@ -7,6 +7,7 @@ import org.briarproject.bramble.api.db.DbException;
 import org.briarproject.bramble.api.db.Transaction;
 import org.briarproject.bramble.api.identity.Author;
 import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
+import org.briarproject.bramble.api.plugin.TransportId;
 import org.briarproject.bramble.api.properties.TransportProperties;
 import org.briarproject.bramble.api.sync.GroupId;
 import org.briarproject.bramble.api.sync.Message;
@@ -89,6 +90,10 @@ public interface ClientHelper {
 	BdfDictionary toDictionary(byte[] b, int off, int len)
 			throws FormatException;
 
+	BdfDictionary toDictionary(TransportProperties transportProperties);
+
+	BdfDictionary toDictionary(Map<TransportId, TransportProperties> map);
+
 	BdfList toList(byte[] b, int off, int len) throws FormatException;
 
 	BdfList toList(byte[] b) throws FormatException;
@@ -107,4 +112,8 @@ public interface ClientHelper {
 
 	TransportProperties parseAndValidateTransportProperties(
 			BdfDictionary properties) throws FormatException;
+
+	Map<TransportId, TransportProperties> parseAndValidateTransportPropertiesMap(
+			BdfDictionary properties) throws FormatException;
+
 }
diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/data/BdfDictionary.java b/bramble-api/src/main/java/org/briarproject/bramble/api/data/BdfDictionary.java
index 50b861d8954a7e0e1e4e2adbee9a40cd3592f54a..927dafb64bb6e0bb64e19e5907250a8b43be0590 100644
--- a/bramble-api/src/main/java/org/briarproject/bramble/api/data/BdfDictionary.java
+++ b/bramble-api/src/main/java/org/briarproject/bramble/api/data/BdfDictionary.java
@@ -34,7 +34,7 @@ public class BdfDictionary extends TreeMap<String, Object> {
 		super();
 	}
 
-	public BdfDictionary(Map<String, Object> m) {
+	public BdfDictionary(Map<String, ?> m) {
 		super(m);
 	}
 
diff --git a/bramble-api/src/test/java/org/briarproject/bramble/test/TestUtils.java b/bramble-api/src/test/java/org/briarproject/bramble/test/TestUtils.java
index 9da2a829ce775fa650ecf7ea8c1915516ff2e857..3ce8d154996355b2a96a6703fc854318c8a9d951 100644
--- a/bramble-api/src/test/java/org/briarproject/bramble/test/TestUtils.java
+++ b/bramble-api/src/test/java/org/briarproject/bramble/test/TestUtils.java
@@ -6,6 +6,7 @@ import org.briarproject.bramble.api.identity.Author;
 import org.briarproject.bramble.api.identity.AuthorId;
 import org.briarproject.bramble.api.identity.LocalAuthor;
 import org.briarproject.bramble.api.plugin.TransportId;
+import org.briarproject.bramble.api.properties.TransportProperties;
 import org.briarproject.bramble.api.sync.ClientId;
 import org.briarproject.bramble.api.sync.Group;
 import org.briarproject.bramble.api.sync.GroupId;
@@ -17,7 +18,9 @@ import java.io.File;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.Random;
 import java.util.concurrent.atomic.AtomicInteger;
 
@@ -25,6 +28,7 @@ import static org.briarproject.bramble.api.identity.Author.FORMAT_VERSION;
 import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
 import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
 import static org.briarproject.bramble.api.plugin.TransportId.MAX_TRANSPORT_ID_LENGTH;
+import static org.briarproject.bramble.api.properties.TransportPropertyConstants.MAX_PROPERTY_LENGTH;
 import static org.briarproject.bramble.api.sync.ClientId.MAX_CLIENT_ID_LENGTH;
 import static org.briarproject.bramble.api.sync.SyncConstants.MAX_GROUP_DESCRIPTOR_LENGTH;
 import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_BODY_LENGTH;
@@ -65,6 +69,25 @@ public class TestUtils {
 		return new TransportId(getRandomString(MAX_TRANSPORT_ID_LENGTH));
 	}
 
+	public static TransportProperties getTransportProperties(int number) {
+		TransportProperties tp = new TransportProperties();
+		for (int i = 0; i < number; i++) {
+			tp.put(getRandomString(1 + random.nextInt(MAX_PROPERTY_LENGTH)),
+					getRandomString(1 + random.nextInt(MAX_PROPERTY_LENGTH))
+			);
+		}
+		return tp;
+	}
+
+	public static Map<TransportId, TransportProperties> getTransportPropertiesMap(
+			int number) {
+		Map<TransportId, TransportProperties> map = new HashMap<>();
+		for (int i = 0; i < number; i++) {
+			map.put(getTransportId(), getTransportProperties(number));
+		}
+		return map;
+	}
+
 	public static SecretKey getSecretKey() {
 		return new SecretKey(getRandomBytes(SecretKey.LENGTH));
 	}
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/client/ClientHelperImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/client/ClientHelperImpl.java
index 81da440bcdf92a66bb99db523505578733ea2614..7c833a66d4c5b143dc8425c85b9b4553644a87ab 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/client/ClientHelperImpl.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/client/ClientHelperImpl.java
@@ -18,6 +18,7 @@ import org.briarproject.bramble.api.db.Transaction;
 import org.briarproject.bramble.api.identity.Author;
 import org.briarproject.bramble.api.identity.AuthorFactory;
 import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
+import org.briarproject.bramble.api.plugin.TransportId;
 import org.briarproject.bramble.api.properties.TransportProperties;
 import org.briarproject.bramble.api.sync.GroupId;
 import org.briarproject.bramble.api.sync.Message;
@@ -327,6 +328,20 @@ class ClientHelperImpl implements ClientHelper {
 		}
 	}
 
+	@Override
+	public BdfDictionary toDictionary(TransportProperties transportProperties) {
+		return new BdfDictionary(transportProperties);
+	}
+
+	@Override
+	public BdfDictionary toDictionary(
+			Map<TransportId, TransportProperties> map) {
+		BdfDictionary d = new BdfDictionary();
+		for (Entry<TransportId, TransportProperties> e : map.entrySet())
+			d.put(e.getKey().getString(), new BdfDictionary(e.getValue()));
+		return d;
+	}
+
 	@Override
 	public BdfList toList(byte[] b, int off, int len) throws FormatException {
 		ByteArrayInputStream in = new ByteArrayInputStream(b, off, len);
@@ -399,4 +414,19 @@ class ClientHelperImpl implements ClientHelper {
 		}
 		return p;
 	}
+
+	@Override
+	public Map<TransportId, TransportProperties> parseAndValidateTransportPropertiesMap(
+			BdfDictionary properties) throws FormatException {
+		Map<TransportId, TransportProperties> tpMap = new HashMap<>();
+		for (String key : properties.keySet()) {
+			TransportId transportId = new TransportId(key);
+			TransportProperties transportProperties =
+					parseAndValidateTransportProperties(
+							properties.getDictionary(key));
+			tpMap.put(transportId, transportProperties);
+		}
+		return tpMap;
+	}
+
 }