diff --git a/briar-api/src/net/sf/briar/api/clock/Clock.java b/briar-api/src/net/sf/briar/api/clock/Clock.java
index c2258c0647aee99b1b4ca0e7340e04a0dbbae01d..f78c60dc47daff86d522f137af6f4f143d066758 100644
--- a/briar-api/src/net/sf/briar/api/clock/Clock.java
+++ b/briar-api/src/net/sf/briar/api/clock/Clock.java
@@ -8,4 +8,7 @@ public interface Clock {
 
 	/** @see {@link java.lang.System#currentTimeMillis()} */
 	long currentTimeMillis();
+
+	/** @see {@link java.lang.Thread.sleep(long)} */
+	void sleep(long milliseconds) throws InterruptedException;
 }
diff --git a/briar-api/src/net/sf/briar/api/clock/SystemClock.java b/briar-api/src/net/sf/briar/api/clock/SystemClock.java
index a0610355f63b172615ccb7b5b68aad600d838689..d6fb2cdb070b167ac3153ee4f5d88267bce9267a 100644
--- a/briar-api/src/net/sf/briar/api/clock/SystemClock.java
+++ b/briar-api/src/net/sf/briar/api/clock/SystemClock.java
@@ -6,4 +6,8 @@ public class SystemClock implements Clock {
 	public long currentTimeMillis() {
 		return System.currentTimeMillis();
 	}
+
+	public void sleep(long milliseconds) throws InterruptedException {
+		Thread.sleep(milliseconds);
+	}
 }
diff --git a/briar-core/src/net/sf/briar/invitation/AliceConnector.java b/briar-core/src/net/sf/briar/invitation/AliceConnector.java
index c54ab2d3b670c91094891a71adbfe0ecdfd67e50..044c3d917a1905a30c1bec36edd1bde2f5acdd80 100644
--- a/briar-core/src/net/sf/briar/invitation/AliceConnector.java
+++ b/briar-core/src/net/sf/briar/invitation/AliceConnector.java
@@ -10,6 +10,7 @@ import java.io.OutputStream;
 import java.security.GeneralSecurityException;
 import java.util.logging.Logger;
 
+import net.sf.briar.api.clock.Clock;
 import net.sf.briar.api.crypto.CryptoComponent;
 import net.sf.briar.api.plugins.duplex.DuplexPlugin;
 import net.sf.briar.api.plugins.duplex.DuplexTransportConnection;
@@ -25,16 +26,16 @@ class AliceConnector extends Connector {
 			Logger.getLogger(AliceConnector.class.getName());
 
 	AliceConnector(CryptoComponent crypto, ReaderFactory readerFactory,
-			WriterFactory writerFactory, ConnectorGroup group,
+			WriterFactory writerFactory, Clock clock, ConnectorGroup group,
 			DuplexPlugin plugin, int localCode, int remoteCode) {
-		super(crypto, readerFactory, writerFactory, group, plugin,
+		super(crypto, readerFactory, writerFactory, clock, group, plugin,
 				crypto.getPseudoRandom(localCode, remoteCode));
 	}
 
 	@Override
 	public void run() {
 		// Try an outgoing connection first, then an incoming connection
-		long halfTime = System.currentTimeMillis() + CONNECTION_TIMEOUT;
+		long halfTime = clock.currentTimeMillis() + CONNECTION_TIMEOUT;
 		DuplexTransportConnection conn = makeOutgoingConnection();
 		if(conn == null) {
 			waitForHalfTime(halfTime);
diff --git a/briar-core/src/net/sf/briar/invitation/BobConnector.java b/briar-core/src/net/sf/briar/invitation/BobConnector.java
index fefe8335a4a8500d9351468b4477667b7681d355..cf21e24b2643ea47a7b2401a893127e14fd03e16 100644
--- a/briar-core/src/net/sf/briar/invitation/BobConnector.java
+++ b/briar-core/src/net/sf/briar/invitation/BobConnector.java
@@ -10,6 +10,7 @@ import java.io.OutputStream;
 import java.security.GeneralSecurityException;
 import java.util.logging.Logger;
 
+import net.sf.briar.api.clock.Clock;
 import net.sf.briar.api.crypto.CryptoComponent;
 import net.sf.briar.api.plugins.duplex.DuplexPlugin;
 import net.sf.briar.api.plugins.duplex.DuplexTransportConnection;
@@ -25,16 +26,16 @@ class BobConnector extends Connector {
 			Logger.getLogger(BobConnector.class.getName());
 
 	BobConnector(CryptoComponent crypto, ReaderFactory readerFactory,
-			WriterFactory writerFactory, ConnectorGroup group,
+			WriterFactory writerFactory, Clock clock, ConnectorGroup group,
 			DuplexPlugin plugin, int localCode, int remoteCode) {
-		super(crypto, readerFactory, writerFactory, group, plugin,
+		super(crypto, readerFactory, writerFactory, clock, group, plugin,
 				crypto.getPseudoRandom(remoteCode, localCode));
 	}
 
 	@Override
 	public void run() {
 		// Try an incoming connection first, then an outgoing connection
-		long halfTime = System.currentTimeMillis() + CONNECTION_TIMEOUT;
+		long halfTime = clock.currentTimeMillis() + CONNECTION_TIMEOUT;
 		DuplexTransportConnection conn = acceptIncomingConnection();
 		if(conn == null) {
 			waitForHalfTime(halfTime);
diff --git a/briar-core/src/net/sf/briar/invitation/Connector.java b/briar-core/src/net/sf/briar/invitation/Connector.java
index 501af0eddfe8c2c20f4d1375f36ad676775c3477..658b3cd401ccc92b65d173071b9aa6a3372614ec 100644
--- a/briar-core/src/net/sf/briar/invitation/Connector.java
+++ b/briar-core/src/net/sf/briar/invitation/Connector.java
@@ -2,8 +2,8 @@ package net.sf.briar.invitation;
 
 import static java.util.logging.Level.INFO;
 import static java.util.logging.Level.WARNING;
-import static net.sf.briar.api.plugins.InvitationConstants.HASH_LENGTH;
 import static net.sf.briar.api.plugins.InvitationConstants.CONNECTION_TIMEOUT;
+import static net.sf.briar.api.plugins.InvitationConstants.HASH_LENGTH;
 import static net.sf.briar.api.plugins.InvitationConstants.MAX_PUBLIC_KEY_LENGTH;
 
 import java.io.IOException;
@@ -13,6 +13,7 @@ import java.util.Arrays;
 import java.util.logging.Logger;
 
 import net.sf.briar.api.FormatException;
+import net.sf.briar.api.clock.Clock;
 import net.sf.briar.api.crypto.CryptoComponent;
 import net.sf.briar.api.crypto.KeyParser;
 import net.sf.briar.api.crypto.MessageDigest;
@@ -32,6 +33,7 @@ abstract class Connector extends Thread {
 	protected final CryptoComponent crypto;
 	protected final ReaderFactory readerFactory;
 	protected final WriterFactory writerFactory;
+	protected final Clock clock;
 	protected final ConnectorGroup group;
 	protected final DuplexPlugin plugin;
 	protected final PseudoRandom random;
@@ -42,12 +44,13 @@ abstract class Connector extends Thread {
 	private final MessageDigest messageDigest;
 
 	Connector(CryptoComponent crypto, ReaderFactory readerFactory,
-			WriterFactory writerFactory, ConnectorGroup group,
+			WriterFactory writerFactory, Clock clock, ConnectorGroup group,
 			DuplexPlugin plugin, PseudoRandom random) {
 		super("Connector");
 		this.crypto = crypto;
 		this.readerFactory = readerFactory;
 		this.writerFactory = writerFactory;
+		this.clock = clock;
 		this.group = group;
 		this.plugin = plugin;
 		this.random = random;
@@ -70,12 +73,12 @@ abstract class Connector extends Thread {
 	}
 
 	protected void waitForHalfTime(long halfTime) {
-		long now = System.currentTimeMillis();
+		long now = clock.currentTimeMillis();
 		if(now < halfTime) {
 			if(LOG.isLoggable(INFO))
 				LOG.info(pluginName + " sleeping until half-time");
 			try {
-				Thread.sleep(halfTime - now);
+				clock.sleep(halfTime - now);
 			} catch(InterruptedException e) {
 				if(LOG.isLoggable(INFO)) LOG.info("Interrupted while sleeping");
 				Thread.currentThread().interrupt();
diff --git a/briar-core/src/net/sf/briar/invitation/ConnectorGroup.java b/briar-core/src/net/sf/briar/invitation/ConnectorGroup.java
index 86352ec86491978eefdfda47b5f0026c40cb8844..50f0865c1a5eb7b3e550bfa4ce980da323a000e8 100644
--- a/briar-core/src/net/sf/briar/invitation/ConnectorGroup.java
+++ b/briar-core/src/net/sf/briar/invitation/ConnectorGroup.java
@@ -11,6 +11,7 @@ import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.logging.Logger;
 
+import net.sf.briar.api.clock.Clock;
 import net.sf.briar.api.crypto.CryptoComponent;
 import net.sf.briar.api.invitation.InvitationListener;
 import net.sf.briar.api.invitation.InvitationManager;
@@ -31,6 +32,7 @@ class ConnectorGroup extends Thread implements InvitationTask {
 	private final CryptoComponent crypto;
 	private final ReaderFactory readerFactory;
 	private final WriterFactory writerFactory;
+	private final Clock clock;
 	private final PluginManager pluginManager;
 	private final int handle, localInvitationCode, remoteInvitationCode;
 	private final Collection<InvitationListener> listeners;
@@ -50,13 +52,14 @@ class ConnectorGroup extends Thread implements InvitationTask {
 
 	ConnectorGroup(InvitationManager invitationManager, CryptoComponent crypto,
 			ReaderFactory readerFactory, WriterFactory writerFactory,
-			PluginManager pluginManager, int handle, int localInvitationCode,
-			int remoteInvitationCode) {
+			Clock clock, PluginManager pluginManager, int handle,
+			int localInvitationCode, int remoteInvitationCode) {
 		super("ConnectorGroup");
 		this.invitationManager = invitationManager;
 		this.crypto = crypto;
 		this.readerFactory = readerFactory;
 		this.writerFactory = writerFactory;
+		this.clock = clock;
 		this.pluginManager = pluginManager;
 		this.handle = handle;
 		this.localInvitationCode = localInvitationCode;
@@ -95,7 +98,7 @@ class ConnectorGroup extends Thread implements InvitationTask {
 		if(localInvitationCode < remoteInvitationCode) {
 			for(DuplexPlugin plugin : pluginManager.getInvitationPlugins()) {
 				Connector c = new AliceConnector(crypto, readerFactory,
-						writerFactory, this, plugin, localInvitationCode,
+						writerFactory, clock, this, plugin, localInvitationCode,
 						remoteInvitationCode);
 				connectors.add(c);
 				c.start();
@@ -103,7 +106,7 @@ class ConnectorGroup extends Thread implements InvitationTask {
 		} else {
 			for(DuplexPlugin plugin: pluginManager.getInvitationPlugins()) {
 				Connector c = (new BobConnector(crypto, readerFactory,
-						writerFactory, this, plugin, localInvitationCode,
+						writerFactory, clock, this, plugin, localInvitationCode,
 						remoteInvitationCode));
 				connectors.add(c);
 				c.start();
diff --git a/briar-core/src/net/sf/briar/invitation/InvitationManagerImpl.java b/briar-core/src/net/sf/briar/invitation/InvitationManagerImpl.java
index be47b398ab1bcdb69dd34348c72c6bf236266189..3de8768c1804d74ad61c83766023c145479b6a65 100644
--- a/briar-core/src/net/sf/briar/invitation/InvitationManagerImpl.java
+++ b/briar-core/src/net/sf/briar/invitation/InvitationManagerImpl.java
@@ -4,6 +4,7 @@ import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.atomic.AtomicInteger;
 
+import net.sf.briar.api.clock.Clock;
 import net.sf.briar.api.crypto.CryptoComponent;
 import net.sf.briar.api.invitation.InvitationManager;
 import net.sf.briar.api.invitation.InvitationTask;
@@ -18,6 +19,7 @@ class InvitationManagerImpl implements InvitationManager {
 	private final CryptoComponent crypto;
 	private final ReaderFactory readerFactory;
 	private final WriterFactory writerFactory;
+	private final Clock clock;
 	private final PluginManager pluginManager;
 
 	private final AtomicInteger nextHandle;
@@ -25,10 +27,12 @@ class InvitationManagerImpl implements InvitationManager {
 
 	@Inject
 	InvitationManagerImpl(CryptoComponent crypto, ReaderFactory readerFactory,
-			WriterFactory writerFactory, PluginManager pluginManager) {
+			WriterFactory writerFactory, Clock clock,
+			PluginManager pluginManager) {
 		this.crypto = crypto;
 		this.readerFactory = readerFactory;
 		this.writerFactory = writerFactory;
+		this.clock = clock;
 		this.pluginManager = pluginManager;
 		nextHandle = new AtomicInteger(0);
 		tasks = new ConcurrentHashMap<Integer, InvitationTask>();
@@ -37,7 +41,7 @@ class InvitationManagerImpl implements InvitationManager {
 	public InvitationTask createTask(int localCode, int remoteCode) {
 		int handle = nextHandle.incrementAndGet();
 		return new ConnectorGroup(this, crypto, readerFactory, writerFactory,
-				pluginManager, handle, localCode, remoteCode);
+				clock, pluginManager, handle, localCode, remoteCode);
 	}
 
 	public InvitationTask getTask(int handle) {
diff --git a/briar-core/src/net/sf/briar/plugins/PollerImpl.java b/briar-core/src/net/sf/briar/plugins/PollerImpl.java
index 29ea3c91326972e72f8bd1f8ec4a185c6c4b8f0b..204547f1c9faf2827d26e8a385574bedb1b5de73 100644
--- a/briar-core/src/net/sf/briar/plugins/PollerImpl.java
+++ b/briar-core/src/net/sf/briar/plugins/PollerImpl.java
@@ -9,6 +9,7 @@ import java.util.concurrent.ExecutorService;
 import java.util.logging.Logger;
 
 import net.sf.briar.api.ContactId;
+import net.sf.briar.api.clock.Clock;
 import net.sf.briar.api.plugins.Plugin;
 import net.sf.briar.api.plugins.PluginExecutor;
 import net.sf.briar.api.transport.ConnectionRegistry;
@@ -22,13 +23,15 @@ class PollerImpl implements Poller, Runnable {
 
 	private final ExecutorService pluginExecutor;
 	private final ConnectionRegistry connRegistry;
+	private final Clock clock;
 	private final SortedSet<PollTime> pollTimes;
 
 	@Inject
 	PollerImpl(@PluginExecutor ExecutorService pluginExecutor,
-			ConnectionRegistry connRegistry) {
+			ConnectionRegistry connRegistry, Clock clock) {
 		this.pluginExecutor = pluginExecutor;
 		this.connRegistry = connRegistry;
+		this.clock = clock;
 		pollTimes = new TreeSet<PollTime>();
 	}
 
@@ -39,7 +42,7 @@ class PollerImpl implements Poller, Runnable {
 
 	private synchronized void schedule(Plugin plugin) {
 		if(plugin.shouldPoll()) {
-			long now = System.currentTimeMillis();
+			long now = clock.currentTimeMillis();
 			long interval = plugin.getPollingInterval();
 			pollTimes.add(new PollTime(now + interval, plugin));
 		}
@@ -57,7 +60,7 @@ class PollerImpl implements Poller, Runnable {
 					if(LOG.isLoggable(INFO)) LOG.info("Finished polling");
 					return;
 				}
-				long now = System.currentTimeMillis();
+				long now = clock.currentTimeMillis();
 				final PollTime p = pollTimes.first();
 				if(now >= p.time) {
 					boolean removed = pollTimes.remove(p);
diff --git a/briar-core/src/net/sf/briar/plugins/bluetooth/BluetoothPluginFactory.java b/briar-core/src/net/sf/briar/plugins/bluetooth/BluetoothPluginFactory.java
index 86f721a17ebdfda8653381bd423e5fee85eac464..94fbdd06a0bf34e3040746fdf7db0acd1b91b31f 100644
--- a/briar-core/src/net/sf/briar/plugins/bluetooth/BluetoothPluginFactory.java
+++ b/briar-core/src/net/sf/briar/plugins/bluetooth/BluetoothPluginFactory.java
@@ -2,6 +2,7 @@ package net.sf.briar.plugins.bluetooth;
 
 import java.util.concurrent.Executor;
 
+import net.sf.briar.api.clock.Clock;
 import net.sf.briar.api.clock.SystemClock;
 import net.sf.briar.api.plugins.PluginExecutor;
 import net.sf.briar.api.plugins.duplex.DuplexPlugin;
@@ -14,9 +15,11 @@ public class BluetoothPluginFactory implements DuplexPluginFactory {
 	private static final long POLLING_INTERVAL = 3L * 60L * 1000L; // 3 mins
 
 	private final Executor pluginExecutor;
+	private final Clock clock;
 
 	public BluetoothPluginFactory(@PluginExecutor Executor pluginExecutor) {
 		this.pluginExecutor = pluginExecutor;
+		clock = new SystemClock();
 	}
 
 	public TransportId getId() {
@@ -24,7 +27,7 @@ public class BluetoothPluginFactory implements DuplexPluginFactory {
 	}
 
 	public DuplexPlugin createPlugin(DuplexPluginCallback callback) {
-		return new BluetoothPlugin(pluginExecutor, new SystemClock(), callback,
+		return new BluetoothPlugin(pluginExecutor, clock, callback,
 				POLLING_INTERVAL);
 	}
 }
diff --git a/briar-core/src/net/sf/briar/plugins/modem/ModemFactoryImpl.java b/briar-core/src/net/sf/briar/plugins/modem/ModemFactoryImpl.java
index 13ae3084807828a3b7105d1830acacf934b72946..e51498c458616be5fa5535342d80f95a275adfb9 100644
--- a/briar-core/src/net/sf/briar/plugins/modem/ModemFactoryImpl.java
+++ b/briar-core/src/net/sf/briar/plugins/modem/ModemFactoryImpl.java
@@ -2,20 +2,25 @@ package net.sf.briar.plugins.modem;
 
 import java.util.concurrent.Executor;
 
+import net.sf.briar.api.clock.Clock;
+import net.sf.briar.api.clock.SystemClock;
 import net.sf.briar.api.reliability.ReliabilityLayerFactory;
 
 class ModemFactoryImpl implements ModemFactory {
 
 	private final Executor executor;
 	private final ReliabilityLayerFactory reliabilityFactory;
+	private final Clock clock;
 
 	ModemFactoryImpl(Executor executor,
 			ReliabilityLayerFactory reliabilityFactory) {
 		this.executor = executor;
 		this.reliabilityFactory = reliabilityFactory;
+		clock = new SystemClock();
 	}
 
 	public Modem createModem(Modem.Callback callback, String portName) {
-		return new ModemImpl(executor, reliabilityFactory, callback, portName);
+		return new ModemImpl(executor, reliabilityFactory, clock, callback,
+				portName);
 	}
 }
diff --git a/briar-core/src/net/sf/briar/plugins/modem/ModemImpl.java b/briar-core/src/net/sf/briar/plugins/modem/ModemImpl.java
index 79731773b0d9193db5cda81a500c69f004560c7c..d227965bbfe0568256f06e9bc566bcade06d302b 100644
--- a/briar-core/src/net/sf/briar/plugins/modem/ModemImpl.java
+++ b/briar-core/src/net/sf/briar/plugins/modem/ModemImpl.java
@@ -12,14 +12,14 @@ import java.util.concurrent.Executor;
 import java.util.concurrent.Semaphore;
 import java.util.logging.Logger;
 
-import net.sf.briar.api.reliability.ReliabilityLayer;
-import net.sf.briar.api.reliability.ReliabilityLayerFactory;
-import net.sf.briar.api.reliability.WriteHandler;
-
 import jssc.SerialPort;
 import jssc.SerialPortEvent;
 import jssc.SerialPortEventListener;
 import jssc.SerialPortException;
+import net.sf.briar.api.clock.Clock;
+import net.sf.briar.api.reliability.ReliabilityLayer;
+import net.sf.briar.api.reliability.ReliabilityLayerFactory;
+import net.sf.briar.api.reliability.WriteHandler;
 
 class ModemImpl implements Modem, WriteHandler, SerialPortEventListener {
 
@@ -35,6 +35,7 @@ class ModemImpl implements Modem, WriteHandler, SerialPortEventListener {
 
 	private final Executor executor;
 	private final ReliabilityLayerFactory reliabilityFactory;
+	private final Clock clock;
 	private final Callback callback;
 	private final SerialPort port;
 	private final Semaphore stateChange;
@@ -46,9 +47,10 @@ class ModemImpl implements Modem, WriteHandler, SerialPortEventListener {
 	private boolean initialised = false, connected = false; // Locking: this
 
 	ModemImpl(Executor executor, ReliabilityLayerFactory reliabilityFactory,
-			Callback callback, String portName) {
+			Clock clock, Callback callback, String portName) {
 		this.executor = executor;
 		this.reliabilityFactory = reliabilityFactory;
+		this.clock = clock;
 		this.callback = callback;
 		port = new SerialPort(portName);
 		stateChange = new Semaphore(1);
@@ -96,11 +98,11 @@ class ModemImpl implements Modem, WriteHandler, SerialPortEventListener {
 			boolean success = false;
 			try {
 				synchronized(this) {
-					long now = System.currentTimeMillis();
+					long now = clock.currentTimeMillis();
 					long end = now + OK_TIMEOUT;
 					while(now < end && !initialised) {
 						wait(end - now);
-						now = System.currentTimeMillis();
+						now = clock.currentTimeMillis();
 					}
 					success = initialised;
 				}
@@ -169,9 +171,9 @@ class ModemImpl implements Modem, WriteHandler, SerialPortEventListener {
 		reliability.stop();
 		if(LOG.isLoggable(INFO)) LOG.info("Hanging up");
 		try {
-			Thread.sleep(ESCAPE_SEQUENCE_GUARD_TIME);
+			clock.sleep(ESCAPE_SEQUENCE_GUARD_TIME);
 			port.writeBytes("+++".getBytes("US-ASCII"));
-			Thread.sleep(ESCAPE_SEQUENCE_GUARD_TIME);
+			clock.sleep(ESCAPE_SEQUENCE_GUARD_TIME);
 			port.writeBytes("ATH\r\n".getBytes("US-ASCII"));
 		} catch(InterruptedException e) {
 			tryToClose(port);
@@ -217,11 +219,11 @@ class ModemImpl implements Modem, WriteHandler, SerialPortEventListener {
 			// Wait for the event thread to receive "CONNECT"
 			try {
 				synchronized(this) {
-					long now = System.currentTimeMillis();
+					long now = clock.currentTimeMillis();
 					long end = now + CONNECT_TIMEOUT;
 					while(now < end && initialised && !connected) {
 						wait(end - now);
-						now = System.currentTimeMillis();
+						now = clock.currentTimeMillis();
 					}
 					if(connected) return true;
 				}
@@ -397,11 +399,11 @@ class ModemImpl implements Modem, WriteHandler, SerialPortEventListener {
 			boolean success = false;
 			try {
 				synchronized(this) {
-					long now = System.currentTimeMillis();
+					long now = clock.currentTimeMillis();
 					long end = now + CONNECT_TIMEOUT;
 					while(now < end && initialised && !connected) {
 						wait(end - now);
-						now = System.currentTimeMillis();
+						now = clock.currentTimeMillis();
 					}
 					success = connected;
 				}
diff --git a/briar-core/src/net/sf/briar/plugins/tcp/LanTcpPlugin.java b/briar-core/src/net/sf/briar/plugins/tcp/LanTcpPlugin.java
index 6812c7236c4ca9dd902f43f037e22e75686a8b5a..0d9350006a11c975e1be9293d0c50d52155c9f09 100644
--- a/briar-core/src/net/sf/briar/plugins/tcp/LanTcpPlugin.java
+++ b/briar-core/src/net/sf/briar/plugins/tcp/LanTcpPlugin.java
@@ -22,6 +22,7 @@ import java.util.concurrent.Executor;
 import java.util.logging.Logger;
 
 import net.sf.briar.api.TransportProperties;
+import net.sf.briar.api.clock.Clock;
 import net.sf.briar.api.crypto.PseudoRandom;
 import net.sf.briar.api.plugins.PluginExecutor;
 import net.sf.briar.api.plugins.duplex.DuplexPluginCallback;
@@ -42,9 +43,12 @@ class LanTcpPlugin extends TcpPlugin {
 	private static final Logger LOG =
 			Logger.getLogger(LanTcpPlugin.class.getName());
 
-	LanTcpPlugin(@PluginExecutor Executor pluginExecutor,
+	private final Clock clock;
+
+	LanTcpPlugin(@PluginExecutor Executor pluginExecutor, Clock clock,
 			DuplexPluginCallback callback, long pollingInterval) {
 		super(pluginExecutor, callback, pollingInterval);
+		this.clock = clock;
 	}
 
 	public TransportId getId() {
@@ -130,7 +134,7 @@ class LanTcpPlugin extends TcpPlugin {
 		// Listen until a valid packet is received or the timeout occurs
 		byte[] buffer = new byte[2];
 		DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
-		long now = System.currentTimeMillis();
+		long now = clock.currentTimeMillis();
 		long end = now + timeout;
 		try {
 			while(now < end) {
@@ -155,7 +159,7 @@ class LanTcpPlugin extends TcpPlugin {
 				} catch(SocketTimeoutException e) {
 					break;
 				}
-				now = System.currentTimeMillis();
+				now = clock.currentTimeMillis();
 				if(!running) return null;
 			}
 			if(LOG.isLoggable(INFO))
@@ -273,7 +277,7 @@ class LanTcpPlugin extends TcpPlugin {
 		DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
 		packet.setAddress(mcast.getAddress());
 		packet.setPort(mcast.getPort());
-		long now = System.currentTimeMillis();
+		long now = clock.currentTimeMillis();
 		long end = now + timeout;
 		long interval = 1000;
 		long nextPacket = now + 1;
@@ -286,10 +290,10 @@ class LanTcpPlugin extends TcpPlugin {
 					s.setSoTimeout(0);
 					return new TcpTransportConnection(s);
 				} catch(SocketTimeoutException e) {
-					now = System.currentTimeMillis();
+					now = clock.currentTimeMillis();
 					if(now < end) {
 						ms.send(packet);
-						now = System.currentTimeMillis();
+						now = clock.currentTimeMillis();
 						nextPacket = now + interval;
 						interval += 1000;
 					}
diff --git a/briar-core/src/net/sf/briar/plugins/tcp/LanTcpPluginFactory.java b/briar-core/src/net/sf/briar/plugins/tcp/LanTcpPluginFactory.java
index 81aa97848e35bbe5a374f563822fb868385b2703..8c938e2c3043db84c1f79d38da4a70dee92cd0ae 100644
--- a/briar-core/src/net/sf/briar/plugins/tcp/LanTcpPluginFactory.java
+++ b/briar-core/src/net/sf/briar/plugins/tcp/LanTcpPluginFactory.java
@@ -2,6 +2,8 @@ package net.sf.briar.plugins.tcp;
 
 import java.util.concurrent.Executor;
 
+import net.sf.briar.api.clock.Clock;
+import net.sf.briar.api.clock.SystemClock;
 import net.sf.briar.api.plugins.PluginExecutor;
 import net.sf.briar.api.plugins.duplex.DuplexPlugin;
 import net.sf.briar.api.plugins.duplex.DuplexPluginCallback;
@@ -13,9 +15,11 @@ public class LanTcpPluginFactory implements DuplexPluginFactory {
 	private static final long POLLING_INTERVAL = 60L * 1000L; // 1 minute
 
 	private final Executor pluginExecutor;
+	private final Clock clock;
 
 	public LanTcpPluginFactory(@PluginExecutor Executor pluginExecutor) {
 		this.pluginExecutor = pluginExecutor;
+		clock = new SystemClock();
 	}
 
 	public TransportId getId() {
@@ -23,6 +27,7 @@ public class LanTcpPluginFactory implements DuplexPluginFactory {
 	}
 
 	public DuplexPlugin createPlugin(DuplexPluginCallback callback) {
-		return new LanTcpPlugin(pluginExecutor, callback, POLLING_INTERVAL);
+		return new LanTcpPlugin(pluginExecutor, clock, callback,
+				POLLING_INTERVAL);
 	}
 }
diff --git a/briar-core/src/net/sf/briar/protocol/MessageFactoryImpl.java b/briar-core/src/net/sf/briar/protocol/MessageFactoryImpl.java
index 28406fd6b61243ea57a7e8fe1323001588054c12..85ce10b49f043128e8e7824fa8ecb37607d136a5 100644
--- a/briar-core/src/net/sf/briar/protocol/MessageFactoryImpl.java
+++ b/briar-core/src/net/sf/briar/protocol/MessageFactoryImpl.java
@@ -13,6 +13,7 @@ import java.security.PrivateKey;
 import java.security.SecureRandom;
 import java.security.Signature;
 
+import net.sf.briar.api.clock.Clock;
 import net.sf.briar.api.crypto.CryptoComponent;
 import net.sf.briar.api.crypto.MessageDigest;
 import net.sf.briar.api.protocol.Author;
@@ -38,14 +39,17 @@ class MessageFactoryImpl implements MessageFactory {
 	private final SecureRandom random;
 	private final MessageDigest messageDigest;
 	private final WriterFactory writerFactory;
+	private final Clock clock;
 
 	@Inject
-	MessageFactoryImpl(CryptoComponent crypto, WriterFactory writerFactory) {
+	MessageFactoryImpl(CryptoComponent crypto, WriterFactory writerFactory,
+			Clock clock) {
 		authorSignature = crypto.getSignature();
 		groupSignature = crypto.getSignature();
 		random = crypto.getSecureRandom();
 		messageDigest = crypto.getMessageDigest();
 		this.writerFactory = writerFactory;
+		this.clock = clock;
 	}
 
 	public Message createMessage(MessageId parent, String subject, byte[] body)
@@ -115,7 +119,7 @@ class MessageFactoryImpl implements MessageFactory {
 		if(author == null) w.writeNull();
 		else writeAuthor(w, author);
 		w.writeString(subject);
-		long timestamp = System.currentTimeMillis();
+		long timestamp = clock.currentTimeMillis();
 		w.writeInt64(timestamp);
 		byte[] salt = new byte[SALT_LENGTH];
 		random.nextBytes(salt);
diff --git a/briar-core/src/net/sf/briar/reliability/Receiver.java b/briar-core/src/net/sf/briar/reliability/Receiver.java
index 9072dbba312b20d62591cc147b44451b5e1eb08c..de630fc31017604cd62866f19338a416694fa99b 100644
--- a/briar-core/src/net/sf/briar/reliability/Receiver.java
+++ b/briar-core/src/net/sf/briar/reliability/Receiver.java
@@ -6,6 +6,7 @@ import java.util.Iterator;
 import java.util.SortedSet;
 import java.util.TreeSet;
 
+import net.sf.briar.api.clock.Clock;
 import net.sf.briar.api.reliability.ReadHandler;
 
 class Receiver implements ReadHandler {
@@ -13,6 +14,7 @@ class Receiver implements ReadHandler {
 	private static final int READ_TIMEOUT = 5 * 60 * 1000; // Milliseconds
 	private static final int MAX_WINDOW_SIZE = 8 * Data.MAX_PAYLOAD_LENGTH;
 
+	private final Clock clock;
 	private final Sender sender;
 	private final SortedSet<Data> dataFrames; // Locking: this
 
@@ -22,13 +24,14 @@ class Receiver implements ReadHandler {
 
 	private volatile boolean valid = true;
 
-	Receiver(Sender sender) {
+	Receiver(Clock clock, Sender sender) {
 		this.sender = sender;
+		this.clock = clock;
 		dataFrames = new TreeSet<Data>(new SequenceNumberComparator());
 	}
 
 	synchronized Data read() throws IOException, InterruptedException {
-		long now = System.currentTimeMillis(), end = now + READ_TIMEOUT;
+		long now = clock.currentTimeMillis(), end = now + READ_TIMEOUT;
 		while(now < end && valid) {
 			if(dataFrames.isEmpty()) {
 				// Wait for a data frame
@@ -47,7 +50,7 @@ class Receiver implements ReadHandler {
 					wait(end - now);
 				}
 			}
-			now = System.currentTimeMillis();
+			now = clock.currentTimeMillis();
 		}
 		if(valid) throw new IOException("Read timed out");
 		throw new IOException("Connection closed");
diff --git a/briar-core/src/net/sf/briar/reliability/ReliabilityLayerFactoryImpl.java b/briar-core/src/net/sf/briar/reliability/ReliabilityLayerFactoryImpl.java
index 5d32324c6d9c520d06e844fa3f560dcb5a39b272..25437bcffc58175549e0c72870c5936fb55697ed 100644
--- a/briar-core/src/net/sf/briar/reliability/ReliabilityLayerFactoryImpl.java
+++ b/briar-core/src/net/sf/briar/reliability/ReliabilityLayerFactoryImpl.java
@@ -2,6 +2,8 @@ package net.sf.briar.reliability;
 
 import java.util.concurrent.Executor;
 
+import net.sf.briar.api.clock.Clock;
+import net.sf.briar.api.clock.SystemClock;
 import net.sf.briar.api.reliability.ReliabilityLayer;
 import net.sf.briar.api.reliability.ReliabilityLayerFactory;
 import net.sf.briar.api.reliability.WriteHandler;
@@ -9,12 +11,14 @@ import net.sf.briar.api.reliability.WriteHandler;
 class ReliabilityLayerFactoryImpl implements ReliabilityLayerFactory {
 
 	private final Executor executor;
+	private final Clock clock;
 
 	ReliabilityLayerFactoryImpl(Executor executor) {
 		this.executor = executor;
+		clock = new SystemClock();
 	}
 
 	public ReliabilityLayer createReliabilityLayer(WriteHandler writeHandler) {
-		return new ReliabilityLayerImpl(executor, writeHandler);
+		return new ReliabilityLayerImpl(executor, clock, writeHandler);
 	}
 }
diff --git a/briar-core/src/net/sf/briar/reliability/ReliabilityLayerImpl.java b/briar-core/src/net/sf/briar/reliability/ReliabilityLayerImpl.java
index 78c86ec6e708475cde7a59553292e9f4d11e6ab4..7b17ba877d1ae36ee12e458d1b69c05a2c70fcc4 100644
--- a/briar-core/src/net/sf/briar/reliability/ReliabilityLayerImpl.java
+++ b/briar-core/src/net/sf/briar/reliability/ReliabilityLayerImpl.java
@@ -11,6 +11,7 @@ import java.util.concurrent.Executor;
 import java.util.concurrent.LinkedBlockingQueue;
 import java.util.logging.Logger;
 
+import net.sf.briar.api.clock.Clock;
 import net.sf.briar.api.reliability.ReliabilityLayer;
 import net.sf.briar.api.reliability.WriteHandler;
 
@@ -22,6 +23,7 @@ class ReliabilityLayerImpl implements ReliabilityLayer, WriteHandler {
 			Logger.getLogger(ReliabilityLayerImpl.class.getName());
 
 	private final Executor executor;
+	private final Clock clock;
 	private final WriteHandler writeHandler;
 	private final BlockingQueue<byte[]> writes;
 
@@ -31,23 +33,25 @@ class ReliabilityLayerImpl implements ReliabilityLayer, WriteHandler {
 	private volatile SenderOutputStream outputStream = null;
 	private volatile boolean running = false;
 
-	ReliabilityLayerImpl(Executor executor, WriteHandler writeHandler) {
+	ReliabilityLayerImpl(Executor executor, Clock clock,
+			WriteHandler writeHandler) {
 		this.executor = executor;
+		this.clock = clock;
 		this.writeHandler = writeHandler;
 		writes = new LinkedBlockingQueue<byte[]>();
 	}
 
 	public void start() {
 		SlipEncoder encoder = new SlipEncoder(this);
-		final Sender sender = new Sender(encoder);
-		receiver = new Receiver(sender);
+		final Sender sender = new Sender(clock, encoder);
+		receiver = new Receiver(clock, sender);
 		decoder = new SlipDecoder(receiver);
 		inputStream = new ReceiverInputStream(receiver);
 		outputStream = new SenderOutputStream(sender);
 		running = true;
 		executor.execute(new Runnable() {
 			public void run() {
-				long now = System.currentTimeMillis();
+				long now = clock.currentTimeMillis();
 				long next = now + TICK_INTERVAL;
 				try {
 					while(running) {
@@ -55,7 +59,7 @@ class ReliabilityLayerImpl implements ReliabilityLayer, WriteHandler {
 						while(now < next && b == null) {
 							b = writes.poll(next - now, MILLISECONDS);
 							if(!running) return;
-							now = System.currentTimeMillis();
+							now = clock.currentTimeMillis();
 						}
 						if(b == null) {
 							sender.tick();
diff --git a/briar-core/src/net/sf/briar/reliability/Sender.java b/briar-core/src/net/sf/briar/reliability/Sender.java
index 7ae6f69f85b10db71c3b1a6935ed054fea845c3b..3208ea0fea443d0e24b03eea9eb4acebfa46f294 100644
--- a/briar-core/src/net/sf/briar/reliability/Sender.java
+++ b/briar-core/src/net/sf/briar/reliability/Sender.java
@@ -6,6 +6,7 @@ import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
 
+import net.sf.briar.api.clock.Clock;
 import net.sf.briar.api.reliability.WriteHandler;
 
 class Sender {
@@ -18,6 +19,7 @@ class Sender {
 	private static final int INITIAL_RTT_VAR = 3 * 1000;
 	private static final int MAX_WINDOW_SIZE = 64 * Data.MAX_PAYLOAD_LENGTH;
 
+	private final Clock clock;
 	private final WriteHandler writeHandler;
 	private final LinkedList<Outstanding> outstanding; // Locking: this
 
@@ -29,7 +31,8 @@ class Sender {
 	private long lastWindowUpdateOrProbe = Long.MAX_VALUE;
 	private boolean dataWaiting = false;
 
-	Sender(WriteHandler writeHandler) {
+	Sender(Clock clock, WriteHandler writeHandler) {
+		this.clock = clock;
 		this.writeHandler = writeHandler;
 		outstanding = new LinkedList<Outstanding>();
 	}
@@ -53,7 +56,7 @@ class Sender {
 			return;
 		}
 		long sequenceNumber = a.getSequenceNumber();
-		long now = System.currentTimeMillis();
+		long now = clock.currentTimeMillis();
 		Outstanding fastRetransmit = null;
 		synchronized(this) {
 			// Remove the acked data frame if it's outstanding
@@ -99,7 +102,7 @@ class Sender {
 	}
 
 	void tick() throws IOException {
-		long now = System.currentTimeMillis();
+		long now = clock.currentTimeMillis();
 		List<Outstanding> retransmit = null;
 		boolean sendProbe = false;
 		synchronized(this) {
@@ -150,15 +153,15 @@ class Sender {
 		int payloadLength = d.getPayloadLength();
 		synchronized(this) {
 			// Wait for space in the window
-			long now = System.currentTimeMillis(), end = now + WRITE_TIMEOUT;
+			long now = clock.currentTimeMillis(), end = now + WRITE_TIMEOUT;
 			while(now < end && outstandingBytes + payloadLength >= windowSize) {
 				dataWaiting = true;
 				wait(end - now);
-				now = System.currentTimeMillis();
+				now = clock.currentTimeMillis();
 			}
 			if(outstandingBytes + payloadLength >= windowSize)
 				throw new IOException("Write timed out");
-			outstanding.add(new Outstanding(d));
+			outstanding.add(new Outstanding(d, now));
 			outstandingBytes += payloadLength;
 			dataWaiting = false;
 		}
@@ -176,9 +179,9 @@ class Sender {
 		private volatile long lastTransmitted;
 		private volatile boolean retransmitted;
 
-		private Outstanding(Data data) {
+		private Outstanding(Data data, long lastTransmitted) {
 			this.data = data;
-			lastTransmitted = System.currentTimeMillis();
+			this.lastTransmitted = lastTransmitted;
 			retransmitted = false;
 		}
 	}
diff --git a/briar-core/src/net/sf/briar/transport/KeyManagerImpl.java b/briar-core/src/net/sf/briar/transport/KeyManagerImpl.java
index 998f7d684f144461c2df70f94f69bfbd178bf386..b7c75a7f045d438ed415bedf0f17723743e7adfb 100644
--- a/briar-core/src/net/sf/briar/transport/KeyManagerImpl.java
+++ b/briar-core/src/net/sf/briar/transport/KeyManagerImpl.java
@@ -12,6 +12,7 @@ import java.util.TimerTask;
 import java.util.logging.Logger;
 
 import net.sf.briar.api.ContactId;
+import net.sf.briar.api.clock.Clock;
 import net.sf.briar.api.clock.Timer;
 import net.sf.briar.api.crypto.CryptoComponent;
 import net.sf.briar.api.crypto.KeyManager;
@@ -39,6 +40,7 @@ class KeyManagerImpl extends TimerTask implements KeyManager, DatabaseListener {
 	private final CryptoComponent crypto;
 	private final DatabaseComponent db;
 	private final ConnectionRecogniser recogniser;
+	private final Clock clock;
 	private final Timer timer;
 	// Locking: this
 	private final Map<ContactTransportKey, TemporarySecret> outgoing;
@@ -49,10 +51,11 @@ class KeyManagerImpl extends TimerTask implements KeyManager, DatabaseListener {
 
 	@Inject
 	KeyManagerImpl(CryptoComponent crypto, DatabaseComponent db,
-			ConnectionRecogniser recogniser, Timer timer) {
+			ConnectionRecogniser recogniser, Clock clock, Timer timer) {
 		this.crypto = crypto;
 		this.db = db;
 		this.recogniser = recogniser;
+		this.clock = clock;
 		this.timer = timer;
 		outgoing = new HashMap<ContactTransportKey, TemporarySecret>();
 		incomingOld = new HashMap<ContactTransportKey, TemporarySecret>();
@@ -68,7 +71,7 @@ class KeyManagerImpl extends TimerTask implements KeyManager, DatabaseListener {
 			return false;
 		}
 		// Work out what phase of its lifecycle each secret is in
-		long now = System.currentTimeMillis();
+		long now = clock.currentTimeMillis();
 		Collection<TemporarySecret> dead = assignSecretsToMaps(now, secrets);
 		// Replace any dead secrets
 		Collection<TemporarySecret> created = replaceDeadSecrets(now, dead);
@@ -233,7 +236,7 @@ class KeyManagerImpl extends TimerTask implements KeyManager, DatabaseListener {
 
 	public synchronized void contactTransportAdded(ContactTransport ct,
 			byte[] initialSecret) {		
-		long now = System.currentTimeMillis();
+		long now = clock.currentTimeMillis();
 		long rotationPeriod = getRotationPeriod(ct);
 		long elapsed = now - ct.getEpoch();
 		long currentPeriod = elapsed / rotationPeriod;
@@ -288,7 +291,7 @@ class KeyManagerImpl extends TimerTask implements KeyManager, DatabaseListener {
 		incomingOld.clear();
 		incomingNew.clear();
 		// Work out what phase of its lifecycle each secret is in
-		long now = System.currentTimeMillis();
+		long now = clock.currentTimeMillis();
 		Collection<TemporarySecret> dead = assignSecretsToMaps(now, secrets);
 		// Remove any dead secrets from the recogniser
 		for(TemporarySecret s : dead) {
diff --git a/briar-tests/src/net/sf/briar/plugins/tcp/LanTcpClientTest.java b/briar-tests/src/net/sf/briar/plugins/tcp/LanTcpClientTest.java
index da1f8641da00889e4781e76bcc9ac563f1e65a8a..410339be78a9ba6a313e225abb691ebbee0975b3 100644
--- a/briar-tests/src/net/sf/briar/plugins/tcp/LanTcpClientTest.java
+++ b/briar-tests/src/net/sf/briar/plugins/tcp/LanTcpClientTest.java
@@ -9,8 +9,8 @@ import java.util.concurrent.Executors;
 import net.sf.briar.api.ContactId;
 import net.sf.briar.api.TransportConfig;
 import net.sf.briar.api.TransportProperties;
+import net.sf.briar.api.clock.SystemClock;
 import net.sf.briar.plugins.DuplexClientTest;
-import net.sf.briar.plugins.tcp.LanTcpPlugin;
 
 // This is not a JUnit test - it has to be run manually while the server test
 // is running on another machine
@@ -27,7 +27,7 @@ public class LanTcpClientTest extends DuplexClientTest {
 		// Create the plugin
 		callback = new ClientCallback(new TransportConfig(),
 				new TransportProperties(), remote);
-		plugin = new LanTcpPlugin(executor, callback, 0L);
+		plugin = new LanTcpPlugin(executor, new SystemClock(), callback, 0L);
 	}
 
 	public static void main(String[] args) throws Exception {
diff --git a/briar-tests/src/net/sf/briar/plugins/tcp/LanTcpPluginTest.java b/briar-tests/src/net/sf/briar/plugins/tcp/LanTcpPluginTest.java
index 7c2a1350fc0b3c552457fdbe0acad55510b4136b..bc4f264494baaa2753aa99b7a88af8c17142c586 100644
--- a/briar-tests/src/net/sf/briar/plugins/tcp/LanTcpPluginTest.java
+++ b/briar-tests/src/net/sf/briar/plugins/tcp/LanTcpPluginTest.java
@@ -17,10 +17,11 @@ import net.sf.briar.BriarTestCase;
 import net.sf.briar.api.ContactId;
 import net.sf.briar.api.TransportConfig;
 import net.sf.briar.api.TransportProperties;
+import net.sf.briar.api.clock.Clock;
+import net.sf.briar.api.clock.SystemClock;
 import net.sf.briar.api.plugins.duplex.DuplexPlugin;
 import net.sf.briar.api.plugins.duplex.DuplexPluginCallback;
 import net.sf.briar.api.plugins.duplex.DuplexTransportConnection;
-import net.sf.briar.plugins.tcp.LanTcpPlugin;
 
 import org.junit.Test;
 
@@ -33,8 +34,9 @@ public class LanTcpPluginTest extends BriarTestCase {
 		Callback callback = new Callback();
 		callback.local.put("address", "127.0.0.1");
 		callback.local.put("port", "0");
-		Executor e = Executors.newCachedThreadPool();
-		DuplexPlugin plugin = new LanTcpPlugin(e, callback, 0L);
+		Executor executor = Executors.newCachedThreadPool();
+		Clock clock = new SystemClock();
+		DuplexPlugin plugin = new LanTcpPlugin(executor, clock, callback, 0L);
 		plugin.start();
 		// The plugin should have bound a socket and stored the port number
 		assertTrue(callback.propertiesLatch.await(5, SECONDS));
@@ -58,8 +60,9 @@ public class LanTcpPluginTest extends BriarTestCase {
 	@Test
 	public void testOutgoingConnection() throws Exception {
 		Callback callback = new Callback();
-		Executor e = Executors.newCachedThreadPool();
-		DuplexPlugin plugin = new LanTcpPlugin(e, callback, 0L);
+		Executor executor = Executors.newCachedThreadPool();
+		Clock clock = new SystemClock();
+		DuplexPlugin plugin = new LanTcpPlugin(executor, clock, callback, 0L);
 		plugin.start();
 		// Listen on a local port
 		final ServerSocket ss = new ServerSocket();
diff --git a/briar-tests/src/net/sf/briar/plugins/tcp/LanTcpServerTest.java b/briar-tests/src/net/sf/briar/plugins/tcp/LanTcpServerTest.java
index 5efe68677d499178a1d93ba9ca13b6ed301271b8..462cfbdf79a2698700af90df3a4f7142a3a47305 100644
--- a/briar-tests/src/net/sf/briar/plugins/tcp/LanTcpServerTest.java
+++ b/briar-tests/src/net/sf/briar/plugins/tcp/LanTcpServerTest.java
@@ -7,8 +7,8 @@ import java.util.concurrent.Executors;
 
 import net.sf.briar.api.TransportConfig;
 import net.sf.briar.api.TransportProperties;
+import net.sf.briar.api.clock.SystemClock;
 import net.sf.briar.plugins.DuplexServerTest;
-import net.sf.briar.plugins.tcp.LanTcpPlugin;
 
 // This is not a JUnit test - it has to be run manually while the client test
 // is running on another machine
@@ -18,7 +18,7 @@ public class LanTcpServerTest extends DuplexServerTest {
 		callback = new ServerCallback(new TransportConfig(),
 				new TransportProperties(),
 				Collections.singletonMap(contactId, new TransportProperties()));
-		plugin = new LanTcpPlugin(executor, callback, 0L);
+		plugin = new LanTcpPlugin(executor, new SystemClock(), callback, 0L);
 	}
 
 	public static void main(String[] args) throws Exception {
diff --git a/briar-tests/src/net/sf/briar/protocol/ConstantsTest.java b/briar-tests/src/net/sf/briar/protocol/ConstantsTest.java
index 5a438af49572a63ca6cb24d734b2d809e68f474d..5f3fee3fa474c296b27835d022b9ddc03407b6e1 100644
--- a/briar-tests/src/net/sf/briar/protocol/ConstantsTest.java
+++ b/briar-tests/src/net/sf/briar/protocol/ConstantsTest.java
@@ -38,6 +38,7 @@ 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.protocol.UniqueId;
+import net.sf.briar.clock.ClockModule;
 import net.sf.briar.crypto.CryptoModule;
 import net.sf.briar.serial.SerialModule;
 
@@ -57,7 +58,7 @@ public class ConstantsTest extends BriarTestCase {
 
 	public ConstantsTest() throws Exception {
 		super();
-		Injector i = Guice.createInjector(new CryptoModule(),
+		Injector i = Guice.createInjector(new ClockModule(), new CryptoModule(),
 				new ProtocolModule(), new SerialModule());
 		crypto = i.getInstance(CryptoComponent.class);
 		groupFactory = i.getInstance(GroupFactory.class);
diff --git a/briar-tests/src/net/sf/briar/protocol/ProtocolIntegrationTest.java b/briar-tests/src/net/sf/briar/protocol/ProtocolIntegrationTest.java
index 4c939bc9c40a38a5b3e2afe0ad8f88e3415b12b8..6328c6535899fc6cdfd68c1172620183f1795769 100644
--- a/briar-tests/src/net/sf/briar/protocol/ProtocolIntegrationTest.java
+++ b/briar-tests/src/net/sf/briar/protocol/ProtocolIntegrationTest.java
@@ -29,6 +29,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.clock.ClockModule;
 import net.sf.briar.crypto.CryptoModule;
 import net.sf.briar.serial.SerialModule;
 
@@ -54,7 +55,7 @@ public class ProtocolIntegrationTest extends BriarTestCase {
 
 	public ProtocolIntegrationTest() throws Exception {
 		super();
-		Injector i = Guice.createInjector(new CryptoModule(),
+		Injector i = Guice.createInjector(new ClockModule(), new CryptoModule(),
 				new ProtocolModule(), new SerialModule());
 		readerFactory = i.getInstance(ProtocolReaderFactory.class);
 		writerFactory = i.getInstance(ProtocolWriterFactory.class);
diff --git a/briar-tests/src/net/sf/briar/protocol/ProtocolWriterImplTest.java b/briar-tests/src/net/sf/briar/protocol/ProtocolWriterImplTest.java
index 4f2343b19a38dc3fd25ffb7fa6c412642047efa8..6c916c3e56828ef502f53cddf247ad19f59b80de 100644
--- a/briar-tests/src/net/sf/briar/protocol/ProtocolWriterImplTest.java
+++ b/briar-tests/src/net/sf/briar/protocol/ProtocolWriterImplTest.java
@@ -10,6 +10,7 @@ import net.sf.briar.api.protocol.ProtocolWriter;
 import net.sf.briar.api.protocol.Request;
 import net.sf.briar.api.serial.SerialComponent;
 import net.sf.briar.api.serial.WriterFactory;
+import net.sf.briar.clock.ClockModule;
 import net.sf.briar.crypto.CryptoModule;
 import net.sf.briar.serial.SerialModule;
 import net.sf.briar.util.StringUtils;
@@ -29,7 +30,7 @@ public class ProtocolWriterImplTest extends BriarTestCase {
 
 	public ProtocolWriterImplTest() {
 		super();
-		Injector i = Guice.createInjector(new CryptoModule(),
+		Injector i = Guice.createInjector(new ClockModule(), new CryptoModule(),
 				new ProtocolModule(), new SerialModule());
 		packetFactory = i.getInstance(PacketFactory.class);
 		serial = i.getInstance(SerialComponent.class);
diff --git a/briar-tests/src/net/sf/briar/protocol/RequestReaderTest.java b/briar-tests/src/net/sf/briar/protocol/RequestReaderTest.java
index 7dc377ecd411d94ea21bf11ad17e35feadfc47c1..aee4a7e25e8e4d894bf89b912fb738e88fc04190 100644
--- a/briar-tests/src/net/sf/briar/protocol/RequestReaderTest.java
+++ b/briar-tests/src/net/sf/briar/protocol/RequestReaderTest.java
@@ -15,6 +15,7 @@ import net.sf.briar.api.serial.Reader;
 import net.sf.briar.api.serial.ReaderFactory;
 import net.sf.briar.api.serial.Writer;
 import net.sf.briar.api.serial.WriterFactory;
+import net.sf.briar.clock.ClockModule;
 import net.sf.briar.crypto.CryptoModule;
 import net.sf.briar.serial.SerialModule;
 
@@ -36,7 +37,7 @@ public class RequestReaderTest extends BriarTestCase {
 
 	public RequestReaderTest() throws Exception {
 		super();
-		Injector i = Guice.createInjector(new CryptoModule(),
+		Injector i = Guice.createInjector(new ClockModule(), new CryptoModule(),
 				new ProtocolModule(), new SerialModule());
 		readerFactory = i.getInstance(ReaderFactory.class);
 		writerFactory = i.getInstance(WriterFactory.class);