diff --git a/briar-api/src/net/sf/briar/api/crypto/KeyManager.java b/briar-api/src/net/sf/briar/api/crypto/KeyManager.java
index 46253592cfae44bf626c1bb455a97caa272ee0b8..b0703abbbf1cd952c440f8aa8a0b56ae6db81ba1 100644
--- a/briar-api/src/net/sf/briar/api/crypto/KeyManager.java
+++ b/briar-api/src/net/sf/briar/api/crypto/KeyManager.java
@@ -3,7 +3,7 @@ package net.sf.briar.api.crypto;
 import net.sf.briar.api.ContactId;
 import net.sf.briar.api.protocol.TransportId;
 import net.sf.briar.api.transport.ConnectionContext;
-import net.sf.briar.api.transport.ContactTransport;
+import net.sf.briar.api.transport.Endpoint;
 
 public interface KeyManager {
 
@@ -24,8 +24,8 @@ public interface KeyManager {
 	ConnectionContext getConnectionContext(ContactId c, TransportId t);
 
 	/**
-	 * Called whenever a contact transport has been added. The initial secret
+	 * Called whenever an endpoint has been added. The initial secret
 	 * is erased before returning.
 	 */
-	void contactTransportAdded(ContactTransport ct, byte[] initialSecret);
+	void endpointAdded(Endpoint ep, byte[] initialSecret);
 }
diff --git a/briar-api/src/net/sf/briar/api/db/DatabaseComponent.java b/briar-api/src/net/sf/briar/api/db/DatabaseComponent.java
index e986f4a5fadd8b472e7497c50d4230fe5518945c..c8a8b3a02fc8944a7a78008043804084b76555f6 100644
--- a/briar-api/src/net/sf/briar/api/db/DatabaseComponent.java
+++ b/briar-api/src/net/sf/briar/api/db/DatabaseComponent.java
@@ -24,7 +24,7 @@ import net.sf.briar.api.protocol.SubscriptionUpdate;
 import net.sf.briar.api.protocol.TransportAck;
 import net.sf.briar.api.protocol.TransportId;
 import net.sf.briar.api.protocol.TransportUpdate;
-import net.sf.briar.api.transport.ContactTransport;
+import net.sf.briar.api.transport.Endpoint;
 import net.sf.briar.api.transport.TemporarySecret;
 
 /**
@@ -54,8 +54,8 @@ public interface DatabaseComponent {
 	 */
 	ContactId addContact() throws DbException;
 
-	/** Adds a contact transport to the database. */
-	void addContactTransport(ContactTransport ct) throws DbException;
+	/** Adds an endpoitn to the database. */
+	void addEndpoint(Endpoint ep) throws DbException;
 
 	/** Adds a locally generated group message to the database. */
 	void addLocalGroupMessage(Message m) throws DbException;
@@ -239,8 +239,8 @@ public interface DatabaseComponent {
 	void removeContact(ContactId c) throws DbException;
 
 	/**
-	 * Sets the connection reordering window for the given contact transport
-	 * in the given rotation period.
+	 * Sets the connection reordering window for the given endoint in the given
+	 * rotation period.
 	 */
 	void setConnectionWindow(ContactId c, TransportId t, long period,
 			long centre, byte[] bitmap) throws DbException;
diff --git a/briar-api/src/net/sf/briar/api/db/NoSuchContactException.java b/briar-api/src/net/sf/briar/api/db/NoSuchContactException.java
index 8813cafa70687562ac36ac619719cd114c7e56f1..ed6033a2d1d4f8a205ecb172cd8f7bd1ceb867b7 100644
--- a/briar-api/src/net/sf/briar/api/db/NoSuchContactException.java
+++ b/briar-api/src/net/sf/briar/api/db/NoSuchContactException.java
@@ -2,7 +2,8 @@ package net.sf.briar.api.db;
 
 /**
  * Thrown when a database operation is attempted for a contact that is not in
- * the database.
+ * the database. This exception may occur due to concurrent updates and does
+ * not indicate a database error.
  */
 public class NoSuchContactException extends DbException {
 
diff --git a/briar-api/src/net/sf/briar/api/db/NoSuchContactTransportException.java b/briar-api/src/net/sf/briar/api/db/NoSuchContactTransportException.java
deleted file mode 100644
index 0bbf6828f320848cd9e6689ee0452fde36ecf50d..0000000000000000000000000000000000000000
--- a/briar-api/src/net/sf/briar/api/db/NoSuchContactTransportException.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package net.sf.briar.api.db;
-
-/**
- * Thrown when a database operation is attempted for a contact transport that
- * is not in the database.
- */
-public class NoSuchContactTransportException extends DbException {
-
-	private static final long serialVersionUID = -6274982612759573100L;
-}
diff --git a/briar-api/src/net/sf/briar/api/db/NoSuchSubscriptionException.java b/briar-api/src/net/sf/briar/api/db/NoSuchSubscriptionException.java
new file mode 100644
index 0000000000000000000000000000000000000000..5905a970c5daa7d1ece6436f3ee669a73561d59a
--- /dev/null
+++ b/briar-api/src/net/sf/briar/api/db/NoSuchSubscriptionException.java
@@ -0,0 +1,12 @@
+package net.sf.briar.api.db;
+
+/**
+ * Thrown when a database operation is attempted for a group to which the user
+ * does not subscribe. This exception may occur due to concurrent updates and
+ * does not indicate a database error.
+ */
+public class NoSuchSubscriptionException extends DbException {
+
+	private static final long serialVersionUID = -5494178507342571697L;
+
+}
diff --git a/briar-api/src/net/sf/briar/api/db/NoSuchTransportException.java b/briar-api/src/net/sf/briar/api/db/NoSuchTransportException.java
new file mode 100644
index 0000000000000000000000000000000000000000..7db2fd09640522b8b344c442866bb6d7ed551262
--- /dev/null
+++ b/briar-api/src/net/sf/briar/api/db/NoSuchTransportException.java
@@ -0,0 +1,11 @@
+package net.sf.briar.api.db;
+
+/**
+ * Thrown when a database operation is attempted for a transport that is not in
+ * the database. This exception may occur due to concurrent updates and does
+ * not indicate a database error.
+ */
+public class NoSuchTransportException extends DbException {
+
+	private static final long serialVersionUID = -6274982612759573100L;
+}
diff --git a/briar-api/src/net/sf/briar/api/transport/ContactTransport.java b/briar-api/src/net/sf/briar/api/transport/Endpoint.java
similarity index 89%
rename from briar-api/src/net/sf/briar/api/transport/ContactTransport.java
rename to briar-api/src/net/sf/briar/api/transport/Endpoint.java
index 870c2ccc4bd07bb17148c0d8fcc1fea8becfb554..3e1590e919b54634569cdfa08a49a62dff4a0dff 100644
--- a/briar-api/src/net/sf/briar/api/transport/ContactTransport.java
+++ b/briar-api/src/net/sf/briar/api/transport/Endpoint.java
@@ -3,14 +3,14 @@ package net.sf.briar.api.transport;
 import net.sf.briar.api.ContactId;
 import net.sf.briar.api.protocol.TransportId;
 
-public class ContactTransport {
+public class Endpoint {
 
 	private final ContactId contactId;
 	private final TransportId transportId;
 	private final long epoch, clockDiff, latency;
 	private final boolean alice;
 
-	public ContactTransport(ContactId contactId, TransportId transportId,
+	public Endpoint(ContactId contactId, TransportId transportId,
 			long epoch, long clockDiff, long latency, boolean alice) {
 		this.contactId = contactId;
 		this.transportId = transportId;
diff --git a/briar-api/src/net/sf/briar/api/transport/TemporarySecret.java b/briar-api/src/net/sf/briar/api/transport/TemporarySecret.java
index 2b2fc259b23004599edd41f964563bae0d5d9acb..4fc8110e03b9fa0358df267e8fa1f1eed914cd5b 100644
--- a/briar-api/src/net/sf/briar/api/transport/TemporarySecret.java
+++ b/briar-api/src/net/sf/briar/api/transport/TemporarySecret.java
@@ -4,7 +4,7 @@ import static net.sf.briar.api.transport.TransportConstants.CONNECTION_WINDOW_SI
 import net.sf.briar.api.ContactId;
 import net.sf.briar.api.protocol.TransportId;
 
-public class TemporarySecret extends ContactTransport {
+public class TemporarySecret extends Endpoint {
 
 	private final long period, outgoing, centre;
 	private final byte[] secret, bitmap;
@@ -30,10 +30,10 @@ public class TemporarySecret extends ContactTransport {
 				secret, 0L, 0L, new byte[CONNECTION_WINDOW_SIZE / 8]);
 	}
 
-	/** Creates a temporary secret derived from the given contact transport. */
-	public TemporarySecret(ContactTransport ct, long period, byte[] secret) {
-		this(ct.getContactId(), ct.getTransportId(), ct.getEpoch(),
-				ct.getClockDifference(), ct.getLatency(), ct.getAlice(),
+	/** Creates a temporary secret derived from the given endpoint. */
+	public TemporarySecret(Endpoint ep, long period, byte[] secret) {
+		this(ep.getContactId(), ep.getTransportId(), ep.getEpoch(),
+				ep.getClockDifference(), ep.getLatency(), ep.getAlice(),
 				period, secret);
 	}
 
diff --git a/briar-core/src/net/sf/briar/db/Database.java b/briar-core/src/net/sf/briar/db/Database.java
index 1a65cccc5fd27d724dc44a6b2e5ea3e17e588a43..0b16b768eb8af88fd3131753ee9e381adf4f72a6 100644
--- a/briar-core/src/net/sf/briar/db/Database.java
+++ b/briar-core/src/net/sf/briar/db/Database.java
@@ -22,7 +22,7 @@ import net.sf.briar.api.protocol.SubscriptionUpdate;
 import net.sf.briar.api.protocol.TransportAck;
 import net.sf.briar.api.protocol.TransportId;
 import net.sf.briar.api.protocol.TransportUpdate;
-import net.sf.briar.api.transport.ContactTransport;
+import net.sf.briar.api.transport.Endpoint;
 import net.sf.briar.api.transport.TemporarySecret;
 
 /**
@@ -82,11 +82,11 @@ interface Database<T> {
 	ContactId addContact(T txn) throws DbException;
 
 	/**
-	 * Adds a contact transport to the database.
+	 * Adds an endpoint to the database.
 	 * <p>
 	 * Locking: contact read, transport read, window write.
 	 */
-	void addContactTransport(T txn, ContactTransport ct) throws DbException;
+	void addEndpoint(T txn, Endpoint ep) throws DbException;
 
 	/**
 	 * Stores the given message, or returns false if the message is already in
@@ -156,14 +156,6 @@ interface Database<T> {
 	 */
 	boolean containsContact(T txn, ContactId c) throws DbException;
 
-	/**
-	 * Returns true if the database contains the given contact transport.
-	 * <p>
-	 * Locking: contact read, transport read, window read.
-	 */
-	boolean containsContactTransport(T txn, ContactId c, TransportId t)
-			throws DbException;
-
 	/**
 	 * Returns true if the database contains the given message.
 	 * <p>
@@ -178,6 +170,13 @@ interface Database<T> {
 	 */
 	boolean containsSubscription(T txn, GroupId g) throws DbException;
 
+	/**
+	 * Returns true if the database contains the given transport.
+	 * <p>
+	 * Locking: contact read, transport read.
+	 */
+	boolean containsTransport(T txn, TransportId t) throws DbException;
+
 	/**
 	 * Returns true if the user subscribes to the given group and the
 	 * subscription is visible to the given contact.
@@ -202,11 +201,11 @@ interface Database<T> {
 	Collection<ContactId> getContacts(T txn) throws DbException;
 
 	/**
-	 * Returns all contact transports.
+	 * Returns all endpoints.
 	 * <p>
 	 * Locking: contact read, transport read, window read.
 	 */
-	Collection<ContactTransport> getContactTransports(T txn) throws DbException;
+	Collection<Endpoint> getEndpoints(T txn) throws DbException;
 
 	/**
 	 * Returns the amount of free storage space available to the database, in
@@ -541,8 +540,8 @@ interface Database<T> {
 	void removeVisibility(T txn, ContactId c, GroupId g) throws DbException;
 
 	/**
-	 * Sets the connection reordering window for the given contact transport in
-	 * the given rotation period.
+	 * Sets the connection reordering window for the given endpoint in the
+	 * given rotation period.
 	 * <p>
 	 * Locking: contact read, transport read, window write.
 	 */
diff --git a/briar-core/src/net/sf/briar/db/DatabaseComponentImpl.java b/briar-core/src/net/sf/briar/db/DatabaseComponentImpl.java
index 21da037a759e756ba0f39f498b0410a327e62648..435ae04eddd78b3107b73fa276c3c70d30c347c2 100644
--- a/briar-core/src/net/sf/briar/db/DatabaseComponentImpl.java
+++ b/briar-core/src/net/sf/briar/db/DatabaseComponentImpl.java
@@ -29,7 +29,8 @@ import net.sf.briar.api.db.DatabaseComponent;
 import net.sf.briar.api.db.DbException;
 import net.sf.briar.api.db.MessageHeader;
 import net.sf.briar.api.db.NoSuchContactException;
-import net.sf.briar.api.db.NoSuchContactTransportException;
+import net.sf.briar.api.db.NoSuchSubscriptionException;
+import net.sf.briar.api.db.NoSuchTransportException;
 import net.sf.briar.api.db.event.ContactAddedEvent;
 import net.sf.briar.api.db.event.ContactRemovedEvent;
 import net.sf.briar.api.db.event.DatabaseEvent;
@@ -61,7 +62,7 @@ import net.sf.briar.api.protocol.SubscriptionUpdate;
 import net.sf.briar.api.protocol.TransportAck;
 import net.sf.briar.api.protocol.TransportId;
 import net.sf.briar.api.protocol.TransportUpdate;
-import net.sf.briar.api.transport.ContactTransport;
+import net.sf.briar.api.transport.Endpoint;
 import net.sf.briar.api.transport.TemporarySecret;
 
 import com.google.inject.Inject;
@@ -196,7 +197,7 @@ DatabaseCleaner.Callback {
 		for(DatabaseListener d : listeners) d.eventOccurred(e);
 	}
 
-	public void addContactTransport(ContactTransport ct) throws DbException {
+	public void addEndpoint(Endpoint ep) throws DbException {
 		contactLock.readLock().lock();
 		try {
 			transportLock.readLock().lock();
@@ -205,9 +206,11 @@ DatabaseCleaner.Callback {
 				try {
 					T txn = db.startTransaction();
 					try {
-						if(!db.containsContact(txn, ct.getContactId()))
+						if(!db.containsContact(txn, ep.getContactId()))
 							throw new NoSuchContactException();
-						db.addContactTransport(txn, ct);
+						if(!db.containsTransport(txn, ep.getTransportId()))
+							throw new NoSuchTransportException();
+						db.addEndpoint(txn, ep);
 						db.commitTransaction(txn);
 					} catch(DbException e) {
 						db.abortTransaction(txn);
@@ -381,9 +384,10 @@ DatabaseCleaner.Callback {
 								new ArrayList<TemporarySecret>();
 						for(TemporarySecret s : secrets) {
 							ContactId c = s.getContactId();
+							if(!db.containsContact(txn, c)) continue;
 							TransportId t = s.getTransportId();
-							if(db.containsContactTransport(txn, c, t))
-								relevant.add(s);
+							if(!db.containsTransport(txn, t)) continue;
+							relevant.add(s);
 						}
 						if(!secrets.isEmpty()) db.addSecrets(txn, relevant);
 						db.commitTransaction(txn);
@@ -725,6 +729,8 @@ DatabaseCleaner.Callback {
 			try {
 				T txn = db.startTransaction();
 				try {
+					if(!db.containsContact(txn, c))
+						throw new NoSuchContactException();
 					Collection<TransportAck> acks = db.getTransportAcks(txn, c);
 					db.commitTransaction(txn);
 					return acks;
@@ -748,6 +754,8 @@ DatabaseCleaner.Callback {
 			try {
 				T txn = db.startTransaction();
 				try {
+					if(!db.containsContact(txn, c))
+						throw new NoSuchContactException();
 					Collection<TransportUpdate> updates =
 							db.getTransportUpdates(txn, c);
 					db.commitTransaction(txn);
@@ -769,6 +777,8 @@ DatabaseCleaner.Callback {
 		try {
 			T txn = db.startTransaction();
 			try {
+				if(!db.containsTransport(txn, t))
+					throw new NoSuchTransportException();
 				TransportConfig config = db.getConfig(txn, t);
 				db.commitTransaction(txn);
 				return config;
@@ -804,6 +814,8 @@ DatabaseCleaner.Callback {
 		try {
 			T txn = db.startTransaction();
 			try {
+				if(!db.containsTransport(txn, t))
+					throw new NoSuchTransportException();
 				TransportProperties properties = db.getLocalProperties(txn, t);
 				db.commitTransaction(txn);
 				return properties;
@@ -822,6 +834,8 @@ DatabaseCleaner.Callback {
 		try {
 			T txn = db.startTransaction();
 			try {
+				if(!db.containsSubscription(txn, g))
+					throw new NoSuchSubscriptionException();
 				Collection<MessageHeader> headers =
 						db.getMessageHeaders(txn, g);
 				db.commitTransaction(txn);
@@ -951,6 +965,8 @@ DatabaseCleaner.Callback {
 			try {
 				T txn = db.startTransaction();
 				try {
+					if(!db.containsSubscription(txn, g))
+						throw new NoSuchSubscriptionException();
 					Collection<ContactId> visible = db.getVisibility(txn, g);
 					db.commitTransaction(txn);
 					return visible;
@@ -1005,8 +1021,10 @@ DatabaseCleaner.Callback {
 				try {
 					T txn = db.startTransaction();
 					try {
-						if(!db.containsContactTransport(txn, c, t))
-							throw new NoSuchContactTransportException();
+						if(!db.containsContact(txn, c))
+							throw new NoSuchContactException();
+						if(!db.containsTransport(txn, t))
+							throw new NoSuchTransportException();
 						long counter = db.incrementConnectionCounter(txn, c, t,
 								period);
 						db.commitTransaction(txn);
@@ -1032,6 +1050,8 @@ DatabaseCleaner.Callback {
 		try {
 			T txn = db.startTransaction();
 			try {
+				if(!db.containsTransport(txn, t))
+					throw new NoSuchTransportException();
 				db.mergeConfig(txn, t, c);
 				db.commitTransaction(txn);
 			} catch(DbException e) {
@@ -1050,6 +1070,8 @@ DatabaseCleaner.Callback {
 		try {
 			T txn = db.startTransaction();
 			try {
+				if(!db.containsTransport(txn, t))
+					throw new NoSuchTransportException();
 				if(!p.equals(db.getLocalProperties(txn, t))) {
 					db.mergeLocalProperties(txn, t, p);
 					changed = true;
@@ -1285,6 +1307,8 @@ DatabaseCleaner.Callback {
 					if(!db.containsContact(txn, c))
 						throw new NoSuchContactException();
 					TransportId t = a.getId();
+					if(!db.containsTransport(txn, t))
+						throw new NoSuchTransportException();
 					db.setTransportUpdateAcked(txn, c, t, a.getVersionNumber());
 					db.commitTransaction(txn);
 				} catch(DbException e) {
@@ -1368,6 +1392,8 @@ DatabaseCleaner.Callback {
 		try {
 			T txn = db.startTransaction();
 			try {
+				if(!db.containsTransport(txn, t))
+					throw new NoSuchTransportException();
 				db.removeTransport(txn, t);
 				db.commitTransaction(txn);
 			} catch(DbException e) {
@@ -1390,8 +1416,10 @@ DatabaseCleaner.Callback {
 				try {
 					T txn = db.startTransaction();
 					try {
-						if(!db.containsContactTransport(txn, c, t))
-							throw new NoSuchContactTransportException();
+						if(!db.containsContact(txn, c))
+							throw new NoSuchContactException();
+						if(!db.containsTransport(txn, t))
+							throw new NoSuchTransportException();
 						db.setConnectionWindow(txn, c, t, period, centre,
 								bitmap);
 						db.commitTransaction(txn);
@@ -1504,6 +1532,8 @@ DatabaseCleaner.Callback {
 			try {
 				T txn = db.startTransaction();
 				try {
+					if(!db.containsSubscription(txn, g))
+						throw new NoSuchSubscriptionException();
 					// Use HashSets for O(1) lookups, O(n) overall running time
 					HashSet<ContactId> newVisible =
 							new HashSet<ContactId>(visible);
@@ -1554,7 +1584,7 @@ DatabaseCleaner.Callback {
 	}
 
 	public void unsubscribe(GroupId g) throws DbException {
-		Collection<ContactId> affected = null;
+		Collection<ContactId> affected;
 		contactLock.writeLock().lock();
 		try {
 			messageLock.writeLock().lock();
@@ -1563,10 +1593,10 @@ DatabaseCleaner.Callback {
 				try {
 					T txn = db.startTransaction();
 					try {
-						if(db.containsSubscription(txn, g)) {
-							affected = db.getVisibility(txn, g);
-							db.removeSubscription(txn, g);
-						}
+						if(!db.containsSubscription(txn, g))
+							throw new NoSuchSubscriptionException();
+						affected = db.getVisibility(txn, g);
+						db.removeSubscription(txn, g);
 						db.commitTransaction(txn);
 					} catch(DbException e) {
 						db.abortTransaction(txn);
diff --git a/briar-core/src/net/sf/briar/db/JdbcDatabase.java b/briar-core/src/net/sf/briar/db/JdbcDatabase.java
index dbfcb80a56ae38a4f0c686f72aeca2841ea09dfa..36dffa2d7936e5cdccbffb292e297e979e2dcc6c 100644
--- a/briar-core/src/net/sf/briar/db/JdbcDatabase.java
+++ b/briar-core/src/net/sf/briar/db/JdbcDatabase.java
@@ -31,18 +31,18 @@ import net.sf.briar.api.db.DbClosedException;
 import net.sf.briar.api.db.DbException;
 import net.sf.briar.api.db.MessageHeader;
 import net.sf.briar.api.protocol.AuthorId;
-import net.sf.briar.api.protocol.RetentionAck;
-import net.sf.briar.api.protocol.RetentionUpdate;
 import net.sf.briar.api.protocol.Group;
 import net.sf.briar.api.protocol.GroupId;
 import net.sf.briar.api.protocol.Message;
 import net.sf.briar.api.protocol.MessageId;
+import net.sf.briar.api.protocol.RetentionAck;
+import net.sf.briar.api.protocol.RetentionUpdate;
 import net.sf.briar.api.protocol.SubscriptionAck;
 import net.sf.briar.api.protocol.SubscriptionUpdate;
 import net.sf.briar.api.protocol.TransportAck;
 import net.sf.briar.api.protocol.TransportId;
 import net.sf.briar.api.protocol.TransportUpdate;
-import net.sf.briar.api.transport.ContactTransport;
+import net.sf.briar.api.transport.Endpoint;
 import net.sf.briar.api.transport.TemporarySecret;
 import net.sf.briar.util.FileUtils;
 
@@ -268,8 +268,8 @@ abstract class JdbcDatabase implements Database<Connection> {
 					+ " ON DELETE CASCADE)";
 
 	// Locking: contact read, transport read, window
-	private static final String CREATE_CONTACT_TRANSPORTS =
-			"CREATE TABLE contactTransports"
+	private static final String CREATE_ENDPOINTS =
+			"CREATE TABLE endpoints"
 					+ " (contactId INT NOT NULL,"
 					+ " transportId HASH NOT NULL,"
 					+ " epoch BIGINT NOT NULL,"
@@ -377,7 +377,7 @@ abstract class JdbcDatabase implements Database<Connection> {
 			s.executeUpdate(insertTypeNames(CREATE_TRANSPORT_VERSIONS));
 			s.executeUpdate(insertTypeNames(CREATE_CONTACT_TRANSPORT_PROPS));
 			s.executeUpdate(insertTypeNames(CREATE_CONTACT_TRANSPORT_VERSIONS));
-			s.executeUpdate(insertTypeNames(CREATE_CONTACT_TRANSPORTS));
+			s.executeUpdate(insertTypeNames(CREATE_ENDPOINTS));
 			s.executeUpdate(insertTypeNames(CREATE_SECRETS));
 			s.close();
 		} catch(SQLException e) {
@@ -567,20 +567,19 @@ abstract class JdbcDatabase implements Database<Connection> {
 		}
 	}
 
-	public void addContactTransport(Connection txn, ContactTransport ct)
-			throws DbException {
+	public void addEndpoint(Connection txn, Endpoint ep) throws DbException {
 		PreparedStatement ps = null;
 		try {
-			String sql = "INSERT INTO contactTransports (contactId,"
-					+ " transportId, epoch, clockDiff, latency, alice)"
+			String sql = "INSERT INTO endpoints (contactId, transportId,"
+					+ " epoch, clockDiff, latency, alice)"
 					+ " VALUES (?, ?, ?, ?, ?, ?)";
 			ps = txn.prepareStatement(sql);
-			ps.setInt(1, ct.getContactId().getInt());
-			ps.setBytes(2, ct.getTransportId().getBytes());
-			ps.setLong(3, ct.getEpoch());
-			ps.setLong(4, ct.getClockDifference());
-			ps.setLong(5, ct.getLatency());
-			ps.setBoolean(6, ct.getAlice());
+			ps.setInt(1, ep.getContactId().getInt());
+			ps.setBytes(2, ep.getTransportId().getBytes());
+			ps.setLong(3, ep.getEpoch());
+			ps.setLong(4, ep.getClockDifference());
+			ps.setLong(5, ep.getLatency());
+			ps.setBoolean(6, ep.getAlice());
 			int affected = ps.executeUpdate();
 			if(affected != 1) throw new DbStateException();
 			ps.close();
@@ -873,16 +872,14 @@ abstract class JdbcDatabase implements Database<Connection> {
 		}
 	}
 
-	public boolean containsContactTransport(Connection txn, ContactId c,
-			TransportId t) throws DbException {
+	public boolean containsMessage(Connection txn, MessageId m)
+			throws DbException {
 		PreparedStatement ps = null;
 		ResultSet rs = null;
 		try {
-			String sql = "SELECT NULL FROM contactTransports"
-					+ " WHERE contactId = ? AND transportId = ?";
+			String sql = "SELECT NULL FROM messages WHERE messageId = ?";
 			ps = txn.prepareStatement(sql);
-			ps.setInt(1, c.getInt());
-			ps.setBytes(2, t.getBytes());
+			ps.setBytes(1, m.getBytes());
 			rs = ps.executeQuery();
 			boolean found = rs.next();
 			if(rs.next()) throw new DbStateException();
@@ -896,14 +893,14 @@ abstract class JdbcDatabase implements Database<Connection> {
 		}
 	}
 
-	public boolean containsMessage(Connection txn, MessageId m)
+	public boolean containsSubscription(Connection txn, GroupId g)
 			throws DbException {
 		PreparedStatement ps = null;
 		ResultSet rs = null;
 		try {
-			String sql = "SELECT NULL FROM messages WHERE messageId = ?";
+			String sql = "SELECT NULL FROM groups WHERE groupId = ?";
 			ps = txn.prepareStatement(sql);
-			ps.setBytes(1, m.getBytes());
+			ps.setBytes(1, g.getBytes());
 			rs = ps.executeQuery();
 			boolean found = rs.next();
 			if(rs.next()) throw new DbStateException();
@@ -917,14 +914,14 @@ abstract class JdbcDatabase implements Database<Connection> {
 		}
 	}
 
-	public boolean containsSubscription(Connection txn, GroupId g)
+	public boolean containsTransport(Connection txn, TransportId t)
 			throws DbException {
 		PreparedStatement ps = null;
 		ResultSet rs = null;
 		try {
-			String sql = "SELECT NULL FROM groups WHERE groupId = ?";
+			String sql = "SELECT NULL FROM transports WHERE transportId = ?";
 			ps = txn.prepareStatement(sql);
-			ps.setBytes(1, g.getBytes());
+			ps.setBytes(1, t.getBytes());
 			rs = ps.executeQuery();
 			boolean found = rs.next();
 			if(rs.next()) throw new DbStateException();
@@ -1005,17 +1002,17 @@ abstract class JdbcDatabase implements Database<Connection> {
 		}
 	}
 
-	public Collection<ContactTransport> getContactTransports(Connection txn)
+	public Collection<Endpoint> getEndpoints(Connection txn)
 			throws DbException {
 		PreparedStatement ps = null;
 		ResultSet rs = null;
 		try {
 			String sql = "SELECT contactId, transportId, epoch, clockDiff,"
 					+ " latency, alice"
-					+ " FROM contactTransports";
+					+ " FROM endpoints";
 			ps = txn.prepareStatement(sql);
 			rs = ps.executeQuery();
-			List<ContactTransport> cts = new ArrayList<ContactTransport>();
+			List<Endpoint> endpoints = new ArrayList<Endpoint>();
 			while(rs.next()) {
 				ContactId c = new ContactId(rs.getInt(1));
 				TransportId t = new TransportId(rs.getBytes(2));
@@ -1023,10 +1020,10 @@ abstract class JdbcDatabase implements Database<Connection> {
 				long clockDiff = rs.getLong(4);
 				long latency = rs.getLong(5);
 				boolean alice = rs.getBoolean(6);
-				cts.add(new ContactTransport(c, t, epoch, clockDiff, latency,
+				endpoints.add(new Endpoint(c, t, epoch, clockDiff, latency,
 						alice));
 			}
-			return Collections.unmodifiableList(cts);
+			return Collections.unmodifiableList(endpoints);
 		} catch(SQLException e) {
 			tryToClose(rs);
 			tryToClose(ps);
@@ -1556,10 +1553,10 @@ abstract class JdbcDatabase implements Database<Connection> {
 			String sql = "SELECT ct.contactId, ct.transportId, epoch,"
 					+ " clockDiff, latency, alice, period, secret, outgoing,"
 					+ " centre, bitmap"
-					+ " FROM contactTransports AS ct"
+					+ " FROM endpoints AS e"
 					+ " JOIN secrets AS s"
-					+ " ON ct.contactId = s.contactId"
-					+ " AND ct.transportId = s.transportId";
+					+ " ON e.contactId = s.contactId"
+					+ " AND e.transportId = s.transportId";
 			ps = txn.prepareStatement(sql);
 			rs = ps.executeQuery();
 			List<TemporarySecret> secrets = new ArrayList<TemporarySecret>();
diff --git a/briar-core/src/net/sf/briar/transport/KeyManagerImpl.java b/briar-core/src/net/sf/briar/transport/KeyManagerImpl.java
index b7c75a7f045d438ed415bedf0f17723743e7adfb..c928fc71cd7d8f1c9a6e8912b4f9f886517917fd 100644
--- a/briar-core/src/net/sf/briar/transport/KeyManagerImpl.java
+++ b/briar-core/src/net/sf/briar/transport/KeyManagerImpl.java
@@ -24,7 +24,7 @@ import net.sf.briar.api.db.event.DatabaseListener;
 import net.sf.briar.api.protocol.TransportId;
 import net.sf.briar.api.transport.ConnectionContext;
 import net.sf.briar.api.transport.ConnectionRecogniser;
-import net.sf.briar.api.transport.ContactTransport;
+import net.sf.briar.api.transport.Endpoint;
 import net.sf.briar.api.transport.TemporarySecret;
 import net.sf.briar.util.ByteUtils;
 
@@ -43,11 +43,11 @@ class KeyManagerImpl extends TimerTask implements KeyManager, DatabaseListener {
 	private final Clock clock;
 	private final Timer timer;
 	// Locking: this
-	private final Map<ContactTransportKey, TemporarySecret> outgoing;
+	private final Map<EndpointKey, TemporarySecret> outgoing;
 	// Locking: this
-	private final Map<ContactTransportKey, TemporarySecret> incomingOld;
+	private final Map<EndpointKey, TemporarySecret> incomingOld;
 	// Locking: this
-	private final Map<ContactTransportKey, TemporarySecret> incomingNew;
+	private final Map<EndpointKey, TemporarySecret> incomingNew;
 
 	@Inject
 	KeyManagerImpl(CryptoComponent crypto, DatabaseComponent db,
@@ -57,9 +57,9 @@ class KeyManagerImpl extends TimerTask implements KeyManager, DatabaseListener {
 		this.recogniser = recogniser;
 		this.clock = clock;
 		this.timer = timer;
-		outgoing = new HashMap<ContactTransportKey, TemporarySecret>();
-		incomingOld = new HashMap<ContactTransportKey, TemporarySecret>();
-		incomingNew = new HashMap<ContactTransportKey, TemporarySecret>();
+		outgoing = new HashMap<EndpointKey, TemporarySecret>();
+		incomingOld = new HashMap<EndpointKey, TemporarySecret>();
+		incomingNew = new HashMap<EndpointKey, TemporarySecret>();
 	}
 
 	public synchronized boolean start() {
@@ -97,7 +97,7 @@ class KeyManagerImpl extends TimerTask implements KeyManager, DatabaseListener {
 			Collection<TemporarySecret> secrets) {
 		Collection<TemporarySecret> dead = new ArrayList<TemporarySecret>();
 		for(TemporarySecret s : secrets) {
-			ContactTransportKey k = new ContactTransportKey(s);
+			EndpointKey k = new EndpointKey(s);
 			long rotationPeriod = getRotationPeriod(s);
 			long creationTime = getCreationTime(s);
 			long activationTime = creationTime + s.getClockDifference();
@@ -136,7 +136,7 @@ class KeyManagerImpl extends TimerTask implements KeyManager, DatabaseListener {
 			Collection<TemporarySecret> dead) {
 		Collection<TemporarySecret> created = new ArrayList<TemporarySecret>();
 		for(TemporarySecret s : dead) {
-			ContactTransportKey k = new ContactTransportKey(s);
+			EndpointKey k = new EndpointKey(s);
 			if(incomingNew.containsKey(k)) throw new IllegalStateException();
 			byte[] secret = s.getSecret();
 			long period = s.getPeriod();
@@ -196,8 +196,8 @@ class KeyManagerImpl extends TimerTask implements KeyManager, DatabaseListener {
 		return created;
 	}
 
-	private long getRotationPeriod(ContactTransport s) {
-		return 2 * s.getClockDifference() + s.getLatency();
+	private long getRotationPeriod(Endpoint ep) {
+		return 2 * ep.getClockDifference() + ep.getLatency();
 	}
 
 	private long getCreationTime(TemporarySecret s) {
@@ -221,7 +221,7 @@ class KeyManagerImpl extends TimerTask implements KeyManager, DatabaseListener {
 
 	public synchronized ConnectionContext getConnectionContext(ContactId c,
 			TransportId t) {
-		TemporarySecret s = outgoing.get(new ContactTransportKey(c, t));
+		TemporarySecret s = outgoing.get(new EndpointKey(c, t));
 		if(s == null) return null;
 		long connection;
 		try {
@@ -234,11 +234,10 @@ class KeyManagerImpl extends TimerTask implements KeyManager, DatabaseListener {
 		return new ConnectionContext(c, t, secret, connection, s.getAlice());
 	}
 
-	public synchronized void contactTransportAdded(ContactTransport ct,
-			byte[] initialSecret) {		
+	public synchronized void endpointAdded(Endpoint ep, byte[] initialSecret) {		
 		long now = clock.currentTimeMillis();
-		long rotationPeriod = getRotationPeriod(ct);
-		long elapsed = now - ct.getEpoch();
+		long rotationPeriod = getRotationPeriod(ep);
+		long elapsed = now - ep.getEpoch();
 		long currentPeriod = elapsed / rotationPeriod;
 		if(currentPeriod < 1) throw new IllegalArgumentException();
 		// Derive the two current incoming secrets
@@ -251,15 +250,15 @@ class KeyManagerImpl extends TimerTask implements KeyManager, DatabaseListener {
 		}
 		secret2 = crypto.deriveNextSecret(secret1, currentPeriod);
 		// One of the incoming secrets is the current outgoing secret
-		ContactTransportKey k = new ContactTransportKey(ct);
+		EndpointKey k = new EndpointKey(ep);
 		TemporarySecret s1, s2, dupe;
-		s1 = new TemporarySecret(ct, currentPeriod - 1, secret1);
+		s1 = new TemporarySecret(ep, currentPeriod - 1, secret1);
 		dupe = incomingOld.put(k, s1);
 		if(dupe != null) throw new IllegalStateException();
-		s2 = new TemporarySecret(ct, currentPeriod, secret2);
+		s2 = new TemporarySecret(ep, currentPeriod, secret2);
 		dupe = incomingNew.put(k, s2);
 		if(dupe != null) throw new IllegalStateException();
-		if(elapsed % rotationPeriod < ct.getClockDifference()) {
+		if(elapsed % rotationPeriod < ep.getClockDifference()) {
 			// The outgoing secret is the newer incoming secret
 			dupe = outgoing.put(k, s2);
 			if(dupe != null) throw new IllegalStateException();
@@ -338,18 +337,17 @@ class KeyManagerImpl extends TimerTask implements KeyManager, DatabaseListener {
 		}
 	}
 
-	private static class ContactTransportKey {
+	private static class EndpointKey {
 
 		private final ContactId contactId;
 		private final TransportId transportId;
 
-		private ContactTransportKey(ContactId contactId,
-				TransportId transportId) {
+		private EndpointKey(ContactId contactId, TransportId transportId) {
 			this.contactId = contactId;
 			this.transportId = transportId;
 		}
 
-		private ContactTransportKey(ContactTransport ct) {
+		private EndpointKey(Endpoint ct) {
 			this(ct.getContactId(), ct.getTransportId());
 		}
 
@@ -360,8 +358,8 @@ class KeyManagerImpl extends TimerTask implements KeyManager, DatabaseListener {
 
 		@Override
 		public boolean equals(Object o) {
-			if(o instanceof ContactTransportKey) {
-				ContactTransportKey k = (ContactTransportKey) o;
+			if(o instanceof EndpointKey) {
+				EndpointKey k = (EndpointKey) o;
 				return contactId.equals(k.contactId) &&
 						transportId.equals(k.transportId);
 			}
diff --git a/briar-tests/src/net/sf/briar/db/DatabaseComponentTest.java b/briar-tests/src/net/sf/briar/db/DatabaseComponentTest.java
index dfe7f39165bfb7a115e3ff46fe1b9bb6d9fc6697..448f0879cbb7da802e48af2e8fd7b09f7801ade7 100644
--- a/briar-tests/src/net/sf/briar/db/DatabaseComponentTest.java
+++ b/briar-tests/src/net/sf/briar/db/DatabaseComponentTest.java
@@ -13,7 +13,7 @@ import net.sf.briar.api.Rating;
 import net.sf.briar.api.TransportProperties;
 import net.sf.briar.api.db.DatabaseComponent;
 import net.sf.briar.api.db.NoSuchContactException;
-import net.sf.briar.api.db.NoSuchContactTransportException;
+import net.sf.briar.api.db.NoSuchTransportException;
 import net.sf.briar.api.db.event.ContactAddedEvent;
 import net.sf.briar.api.db.event.ContactRemovedEvent;
 import net.sf.briar.api.db.event.DatabaseListener;
@@ -33,7 +33,7 @@ import net.sf.briar.api.protocol.SubscriptionUpdate;
 import net.sf.briar.api.protocol.Transport;
 import net.sf.briar.api.protocol.TransportId;
 import net.sf.briar.api.protocol.TransportUpdate;
-import net.sf.briar.api.transport.ContactTransport;
+import net.sf.briar.api.transport.Endpoint;
 import net.sf.briar.api.transport.TemporarySecret;
 
 import org.jmock.Expectations;
@@ -55,7 +55,7 @@ public abstract class DatabaseComponentTest extends BriarTestCase {
 	private final Group group;
 	private final TransportId transportId;
 	private final Collection<Transport> transports;
-	private final ContactTransport contactTransport;
+	private final Endpoint contactTransport;
 	private final TemporarySecret temporarySecret;
 
 	public DatabaseComponentTest() {
@@ -79,7 +79,7 @@ public abstract class DatabaseComponentTest extends BriarTestCase {
 				Collections.singletonMap("foo", "bar"));
 		Transport transport = new Transport(transportId, properties);
 		transports = Collections.singletonList(transport);
-		contactTransport = new ContactTransport(contactId, transportId, 123L,
+		contactTransport = new Endpoint(contactId, transportId, 123L,
 				234L, 345L, true);
 		temporarySecret = new TemporarySecret(contactId, transportId, 1L, 2L,
 				3L, false, 4L, new byte[32], 5L, 6L, new byte[4]);
@@ -494,7 +494,7 @@ public abstract class DatabaseComponentTest extends BriarTestCase {
 				shutdown);
 
 		try {
-			db.addContactTransport(contactTransport);
+			db.addEndpoint(contactTransport);
 			fail();
 		} catch(NoSuchContactException expected) {}
 
@@ -589,7 +589,7 @@ public abstract class DatabaseComponentTest extends BriarTestCase {
 			// Check whether the contact transport is in the DB (which it's not)
 			exactly(2).of(database).startTransaction();
 			will(returnValue(txn));
-			exactly(2).of(database).containsContactTransport(txn, contactId,
+			exactly(2).of(database).containsEndpoint(txn, contactId,
 					transportId);
 			will(returnValue(false));
 			exactly(2).of(database).abortTransaction(txn);
@@ -600,12 +600,12 @@ public abstract class DatabaseComponentTest extends BriarTestCase {
 		try {
 			db.incrementConnectionCounter(contactId, transportId, 0L);
 			fail();
-		} catch(NoSuchContactTransportException expected) {}
+		} catch(NoSuchTransportException expected) {}
 
 		try {
 			db.setConnectionWindow(contactId, transportId, 0L, 0L, new byte[4]);
 			fail();
-		} catch(NoSuchContactTransportException expected) {}
+		} catch(NoSuchTransportException expected) {}
 
 		context.assertIsSatisfied();
 	}
@@ -1427,7 +1427,7 @@ public abstract class DatabaseComponentTest extends BriarTestCase {
 			// addSecrets()
 			oneOf(database).startTransaction();
 			will(returnValue(txn));
-			oneOf(database).containsContactTransport(txn, contactId,
+			oneOf(database).containsEndpoint(txn, contactId,
 					transportId);
 			will(returnValue(true));
 			oneOf(database).addSecrets(txn,
diff --git a/briar-tests/src/net/sf/briar/db/H2DatabaseTest.java b/briar-tests/src/net/sf/briar/db/H2DatabaseTest.java
index 8e9a2c23b074abd072c0c200894d15785086971e..433215c78ad72edacc97d61cc1444933e5734cc5 100644
--- a/briar-tests/src/net/sf/briar/db/H2DatabaseTest.java
+++ b/briar-tests/src/net/sf/briar/db/H2DatabaseTest.java
@@ -35,7 +35,7 @@ import net.sf.briar.api.protocol.Message;
 import net.sf.briar.api.protocol.MessageId;
 import net.sf.briar.api.protocol.Transport;
 import net.sf.briar.api.protocol.TransportId;
-import net.sf.briar.api.transport.ContactTransport;
+import net.sf.briar.api.transport.Endpoint;
 import net.sf.briar.api.transport.TemporarySecret;
 
 import org.apache.commons.io.FileSystemUtils;
@@ -1562,7 +1562,7 @@ public class H2DatabaseTest extends BriarTestCase {
 		long outgoing1 = 456L, centre1 = 567L;
 		long outgoing2 = 678L, centre2 = 789L;
 		long outgoing3 = 890L, centre3 = 901L;
-		ContactTransport ct = new ContactTransport(contactId, transportId,
+		Endpoint ct = new Endpoint(contactId, transportId,
 				epoch, clockDiff, latency, alice);
 		Random random = new Random();
 		byte[] secret1 = new byte[32], bitmap1 = new byte[4];
@@ -1592,7 +1592,7 @@ public class H2DatabaseTest extends BriarTestCase {
 
 		// Add the contact transport and the first two secrets
 		assertEquals(contactId, db.addContact(txn));
-		db.addContactTransport(txn, ct);
+		db.addEndpoint(txn, ct);
 		db.addSecrets(txn, Arrays.asList(s1, s2));
 
 		// Retrieve the first two secrets
@@ -1671,7 +1671,7 @@ public class H2DatabaseTest extends BriarTestCase {
 		long epoch = 123L, clockDiff = 234L, latency = 345L;
 		boolean alice = false;
 		long period = 456L, outgoing = 567L, centre = 678L;
-		ContactTransport ct = new ContactTransport(contactId, transportId,
+		Endpoint ct = new Endpoint(contactId, transportId,
 				epoch, clockDiff, latency, alice);
 		Random random = new Random();
 		byte[] secret = new byte[32], bitmap = new byte[4];
@@ -1685,7 +1685,7 @@ public class H2DatabaseTest extends BriarTestCase {
 
 		// Add the contact transport and the temporary secret
 		assertEquals(contactId, db.addContact(txn));
-		db.addContactTransport(txn, ct);
+		db.addEndpoint(txn, ct);
 		db.addSecrets(txn, Arrays.asList(s));
 
 		// Retrieve the secret
@@ -1726,7 +1726,7 @@ public class H2DatabaseTest extends BriarTestCase {
 		long epoch = 123L, clockDiff = 234L, latency = 345L;
 		boolean alice = false;
 		long period = 456L, outgoing = 567L, centre = 678L;
-		ContactTransport ct = new ContactTransport(contactId, transportId,
+		Endpoint ct = new Endpoint(contactId, transportId,
 				epoch, clockDiff, latency, alice);
 		Random random = new Random();
 		byte[] secret = new byte[32], bitmap = new byte[4];
@@ -1740,7 +1740,7 @@ public class H2DatabaseTest extends BriarTestCase {
 
 		// Add the contact transport and the temporary secret
 		assertEquals(contactId, db.addContact(txn));
-		db.addContactTransport(txn, ct);
+		db.addEndpoint(txn, ct);
 		db.addSecrets(txn, Arrays.asList(s));
 
 		// Retrieve the secret
@@ -1797,27 +1797,27 @@ public class H2DatabaseTest extends BriarTestCase {
 		boolean alice1 = true, alice2 = false;
 		TransportId transportId1 = new TransportId(TestUtils.getRandomId());
 		TransportId transportId2 = new TransportId(TestUtils.getRandomId());
-		ContactTransport ct1 = new ContactTransport(contactId, transportId1,
+		Endpoint ct1 = new Endpoint(contactId, transportId1,
 				epoch1, clockDiff1, latency1, alice1);
-		ContactTransport ct2 = new ContactTransport(contactId, transportId2,
+		Endpoint ct2 = new Endpoint(contactId, transportId2,
 				epoch2, clockDiff2, latency2, alice2);
 
 		Database<Connection> db = open(false);
 		Connection txn = db.startTransaction();
 
 		// Initially there should be no contact transports in the database
-		assertEquals(Collections.emptyList(), db.getContactTransports(txn));
+		assertEquals(Collections.emptyList(), db.getEndpoints(txn));
 
 		// Add a contact and the contact transports
 		assertEquals(contactId, db.addContact(txn));
-		db.addContactTransport(txn, ct1);
-		db.addContactTransport(txn, ct2);
+		db.addEndpoint(txn, ct1);
+		db.addEndpoint(txn, ct2);
 
 		// Retrieve the contact transports
-		Collection<ContactTransport> cts = db.getContactTransports(txn);
+		Collection<Endpoint> cts = db.getEndpoints(txn);
 		assertEquals(2, cts.size());
 		boolean foundFirst = false, foundSecond = false;
-		for(ContactTransport ct : cts) {
+		for(Endpoint ct : cts) {
 			assertEquals(contactId, ct.getContactId());
 			if(ct.getTransportId().equals(transportId1)) {
 				assertEquals(epoch1, ct.getEpoch());
@@ -1840,7 +1840,7 @@ public class H2DatabaseTest extends BriarTestCase {
 
 		// Removing the contact should remove the contact transports
 		db.removeContact(txn, contactId);
-		assertEquals(Collections.emptyList(), db.getContactTransports(txn));
+		assertEquals(Collections.emptyList(), db.getEndpoints(txn));
 
 		db.commitTransaction(txn);
 		db.close();
diff --git a/briar-tests/src/net/sf/briar/protocol/simplex/SimplexProtocolIntegrationTest.java b/briar-tests/src/net/sf/briar/protocol/simplex/SimplexProtocolIntegrationTest.java
index eea453a76800c6028fd7770a080fd1f63656bb5b..f59486243b5a262104b827ef399d6f9458ed0e01 100644
--- a/briar-tests/src/net/sf/briar/protocol/simplex/SimplexProtocolIntegrationTest.java
+++ b/briar-tests/src/net/sf/briar/protocol/simplex/SimplexProtocolIntegrationTest.java
@@ -29,7 +29,7 @@ import net.sf.briar.api.transport.ConnectionReaderFactory;
 import net.sf.briar.api.transport.ConnectionRecogniser;
 import net.sf.briar.api.transport.ConnectionRegistry;
 import net.sf.briar.api.transport.ConnectionWriterFactory;
-import net.sf.briar.api.transport.ContactTransport;
+import net.sf.briar.api.transport.Endpoint;
 import net.sf.briar.clock.ClockModule;
 import net.sf.briar.crypto.CryptoModule;
 import net.sf.briar.db.DatabaseModule;
@@ -107,10 +107,10 @@ public class SimplexProtocolIntegrationTest extends BriarTestCase {
 		km.start();
 		// Add Bob as a contact
 		ContactId contactId = db.addContact();
-		ContactTransport ct = new ContactTransport(contactId, transportId,
+		Endpoint ct = new Endpoint(contactId, transportId,
 				epoch, CLOCK_DIFFERENCE, LATENCY, true);
-		db.addContactTransport(ct);
-		km.contactTransportAdded(ct, initialSecret.clone());
+		db.addEndpoint(ct);
+		km.endpointAdded(ct, initialSecret.clone());
 		// Send Bob a message
 		String subject = "Hello";
 		byte[] body = "Hi Bob!".getBytes("UTF-8");
@@ -151,10 +151,10 @@ public class SimplexProtocolIntegrationTest extends BriarTestCase {
 		km.start();
 		// Add Alice as a contact
 		ContactId contactId = db.addContact();
-		ContactTransport ct = new ContactTransport(contactId, transportId,
+		Endpoint ct = new Endpoint(contactId, transportId,
 				epoch, CLOCK_DIFFERENCE, LATENCY, false);
-		db.addContactTransport(ct);
-		km.contactTransportAdded(ct, initialSecret.clone());
+		db.addEndpoint(ct);
+		km.endpointAdded(ct, initialSecret.clone());
 		// Set up a database listener
 		MessageListener listener = new MessageListener();
 		db.addListener(listener);