diff --git a/briar-android/res/values/roboguice.xml b/briar-android/res/values/roboguice.xml
index e1ccbebbe9f30c075d8438d47989b249cad5873d..0f6ffcd915b60127967ef02d69fd86bc8c3110db 100644
--- a/briar-android/res/values/roboguice.xml
+++ b/briar-android/res/values/roboguice.xml
@@ -9,9 +9,10 @@
 		<item>org.briarproject.messaging.MessagingModule</item>
 		<item>org.briarproject.messaging.duplex.DuplexMessagingModule</item>
 		<item>org.briarproject.messaging.simplex.SimplexMessagingModule</item>
+		<item>org.briarproject.plugins.AndroidPluginsModule</item>
 		<item>org.briarproject.plugins.PluginsModule</item>
 		<item>org.briarproject.serial.SerialModule</item>
-		<item>org.briarproject.system.SystemModule</item>
+		<item>org.briarproject.system.AndroidSystemModule</item>
 		<item>org.briarproject.transport.TransportModule</item>
 	</string-array>
 </resources>
\ No newline at end of file
diff --git a/briar-android/src/org/briarproject/android/AndroidModule.java b/briar-android/src/org/briarproject/android/AndroidModule.java
index df6bfb316c5a75d5c612712430f4249f48845852..78c7a3a5798ef711154dbc75c3960c183773e2c1 100644
--- a/briar-android/src/org/briarproject/android/AndroidModule.java
+++ b/briar-android/src/org/briarproject/android/AndroidModule.java
@@ -4,9 +4,6 @@ import static android.content.Context.MODE_PRIVATE;
 import static java.util.concurrent.TimeUnit.SECONDS;
 
 import java.io.File;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
 import java.util.concurrent.BlockingQueue;
 import java.util.concurrent.Executor;
 import java.util.concurrent.ExecutorService;
@@ -19,23 +16,11 @@ import javax.inject.Singleton;
 import org.briarproject.api.android.AndroidExecutor;
 import org.briarproject.api.android.DatabaseUiExecutor;
 import org.briarproject.api.android.ReferenceManager;
-import org.briarproject.api.crypto.CryptoComponent;
 import org.briarproject.api.db.DatabaseConfig;
 import org.briarproject.api.lifecycle.LifecycleManager;
-import org.briarproject.api.lifecycle.ShutdownManager;
-import org.briarproject.api.plugins.PluginExecutor;
-import org.briarproject.api.plugins.duplex.DuplexPluginConfig;
-import org.briarproject.api.plugins.duplex.DuplexPluginFactory;
-import org.briarproject.api.plugins.simplex.SimplexPluginConfig;
-import org.briarproject.api.plugins.simplex.SimplexPluginFactory;
-import org.briarproject.api.system.FileUtils;
 import org.briarproject.api.ui.UiCallback;
-import org.briarproject.plugins.droidtooth.DroidtoothPluginFactory;
-import org.briarproject.plugins.tcp.DroidLanTcpPluginFactory;
-import org.briarproject.plugins.tcp.WanTcpPluginFactory;
-import org.briarproject.plugins.tor.TorPluginFactory;
+
 import android.app.Application;
-import android.content.Context;
 
 import com.google.inject.AbstractModule;
 import com.google.inject.Provides;
@@ -75,7 +60,6 @@ public class AndroidModule extends AbstractModule {
 		bind(AndroidExecutor.class).to(AndroidExecutorImpl.class);
 		bind(ReferenceManager.class).to(
 				ReferenceManagerImpl.class).in(Singleton.class);
-		bind(FileUtils.class).to(AndroidFileUtils.class);
 		bind(UiCallback.class).toInstance(uiCallback);
 	}
 
@@ -85,38 +69,6 @@ public class AndroidModule extends AbstractModule {
 		return databaseUiExecutor;
 	}
 
-	@Provides
-	SimplexPluginConfig getSimplexPluginConfig() {
-		return new SimplexPluginConfig() {
-			public Collection<SimplexPluginFactory> getFactories() {
-				return Collections.emptyList();
-			}
-		};
-	}
-
-	@Provides
-	DuplexPluginConfig getDuplexPluginConfig(
-			@PluginExecutor Executor pluginExecutor,
-			AndroidExecutor androidExecutor, Context appContext,
-			CryptoComponent crypto, ShutdownManager shutdownManager) {
-		DuplexPluginFactory droidtooth = new DroidtoothPluginFactory(
-				pluginExecutor, androidExecutor, appContext,
-				crypto.getSecureRandom());
-		DuplexPluginFactory tor = new TorPluginFactory(pluginExecutor,
-				appContext, shutdownManager);
-		DuplexPluginFactory lan = new DroidLanTcpPluginFactory(pluginExecutor,
-				appContext);
-		DuplexPluginFactory wan = new WanTcpPluginFactory(pluginExecutor,
-				shutdownManager);
-		final Collection<DuplexPluginFactory> factories =
-				Arrays.asList(droidtooth, tor, lan, wan);
-		return new DuplexPluginConfig() {
-			public Collection<DuplexPluginFactory> getFactories() {
-				return factories;
-			}
-		};
-	}
-
 	@Provides @Singleton
 	DatabaseConfig getDatabaseConfig(final Application app) {
 		final File dir = app.getApplicationContext().getDir("db", MODE_PRIVATE);
diff --git a/briar-android/src/org/briarproject/plugins/AndroidPluginsModule.java b/briar-android/src/org/briarproject/plugins/AndroidPluginsModule.java
new file mode 100644
index 0000000000000000000000000000000000000000..d778a70901b0d8676fe9799d88f27abbe1ed40b9
--- /dev/null
+++ b/briar-android/src/org/briarproject/plugins/AndroidPluginsModule.java
@@ -0,0 +1,61 @@
+package org.briarproject.plugins;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.concurrent.Executor;
+
+import org.briarproject.api.android.AndroidExecutor;
+import org.briarproject.api.crypto.CryptoComponent;
+import org.briarproject.api.lifecycle.ShutdownManager;
+import org.briarproject.api.plugins.PluginExecutor;
+import org.briarproject.api.plugins.duplex.DuplexPluginConfig;
+import org.briarproject.api.plugins.duplex.DuplexPluginFactory;
+import org.briarproject.api.plugins.simplex.SimplexPluginConfig;
+import org.briarproject.api.plugins.simplex.SimplexPluginFactory;
+import org.briarproject.plugins.droidtooth.DroidtoothPluginFactory;
+import org.briarproject.plugins.tcp.DroidLanTcpPluginFactory;
+import org.briarproject.plugins.tcp.WanTcpPluginFactory;
+import org.briarproject.plugins.tor.TorPluginFactory;
+
+import android.content.Context;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.Provides;
+
+public class AndroidPluginsModule extends AbstractModule {
+
+	protected void configure() {}
+
+	@Provides
+	SimplexPluginConfig getSimplexPluginConfig() {
+		return new SimplexPluginConfig() {
+			public Collection<SimplexPluginFactory> getFactories() {
+				return Collections.emptyList();
+			}
+		};
+	}
+
+	@Provides
+	DuplexPluginConfig getDuplexPluginConfig(
+			@PluginExecutor Executor pluginExecutor,
+			AndroidExecutor androidExecutor, Context appContext,
+			CryptoComponent crypto, ShutdownManager shutdownManager) {
+		DuplexPluginFactory droidtooth = new DroidtoothPluginFactory(
+				pluginExecutor, androidExecutor, appContext,
+				crypto.getSecureRandom());
+		DuplexPluginFactory tor = new TorPluginFactory(pluginExecutor,
+				appContext, shutdownManager);
+		DuplexPluginFactory lan = new DroidLanTcpPluginFactory(pluginExecutor,
+				appContext);
+		DuplexPluginFactory wan = new WanTcpPluginFactory(pluginExecutor,
+				shutdownManager);
+		final Collection<DuplexPluginFactory> factories =
+				Arrays.asList(droidtooth, tor, lan, wan);
+		return new DuplexPluginConfig() {
+			public Collection<DuplexPluginFactory> getFactories() {
+				return factories;
+			}
+		};
+	}
+}
diff --git a/briar-android/src/org/briarproject/plugins/droidtooth/DroidtoothPluginFactory.java b/briar-android/src/org/briarproject/plugins/droidtooth/DroidtoothPluginFactory.java
index 08a44b820709d40df211e0945f0d9f99d13c7322..4015185fa300dd6056bde1bf91f1dcd32cbd580b 100644
--- a/briar-android/src/org/briarproject/plugins/droidtooth/DroidtoothPluginFactory.java
+++ b/briar-android/src/org/briarproject/plugins/droidtooth/DroidtoothPluginFactory.java
@@ -9,7 +9,8 @@ import org.briarproject.api.plugins.duplex.DuplexPlugin;
 import org.briarproject.api.plugins.duplex.DuplexPluginCallback;
 import org.briarproject.api.plugins.duplex.DuplexPluginFactory;
 import org.briarproject.api.system.Clock;
-import org.briarproject.api.system.SystemClock;
+import org.briarproject.system.SystemClock;
+
 import android.content.Context;
 
 public class DroidtoothPluginFactory implements DuplexPluginFactory {
diff --git a/briar-android/src/org/briarproject/plugins/tcp/DroidLanTcpPluginFactory.java b/briar-android/src/org/briarproject/plugins/tcp/DroidLanTcpPluginFactory.java
index b9d870fc4ad588842acfaac311b3af88dc78c8c3..70ce255bcfa3f7cd965a752b1f1069a20c05ae67 100644
--- a/briar-android/src/org/briarproject/plugins/tcp/DroidLanTcpPluginFactory.java
+++ b/briar-android/src/org/briarproject/plugins/tcp/DroidLanTcpPluginFactory.java
@@ -7,7 +7,8 @@ import org.briarproject.api.plugins.duplex.DuplexPlugin;
 import org.briarproject.api.plugins.duplex.DuplexPluginCallback;
 import org.briarproject.api.plugins.duplex.DuplexPluginFactory;
 import org.briarproject.api.system.Clock;
-import org.briarproject.api.system.SystemClock;
+import org.briarproject.system.SystemClock;
+
 import android.content.Context;
 
 public class DroidLanTcpPluginFactory implements DuplexPluginFactory {
diff --git a/briar-android/src/org/briarproject/android/AndroidFileUtils.java b/briar-android/src/org/briarproject/system/AndroidFileUtils.java
similarity index 93%
rename from briar-android/src/org/briarproject/android/AndroidFileUtils.java
rename to briar-android/src/org/briarproject/system/AndroidFileUtils.java
index 6c1f98a8a180614bc97ea820807ba92856db3be5..80efdc2a4785e208d20c195ea93d9e3562cf3bd8 100644
--- a/briar-android/src/org/briarproject/android/AndroidFileUtils.java
+++ b/briar-android/src/org/briarproject/system/AndroidFileUtils.java
@@ -1,4 +1,4 @@
-package org.briarproject.android;
+package org.briarproject.system;
 
 import java.io.File;
 import java.io.IOException;
diff --git a/briar-android/src/org/briarproject/system/AndroidSeedProvider.java b/briar-android/src/org/briarproject/system/AndroidSeedProvider.java
new file mode 100644
index 0000000000000000000000000000000000000000..3d20ee25fc70652adfe107a2e7d8607074948536
--- /dev/null
+++ b/briar-android/src/org/briarproject/system/AndroidSeedProvider.java
@@ -0,0 +1,23 @@
+package org.briarproject.system;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import android.os.Build;
+
+class AndroidSeedProvider extends LinuxSeedProvider {
+
+	@Override
+	void writeToEntropyPool(DataOutputStream out) throws IOException {
+		out.writeInt(android.os.Process.myPid());
+		out.writeInt(android.os.Process.myTid());
+		out.writeInt(android.os.Process.myUid());
+		String fingerprint = Build.FINGERPRINT;
+		if(fingerprint != null) out.writeUTF(fingerprint);
+		if(Build.VERSION.SDK_INT >= 9) {
+			String serial = Build.SERIAL;
+			if(serial != null) out.writeUTF(serial);
+		}
+		super.writeToEntropyPool(out);
+	}
+}
diff --git a/briar-core/src/org/briarproject/system/SystemModule.java b/briar-android/src/org/briarproject/system/AndroidSystemModule.java
similarity index 51%
rename from briar-core/src/org/briarproject/system/SystemModule.java
rename to briar-android/src/org/briarproject/system/AndroidSystemModule.java
index db0b92cb5456e941973fcdbc918207b0684edb50..570d4fbbc79b0fba9f7ceff17c741de14f70b0b0 100644
--- a/briar-core/src/org/briarproject/system/SystemModule.java
+++ b/briar-android/src/org/briarproject/system/AndroidSystemModule.java
@@ -1,16 +1,18 @@
 package org.briarproject.system;
 
 import org.briarproject.api.system.Clock;
-import org.briarproject.api.system.SystemClock;
-import org.briarproject.api.system.SystemTimer;
+import org.briarproject.api.system.FileUtils;
+import org.briarproject.api.system.SeedProvider;
 import org.briarproject.api.system.Timer;
 
 import com.google.inject.AbstractModule;
 
-public class SystemModule extends AbstractModule {
+public class AndroidSystemModule extends AbstractModule {
 
 	protected void configure() {
 		bind(Clock.class).to(SystemClock.class);
 		bind(Timer.class).to(SystemTimer.class);
+		bind(SeedProvider.class).to(AndroidSeedProvider.class);
+		bind(FileUtils.class).to(AndroidFileUtils.class);
 	}
 }
diff --git a/briar-api/src/org/briarproject/api/crypto/SeedProvider.java b/briar-api/src/org/briarproject/api/system/SeedProvider.java
similarity index 82%
rename from briar-api/src/org/briarproject/api/crypto/SeedProvider.java
rename to briar-api/src/org/briarproject/api/system/SeedProvider.java
index 56cc9092a230f71034f63365054beb0109b0211a..886fa2df3c397b2c40e46b98be5b36c92408a1bf 100644
--- a/briar-api/src/org/briarproject/api/crypto/SeedProvider.java
+++ b/briar-api/src/org/briarproject/api/system/SeedProvider.java
@@ -1,4 +1,4 @@
-package org.briarproject.api.crypto;
+package org.briarproject.api.system;
 
 /**
  * Uses a platform-specific source to provide a seed for a pseudo-random
diff --git a/briar-core/src/org/briarproject/crypto/CryptoComponentImpl.java b/briar-core/src/org/briarproject/crypto/CryptoComponentImpl.java
index e6d7c3cdbf97a2024f9a4ea82cdd1fc93dc00f03..49e362b67aa5c8a0a48ace7eca2846a7b13b841a 100644
--- a/briar-core/src/org/briarproject/crypto/CryptoComponentImpl.java
+++ b/briar-core/src/org/briarproject/crypto/CryptoComponentImpl.java
@@ -30,8 +30,8 @@ import org.briarproject.api.crypto.PrivateKey;
 import org.briarproject.api.crypto.PseudoRandom;
 import org.briarproject.api.crypto.PublicKey;
 import org.briarproject.api.crypto.SecretKey;
-import org.briarproject.api.crypto.SeedProvider;
 import org.briarproject.api.crypto.Signature;
+import org.briarproject.api.system.SeedProvider;
 import org.briarproject.util.ByteUtils;
 import org.spongycastle.crypto.AsymmetricCipherKeyPair;
 import org.spongycastle.crypto.BlockCipher;
diff --git a/briar-core/src/org/briarproject/crypto/CryptoModule.java b/briar-core/src/org/briarproject/crypto/CryptoModule.java
index 9d097e7e82ca2e6216549ecc6feba2d0bdd1ca71..f0eb56f05dbb57c04238392f19c9c7d8162a247e 100644
--- a/briar-core/src/org/briarproject/crypto/CryptoModule.java
+++ b/briar-core/src/org/briarproject/crypto/CryptoModule.java
@@ -14,9 +14,7 @@ import javax.inject.Singleton;
 import org.briarproject.api.crypto.CryptoComponent;
 import org.briarproject.api.crypto.CryptoExecutor;
 import org.briarproject.api.crypto.PasswordStrengthEstimator;
-import org.briarproject.api.crypto.SeedProvider;
 import org.briarproject.api.lifecycle.LifecycleManager;
-import org.briarproject.util.OsUtils;
 
 import com.google.inject.AbstractModule;
 import com.google.inject.Provides;
@@ -41,9 +39,6 @@ public class CryptoModule extends AbstractModule {
 	}
 
 	protected void configure() {
-		if(OsUtils.isAndroid() || OsUtils.isLinux()) {
-			bind(SeedProvider.class).to(LinuxSeedProvider.class);
-		}
 		bind(CryptoComponent.class).to(
 				CryptoComponentImpl.class).in(Singleton.class);
 		bind(PasswordStrengthEstimator.class).to(
diff --git a/briar-core/src/org/briarproject/crypto/LinuxSeedProvider.java b/briar-core/src/org/briarproject/crypto/LinuxSeedProvider.java
deleted file mode 100644
index 3db1cd87f502ced42e64f1b1d1bf85ec2913fdac..0000000000000000000000000000000000000000
--- a/briar-core/src/org/briarproject/crypto/LinuxSeedProvider.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package org.briarproject.crypto;
-
-import java.io.DataInputStream;
-import java.io.FileInputStream;
-import java.io.IOException;
-
-import org.briarproject.api.crypto.SeedProvider;
-
-class LinuxSeedProvider implements SeedProvider {
-
-	public byte[] getSeed() {
-		byte[] seed = new byte[SEED_BYTES];
-		try {
-			DataInputStream in =  new DataInputStream(
-					new FileInputStream("/dev/urandom"));
-			in.readFully(seed);
-			in.close();
-		} catch(IOException e) {
-			throw new RuntimeException(e);
-		}
-		return seed;
-	}
-}
diff --git a/briar-core/src/org/briarproject/db/DatabaseModule.java b/briar-core/src/org/briarproject/db/DatabaseModule.java
index 3457fc6962b2459fa4ee3ecbfb67347d1f994640..d8916a591be8f008a3ddd19ebf3aa5c535c7ec29 100644
--- a/briar-core/src/org/briarproject/db/DatabaseModule.java
+++ b/briar-core/src/org/briarproject/db/DatabaseModule.java
@@ -19,7 +19,7 @@ import org.briarproject.api.lifecycle.LifecycleManager;
 import org.briarproject.api.lifecycle.ShutdownManager;
 import org.briarproject.api.system.Clock;
 import org.briarproject.api.system.FileUtils;
-import org.briarproject.api.system.SystemClock;
+import org.briarproject.system.SystemClock;
 
 import com.google.inject.AbstractModule;
 import com.google.inject.Provides;
diff --git a/briar-core/src/org/briarproject/plugins/tcp/LanTcpPluginFactory.java b/briar-core/src/org/briarproject/plugins/tcp/LanTcpPluginFactory.java
index 502418457e8fac3a2585247edb67eb4b1c31afe6..3ce4e4af5600cf394024c912d870e994a8ebb72a 100644
--- a/briar-core/src/org/briarproject/plugins/tcp/LanTcpPluginFactory.java
+++ b/briar-core/src/org/briarproject/plugins/tcp/LanTcpPluginFactory.java
@@ -7,7 +7,7 @@ import org.briarproject.api.plugins.duplex.DuplexPlugin;
 import org.briarproject.api.plugins.duplex.DuplexPluginCallback;
 import org.briarproject.api.plugins.duplex.DuplexPluginFactory;
 import org.briarproject.api.system.Clock;
-import org.briarproject.api.system.SystemClock;
+import org.briarproject.system.SystemClock;
 
 public class LanTcpPluginFactory implements DuplexPluginFactory {
 
diff --git a/briar-core/src/org/briarproject/reliability/ReliabilityLayerFactoryImpl.java b/briar-core/src/org/briarproject/reliability/ReliabilityLayerFactoryImpl.java
index a71e42672f0a74fb64f0a0e708f1086e3ababa97..0cb3716cbf98615b897fbf5e42eee68cb2b7e8c9 100644
--- a/briar-core/src/org/briarproject/reliability/ReliabilityLayerFactoryImpl.java
+++ b/briar-core/src/org/briarproject/reliability/ReliabilityLayerFactoryImpl.java
@@ -9,7 +9,7 @@ import org.briarproject.api.reliability.ReliabilityLayer;
 import org.briarproject.api.reliability.ReliabilityLayerFactory;
 import org.briarproject.api.reliability.WriteHandler;
 import org.briarproject.api.system.Clock;
-import org.briarproject.api.system.SystemClock;
+import org.briarproject.system.SystemClock;
 
 class ReliabilityLayerFactoryImpl implements ReliabilityLayerFactory {
 
diff --git a/briar-core/src/org/briarproject/system/LinuxSeedProvider.java b/briar-core/src/org/briarproject/system/LinuxSeedProvider.java
new file mode 100644
index 0000000000000000000000000000000000000000..49645a776b34551e088769ca1555ca84a316d21f
--- /dev/null
+++ b/briar-core/src/org/briarproject/system/LinuxSeedProvider.java
@@ -0,0 +1,69 @@
+package org.briarproject.system;
+
+import static java.util.logging.Level.WARNING;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.util.Collections;
+import java.util.List;
+import java.util.logging.Logger;
+
+import org.briarproject.api.system.SeedProvider;
+
+class LinuxSeedProvider implements SeedProvider {
+
+	private static final Logger LOG =
+			Logger.getLogger(LinuxSeedProvider.class.getName());
+
+	private final String outputFile, inputFile;
+
+	LinuxSeedProvider() {
+		this("/dev/urandom", "/dev/urandom");
+	}
+
+	LinuxSeedProvider(String outputFile, String inputFile) {
+		this.outputFile = outputFile;
+		this.inputFile = inputFile;
+	}
+
+	public byte[] getSeed() {
+		byte[] seed = new byte[SEED_BYTES];
+		// Contribute whatever slightly unpredictable info we have to the pool
+		try {
+			DataOutputStream out = new DataOutputStream(
+					new FileOutputStream(outputFile));
+			writeToEntropyPool(out);
+			out.flush();
+			out.close();
+		} catch(IOException e) {
+			// On some devices /dev/urandom isn't writable - this isn't fatal
+			if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
+		}
+		// Read the seed from the pool
+		try {
+			DataInputStream in =  new DataInputStream(
+					new FileInputStream(inputFile));
+			in.readFully(seed);
+			in.close();
+		} catch(IOException e) {
+			throw new RuntimeException(e);
+		}
+		return seed;
+	}
+
+	void writeToEntropyPool(DataOutputStream out) throws IOException {
+		out.writeLong(System.currentTimeMillis());
+		out.writeLong(System.nanoTime());
+		List<NetworkInterface> ifaces =
+				Collections.list(NetworkInterface.getNetworkInterfaces());
+		for(NetworkInterface i : ifaces) {
+			List<InetAddress> addrs = Collections.list(i.getInetAddresses());
+			for(InetAddress a : addrs) out.write(a.getAddress());
+		}
+	}
+}
diff --git a/briar-api/src/org/briarproject/api/system/SystemClock.java b/briar-core/src/org/briarproject/system/SystemClock.java
similarity index 77%
rename from briar-api/src/org/briarproject/api/system/SystemClock.java
rename to briar-core/src/org/briarproject/system/SystemClock.java
index bf8c14872435a868f7a71bcdab68b53879e31898..3117b0a5035bbf779af77280d57bec0732fcc569 100644
--- a/briar-api/src/org/briarproject/api/system/SystemClock.java
+++ b/briar-core/src/org/briarproject/system/SystemClock.java
@@ -1,4 +1,6 @@
-package org.briarproject.api.system;
+package org.briarproject.system;
+
+import org.briarproject.api.system.Clock;
 
 /** Default clock implementation. */
 public class SystemClock implements Clock {
diff --git a/briar-api/src/org/briarproject/api/system/SystemTimer.java b/briar-core/src/org/briarproject/system/SystemTimer.java
similarity index 88%
rename from briar-api/src/org/briarproject/api/system/SystemTimer.java
rename to briar-core/src/org/briarproject/system/SystemTimer.java
index bbdf59674116f171b67a108d43b4d2cbb27c2fec..d1bd00735c8b232cdfe85c776872cad8dfa8d4f2 100644
--- a/briar-api/src/org/briarproject/api/system/SystemTimer.java
+++ b/briar-core/src/org/briarproject/system/SystemTimer.java
@@ -1,7 +1,9 @@
-package org.briarproject.api.system;
+package org.briarproject.system;
 
 import java.util.TimerTask;
 
+import org.briarproject.api.system.Timer;
+
 /** Default timer implementation. */
 public class SystemTimer implements Timer {
 
diff --git a/briar-desktop/src/org/briarproject/plugins/bluetooth/BluetoothPluginFactory.java b/briar-desktop/src/org/briarproject/plugins/bluetooth/BluetoothPluginFactory.java
index ad744d766b1965612c234f98882084608f59ae75..8e4963f7909e2d038fddc28681c6ea948c03e050 100644
--- a/briar-desktop/src/org/briarproject/plugins/bluetooth/BluetoothPluginFactory.java
+++ b/briar-desktop/src/org/briarproject/plugins/bluetooth/BluetoothPluginFactory.java
@@ -8,7 +8,7 @@ import org.briarproject.api.plugins.duplex.DuplexPlugin;
 import org.briarproject.api.plugins.duplex.DuplexPluginCallback;
 import org.briarproject.api.plugins.duplex.DuplexPluginFactory;
 import org.briarproject.api.system.Clock;
-import org.briarproject.api.system.SystemClock;
+import org.briarproject.system.SystemClock;
 
 public class BluetoothPluginFactory implements DuplexPluginFactory {
 
diff --git a/briar-desktop/src/org/briarproject/plugins/modem/ModemFactoryImpl.java b/briar-desktop/src/org/briarproject/plugins/modem/ModemFactoryImpl.java
index 2dc8375221b2ae3bf05f69b7d489d09fd2a08d28..892f8f541fae50ffa60e88e937bbd5e0af9c007a 100644
--- a/briar-desktop/src/org/briarproject/plugins/modem/ModemFactoryImpl.java
+++ b/briar-desktop/src/org/briarproject/plugins/modem/ModemFactoryImpl.java
@@ -4,7 +4,7 @@ import java.util.concurrent.Executor;
 
 import org.briarproject.api.reliability.ReliabilityLayerFactory;
 import org.briarproject.api.system.Clock;
-import org.briarproject.api.system.SystemClock;
+import org.briarproject.system.SystemClock;
 
 class ModemFactoryImpl implements ModemFactory {
 
diff --git a/briar-desktop/src/org/briarproject/system/DesktopOsModule.java b/briar-desktop/src/org/briarproject/system/DesktopOsModule.java
deleted file mode 100644
index 7b3c73dc287946020bb9039ce280f3ccf18087cc..0000000000000000000000000000000000000000
--- a/briar-desktop/src/org/briarproject/system/DesktopOsModule.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package org.briarproject.system;
-
-import org.briarproject.api.system.FileUtils;
-
-import com.google.inject.AbstractModule;
-
-public class DesktopOsModule extends AbstractModule {
-
-	@Override
-	protected void configure() {
-		bind(FileUtils.class).to(FileUtilsImpl.class);
-	}
-}
diff --git a/briar-desktop/src/org/briarproject/system/DesktopSystemModule.java b/briar-desktop/src/org/briarproject/system/DesktopSystemModule.java
new file mode 100644
index 0000000000000000000000000000000000000000..5a3badb9fae3fa19a9ac0094e0547271cc2f6e0f
--- /dev/null
+++ b/briar-desktop/src/org/briarproject/system/DesktopSystemModule.java
@@ -0,0 +1,27 @@
+package org.briarproject.system;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.briarproject.api.system.Clock;
+import org.briarproject.api.system.FileUtils;
+import org.briarproject.api.system.SeedProvider;
+import org.briarproject.api.system.Timer;
+import org.briarproject.util.OsUtils;
+
+import com.google.inject.AbstractModule;
+
+public class DesktopSystemModule extends AbstractModule {
+
+	protected void configure() {
+		bind(Clock.class).to(SystemClock.class);
+		bind(Timer.class).to(SystemTimer.class);
+		if(OsUtils.isLinux())
+			bind(SeedProvider.class).to(LinuxSeedProvider.class);
+		bind(FileUtils.class).toInstance(new FileUtils() {
+			public long getFreeSpace(File f) throws IOException {
+				return f.getFreeSpace();
+			}
+		});
+	}
+}
diff --git a/briar-desktop/src/org/briarproject/system/FileUtilsImpl.java b/briar-desktop/src/org/briarproject/system/FileUtilsImpl.java
deleted file mode 100644
index b22a6034fe3f63daa9a10c0d52415cba1424ebba..0000000000000000000000000000000000000000
--- a/briar-desktop/src/org/briarproject/system/FileUtilsImpl.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package org.briarproject.system;
-
-import java.io.File;
-import java.io.IOException;
-
-import org.briarproject.api.system.FileUtils;
-
-class FileUtilsImpl implements FileUtils {
-
-	public long getFreeSpace(File f) throws IOException {
-		return f.getFreeSpace();
-	}
-}
diff --git a/briar-tests/build.xml b/briar-tests/build.xml
index 01eca558d3416f42c8910407b93f6723d3d3304d..06a023d9181cbbae119773f0f2f3da64128eff7c 100644
--- a/briar-tests/build.xml
+++ b/briar-tests/build.xml
@@ -123,6 +123,7 @@
 			<test name='org.briarproject.plugins.tcp.LanTcpPluginTest'/>
 			<test name='org.briarproject.serial.ReaderImplTest'/>
 			<test name='org.briarproject.serial.WriterImplTest'/>
+			<test name='org.briarproject.system.LinuxSeedProviderTest'/>
 			<test name='org.briarproject.transport.ConnectionReaderImplTest'/>
 			<test name='org.briarproject.transport.ConnectionRegistryImplTest'/>
 			<test name='org.briarproject.transport.ConnectionWindowTest'/>
diff --git a/briar-tests/src/org/briarproject/ProtocolIntegrationTest.java b/briar-tests/src/org/briarproject/ProtocolIntegrationTest.java
index 6676679b5b29f546cc95c4b7e2335b2c134c1657..1fff6b50c091aaa81ca6fd45f7341ee242615670 100644
--- a/briar-tests/src/org/briarproject/ProtocolIntegrationTest.java
+++ b/briar-tests/src/org/briarproject/ProtocolIntegrationTest.java
@@ -48,9 +48,7 @@ import org.briarproject.messaging.duplex.DuplexMessagingModule;
 import org.briarproject.messaging.simplex.SimplexMessagingModule;
 import org.briarproject.reliability.ReliabilityModule;
 import org.briarproject.serial.SerialModule;
-import org.briarproject.system.SystemModule;
 import org.briarproject.transport.TransportModule;
-
 import org.junit.Test;
 
 import com.google.inject.Guice;
@@ -79,8 +77,8 @@ public class ProtocolIntegrationTest extends BriarTestCase {
 
 	public ProtocolIntegrationTest() throws Exception {
 		Injector i = Guice.createInjector(new TestDatabaseModule(),
-				new TestLifecycleModule(), new TestUiModule(),
-				new SystemModule(), new CryptoModule(), new DatabaseModule(),
+				new TestLifecycleModule(), new TestSystemModule(),
+				new TestUiModule(), new CryptoModule(), new DatabaseModule(),
 				new MessagingModule(), new DuplexMessagingModule(),
 				new SimplexMessagingModule(), new ReliabilityModule(),
 				new SerialModule(), new TransportModule());
diff --git a/briar-tests/src/org/briarproject/TestSeedProvider.java b/briar-tests/src/org/briarproject/TestSeedProvider.java
index 6a6ef90d91307fb404405e9df607b24eb52ddc28..aefeeda5c9daa06a7e0224b9e79f0939b2407162 100644
--- a/briar-tests/src/org/briarproject/TestSeedProvider.java
+++ b/briar-tests/src/org/briarproject/TestSeedProvider.java
@@ -2,7 +2,7 @@ package org.briarproject;
 
 import java.util.Random;
 
-import org.briarproject.api.crypto.SeedProvider;
+import org.briarproject.api.system.SeedProvider;
 
 public class TestSeedProvider implements SeedProvider {
 
diff --git a/briar-tests/src/org/briarproject/TestSystemModule.java b/briar-tests/src/org/briarproject/TestSystemModule.java
new file mode 100644
index 0000000000000000000000000000000000000000..1015deb9ec235b63492d6f8c3141740caaf5eba1
--- /dev/null
+++ b/briar-tests/src/org/briarproject/TestSystemModule.java
@@ -0,0 +1,18 @@
+package org.briarproject;
+
+import org.briarproject.api.system.Clock;
+import org.briarproject.api.system.SeedProvider;
+import org.briarproject.api.system.Timer;
+import org.briarproject.system.SystemClock;
+import org.briarproject.system.SystemTimer;
+
+import com.google.inject.AbstractModule;
+
+public class TestSystemModule extends AbstractModule {
+
+	protected void configure() {
+		bind(Clock.class).to(SystemClock.class);
+		bind(Timer.class).to(SystemTimer.class);
+		bind(SeedProvider.class).to(TestSeedProvider.class);
+	}
+}
diff --git a/briar-tests/src/org/briarproject/TestUtils.java b/briar-tests/src/org/briarproject/TestUtils.java
index de09fc35b5de49f383b7be27bb7e513259759974..4c39dec2a236a22479550d7ec96dedf09d5f6d20 100644
--- a/briar-tests/src/org/briarproject/TestUtils.java
+++ b/briar-tests/src/org/briarproject/TestUtils.java
@@ -1,15 +1,12 @@
 package org.briarproject;
 
-
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
-import java.io.InputStream;
 import java.io.PrintStream;
 import java.util.Random;
 import java.util.concurrent.atomic.AtomicInteger;
 
-import junit.framework.TestCase;
 import org.briarproject.api.UniqueId;
 
 public class TestUtils {
@@ -42,38 +39,12 @@ public class TestUtils {
 		testDir.getParentFile().delete(); // Delete if empty
 	}
 
-	public static File getBuildDirectory() {
-		File build = new File("build"); // Ant
-		if(build.exists() && build.isDirectory()) return build;
-		File bin = new File("bin"); // Eclipse
-		if(bin.exists() && bin.isDirectory()) return bin;
-		throw new RuntimeException("Could not find build directory");
-	}
-
-	public static File getFontDirectory() {
-		File f = new File("i18n");
-		if(f.exists() && f.isDirectory()) return f;
-		f = new File("../i18n");
-		if(f.exists() && f.isDirectory()) return f;
-		throw new RuntimeException("Could not find font directory");
-	}
-
 	public static byte[] getRandomId() {
 		byte[] b = new byte[UniqueId.LENGTH];
 		random.nextBytes(b);
 		return b;
 	}
 
-	public static void readFully(InputStream in, byte[] b) throws IOException {
-		int offset = 0;
-		while(offset < b.length) {
-			int read = in.read(b, offset, b.length - offset);
-			if(read == -1) break;
-			offset += read;
-		}
-		TestCase.assertEquals(b.length, offset);
-	}
-
 	public static String createRandomString(int length) throws Exception {
 		StringBuilder s = new StringBuilder(length);
 		for(int i = 0; i < length; i++)
diff --git a/briar-tests/src/org/briarproject/crypto/KeyAgreementTest.java b/briar-tests/src/org/briarproject/crypto/KeyAgreementTest.java
index 1193e60d950977c53b3f13e78c5b8f8d2ff87ba4..ae8860b687531e60dda7ac0538bcf867dce704e8 100644
--- a/briar-tests/src/org/briarproject/crypto/KeyAgreementTest.java
+++ b/briar-tests/src/org/briarproject/crypto/KeyAgreementTest.java
@@ -6,7 +6,7 @@ import org.briarproject.BriarTestCase;
 import org.briarproject.TestSeedProvider;
 import org.briarproject.api.crypto.CryptoComponent;
 import org.briarproject.api.crypto.KeyPair;
-import org.briarproject.api.crypto.SeedProvider;
+import org.briarproject.api.system.SeedProvider;
 import org.junit.Test;
 
 public class KeyAgreementTest extends BriarTestCase {
diff --git a/briar-tests/src/org/briarproject/db/DatabaseCleanerImplTest.java b/briar-tests/src/org/briarproject/db/DatabaseCleanerImplTest.java
index 2442aed79f7f7713f1adf97751650ffd613ef4e2..28b35b54bc58f284f35d1d26c7e1b7d1e07486b2 100644
--- a/briar-tests/src/org/briarproject/db/DatabaseCleanerImplTest.java
+++ b/briar-tests/src/org/briarproject/db/DatabaseCleanerImplTest.java
@@ -6,9 +6,9 @@ import java.util.concurrent.CountDownLatch;
 
 import org.briarproject.BriarTestCase;
 import org.briarproject.api.db.DbException;
-import org.briarproject.api.system.SystemTimer;
 import org.briarproject.api.system.Timer;
 import org.briarproject.db.DatabaseCleaner.Callback;
+import org.briarproject.system.SystemTimer;
 
 import org.junit.Test;
 
diff --git a/briar-tests/src/org/briarproject/db/DatabaseComponentImplTest.java b/briar-tests/src/org/briarproject/db/DatabaseComponentImplTest.java
index 7f68c99e7fe50111d3420dca36c9a496827e30fe..d531116c510b6309b8e0cf3e33523e27ceb8862a 100644
--- a/briar-tests/src/org/briarproject/db/DatabaseComponentImplTest.java
+++ b/briar-tests/src/org/briarproject/db/DatabaseComponentImplTest.java
@@ -8,8 +8,8 @@ import java.util.Collections;
 import org.briarproject.api.db.DatabaseComponent;
 import org.briarproject.api.db.DbException;
 import org.briarproject.api.lifecycle.ShutdownManager;
-import org.briarproject.api.system.SystemClock;
 import org.briarproject.db.DatabaseCleaner.Callback;
+import org.briarproject.system.SystemClock;
 
 import org.jmock.Expectations;
 import org.jmock.Mockery;
diff --git a/briar-tests/src/org/briarproject/db/H2DatabaseTest.java b/briar-tests/src/org/briarproject/db/H2DatabaseTest.java
index dc93ac9889bc38e8f68af7e45e116b4fccdf4299..77ee034057616ce5105f7754004d0912df30a95d 100644
--- a/briar-tests/src/org/briarproject/db/H2DatabaseTest.java
+++ b/briar-tests/src/org/briarproject/db/H2DatabaseTest.java
@@ -38,9 +38,9 @@ import org.briarproject.api.messaging.GroupId;
 import org.briarproject.api.messaging.GroupStatus;
 import org.briarproject.api.messaging.Message;
 import org.briarproject.api.messaging.MessageId;
-import org.briarproject.api.system.SystemClock;
 import org.briarproject.api.transport.Endpoint;
 import org.briarproject.api.transport.TemporarySecret;
+import org.briarproject.system.SystemClock;
 
 import org.junit.After;
 import org.junit.Before;
diff --git a/briar-tests/src/org/briarproject/messaging/ConstantsTest.java b/briar-tests/src/org/briarproject/messaging/ConstantsTest.java
index 2f457f690cc76a1b31244aedde4255538aed110c..52c40b056ab101ec66d0a41e720b809ea6451007 100644
--- a/briar-tests/src/org/briarproject/messaging/ConstantsTest.java
+++ b/briar-tests/src/org/briarproject/messaging/ConstantsTest.java
@@ -19,6 +19,7 @@ import java.util.Random;
 import org.briarproject.BriarTestCase;
 import org.briarproject.TestDatabaseModule;
 import org.briarproject.TestLifecycleModule;
+import org.briarproject.TestSystemModule;
 import org.briarproject.TestUtils;
 import org.briarproject.api.Author;
 import org.briarproject.api.AuthorFactory;
@@ -45,9 +46,7 @@ import org.briarproject.db.DatabaseModule;
 import org.briarproject.messaging.duplex.DuplexMessagingModule;
 import org.briarproject.messaging.simplex.SimplexMessagingModule;
 import org.briarproject.serial.SerialModule;
-import org.briarproject.system.SystemModule;
 import org.briarproject.transport.TransportModule;
-
 import org.junit.Test;
 
 import com.google.inject.Guice;
@@ -63,7 +62,7 @@ public class ConstantsTest extends BriarTestCase {
 
 	public ConstantsTest() throws Exception {
 		Injector i = Guice.createInjector(new TestDatabaseModule(),
-				new TestLifecycleModule(), new SystemModule(),
+				new TestLifecycleModule(), new TestSystemModule(),
 				new CryptoModule(), new DatabaseModule(), new MessagingModule(),
 				new DuplexMessagingModule(), new SimplexMessagingModule(),
 				new SerialModule(), new TransportModule());
diff --git a/briar-tests/src/org/briarproject/messaging/simplex/OutgoingSimplexConnectionTest.java b/briar-tests/src/org/briarproject/messaging/simplex/OutgoingSimplexConnectionTest.java
index f3b9d6c012f660716e779829d5341a30a9b4431a..c01501c92772dbac679d37912ebec82e6e5a653e 100644
--- a/briar-tests/src/org/briarproject/messaging/simplex/OutgoingSimplexConnectionTest.java
+++ b/briar-tests/src/org/briarproject/messaging/simplex/OutgoingSimplexConnectionTest.java
@@ -14,6 +14,7 @@ import java.util.concurrent.Executors;
 
 import org.briarproject.BriarTestCase;
 import org.briarproject.TestLifecycleModule;
+import org.briarproject.TestSystemModule;
 import org.briarproject.TestUtils;
 import org.briarproject.api.ContactId;
 import org.briarproject.api.TransportId;
@@ -30,9 +31,7 @@ import org.briarproject.crypto.CryptoModule;
 import org.briarproject.messaging.MessagingModule;
 import org.briarproject.messaging.duplex.DuplexMessagingModule;
 import org.briarproject.serial.SerialModule;
-import org.briarproject.system.SystemModule;
 import org.briarproject.transport.TransportModule;
-
 import org.jmock.Expectations;
 import org.jmock.Mockery;
 import org.junit.Test;
@@ -68,7 +67,7 @@ public class OutgoingSimplexConnectionTest extends BriarTestCase {
 			}
 		};
 		Injector i = Guice.createInjector(testModule,
-				new TestLifecycleModule(), new SystemModule(),
+				new TestLifecycleModule(), new TestSystemModule(),
 				new CryptoModule(), new MessagingModule(),
 				new DuplexMessagingModule(), new SimplexMessagingModule(),
 				new SerialModule(), new TransportModule());
diff --git a/briar-tests/src/org/briarproject/messaging/simplex/SimplexMessagingIntegrationTest.java b/briar-tests/src/org/briarproject/messaging/simplex/SimplexMessagingIntegrationTest.java
index 1c522d458d03d31b916ddac7f06a26d62878dcd0..9fa7f371b3cc909a3ee3f3046bd3f5c16ad8324c 100644
--- a/briar-tests/src/org/briarproject/messaging/simplex/SimplexMessagingIntegrationTest.java
+++ b/briar-tests/src/org/briarproject/messaging/simplex/SimplexMessagingIntegrationTest.java
@@ -12,6 +12,7 @@ import java.util.Random;
 import org.briarproject.BriarTestCase;
 import org.briarproject.TestDatabaseModule;
 import org.briarproject.TestLifecycleModule;
+import org.briarproject.TestSystemModule;
 import org.briarproject.TestUtils;
 import org.briarproject.api.Author;
 import org.briarproject.api.AuthorId;
@@ -42,9 +43,7 @@ import org.briarproject.messaging.MessagingModule;
 import org.briarproject.messaging.duplex.DuplexMessagingModule;
 import org.briarproject.plugins.ImmediateExecutor;
 import org.briarproject.serial.SerialModule;
-import org.briarproject.system.SystemModule;
 import org.briarproject.transport.TransportModule;
-
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
@@ -87,7 +86,7 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
 
 	private Injector createInjector(File dir) {
 		return Guice.createInjector(new TestDatabaseModule(dir),
-				new TestLifecycleModule(), new SystemModule(),
+				new TestLifecycleModule(), new TestSystemModule(),
 				new CryptoModule(), new DatabaseModule(), new MessagingModule(),
 				new DuplexMessagingModule(), new SimplexMessagingModule(), 
 				new SerialModule(), new TransportModule());
diff --git a/briar-tests/src/org/briarproject/plugins/PluginManagerImplTest.java b/briar-tests/src/org/briarproject/plugins/PluginManagerImplTest.java
index 78ddfb5e8477f094b194a8ea6715d3241371162f..3d832c47280d487e35c5ef097dbbf2220ec16ab2 100644
--- a/briar-tests/src/org/briarproject/plugins/PluginManagerImplTest.java
+++ b/briar-tests/src/org/briarproject/plugins/PluginManagerImplTest.java
@@ -17,9 +17,9 @@ import org.briarproject.api.plugins.simplex.SimplexPluginCallback;
 import org.briarproject.api.plugins.simplex.SimplexPluginConfig;
 import org.briarproject.api.plugins.simplex.SimplexPluginFactory;
 import org.briarproject.api.system.Clock;
-import org.briarproject.api.system.SystemClock;
 import org.briarproject.api.transport.ConnectionDispatcher;
 import org.briarproject.api.ui.UiCallback;
+import org.briarproject.system.SystemClock;
 import org.jmock.Expectations;
 import org.jmock.Mockery;
 import org.junit.Test;
diff --git a/briar-tests/src/org/briarproject/plugins/bluetooth/BluetoothClientTest.java b/briar-tests/src/org/briarproject/plugins/bluetooth/BluetoothClientTest.java
index 28eef667e1a51844828f2779546849fef0c1392c..3b86da8a1bd3a8f80c79445f80d14082261921c9 100644
--- a/briar-tests/src/org/briarproject/plugins/bluetooth/BluetoothClientTest.java
+++ b/briar-tests/src/org/briarproject/plugins/bluetooth/BluetoothClientTest.java
@@ -10,8 +10,8 @@ import java.util.concurrent.Executors;
 import org.briarproject.api.ContactId;
 import org.briarproject.api.TransportConfig;
 import org.briarproject.api.TransportProperties;
-import org.briarproject.api.system.SystemClock;
 import org.briarproject.plugins.DuplexClientTest;
+import org.briarproject.system.SystemClock;
 
 // This is not a JUnit test - it has to be run manually while the server test
 // is running on another machine
diff --git a/briar-tests/src/org/briarproject/plugins/bluetooth/BluetoothServerTest.java b/briar-tests/src/org/briarproject/plugins/bluetooth/BluetoothServerTest.java
index 99b77e3f24e023f410623058e07a02951abf1878..1dfbf841dcc52f64bf50f2e94e2d5a5422186c8a 100644
--- a/briar-tests/src/org/briarproject/plugins/bluetooth/BluetoothServerTest.java
+++ b/briar-tests/src/org/briarproject/plugins/bluetooth/BluetoothServerTest.java
@@ -8,8 +8,8 @@ import java.util.concurrent.Executors;
 
 import org.briarproject.api.TransportConfig;
 import org.briarproject.api.TransportProperties;
-import org.briarproject.api.system.SystemClock;
 import org.briarproject.plugins.DuplexServerTest;
+import org.briarproject.system.SystemClock;
 
 // This is not a JUnit test - it has to be run manually while the client test
 // is running on another machine
diff --git a/briar-tests/src/org/briarproject/plugins/tcp/LanTcpClientTest.java b/briar-tests/src/org/briarproject/plugins/tcp/LanTcpClientTest.java
index 1c7c7b83a74ea4882b8aad786710644cad6e6d08..9e9fb77d59836544080c1365ba26bcb26f37aa51 100644
--- a/briar-tests/src/org/briarproject/plugins/tcp/LanTcpClientTest.java
+++ b/briar-tests/src/org/briarproject/plugins/tcp/LanTcpClientTest.java
@@ -10,8 +10,8 @@ import org.briarproject.api.ContactId;
 import org.briarproject.api.TransportConfig;
 import org.briarproject.api.TransportProperties;
 import org.briarproject.api.system.Clock;
-import org.briarproject.api.system.SystemClock;
 import org.briarproject.plugins.DuplexClientTest;
+import org.briarproject.system.SystemClock;
 
 // This is not a JUnit test - it has to be run manually while the server test
 // is running on another machine
diff --git a/briar-tests/src/org/briarproject/plugins/tcp/LanTcpPluginTest.java b/briar-tests/src/org/briarproject/plugins/tcp/LanTcpPluginTest.java
index 38ba8b6a4efd1c4a9ebd5c0c2df90ec9fcc359f3..832107d521677d7bf810f18f82f79db628eaab12 100644
--- a/briar-tests/src/org/briarproject/plugins/tcp/LanTcpPluginTest.java
+++ b/briar-tests/src/org/briarproject/plugins/tcp/LanTcpPluginTest.java
@@ -21,7 +21,7 @@ import org.briarproject.api.plugins.duplex.DuplexPlugin;
 import org.briarproject.api.plugins.duplex.DuplexPluginCallback;
 import org.briarproject.api.plugins.duplex.DuplexTransportConnection;
 import org.briarproject.api.system.Clock;
-import org.briarproject.api.system.SystemClock;
+import org.briarproject.system.SystemClock;
 
 import org.junit.Test;
 
diff --git a/briar-tests/src/org/briarproject/plugins/tcp/LanTcpServerTest.java b/briar-tests/src/org/briarproject/plugins/tcp/LanTcpServerTest.java
index d53f77b488cbd89cf110e52cc4f035a5ca699f5e..3506de7f715b6674d4f98920a5cf88932ed50a9c 100644
--- a/briar-tests/src/org/briarproject/plugins/tcp/LanTcpServerTest.java
+++ b/briar-tests/src/org/briarproject/plugins/tcp/LanTcpServerTest.java
@@ -8,8 +8,8 @@ import java.util.concurrent.Executors;
 import org.briarproject.api.TransportConfig;
 import org.briarproject.api.TransportProperties;
 import org.briarproject.api.system.Clock;
-import org.briarproject.api.system.SystemClock;
 import org.briarproject.plugins.DuplexServerTest;
+import org.briarproject.system.SystemClock;
 
 // This is not a JUnit test - it has to be run manually while the client test
 // is running on another machine
diff --git a/briar-tests/src/org/briarproject/system/LinuxSeedProviderTest.java b/briar-tests/src/org/briarproject/system/LinuxSeedProviderTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..e7ddccf3521a34e7e0ee1cb6e9e1bf1e1ab7dabd
--- /dev/null
+++ b/briar-tests/src/org/briarproject/system/LinuxSeedProviderTest.java
@@ -0,0 +1,77 @@
+package org.briarproject.system;
+
+import static org.briarproject.api.system.SeedProvider.SEED_BYTES;
+import static org.junit.Assert.assertArrayEquals;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.util.HashSet;
+import java.util.Random;
+import java.util.Set;
+
+import org.briarproject.BriarTestCase;
+import org.briarproject.TestUtils;
+import org.briarproject.api.Bytes;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class LinuxSeedProviderTest extends BriarTestCase {
+
+	private final File testDir = TestUtils.getTestDirectory();
+
+	@Before
+	public void setUp() {
+		testDir.mkdirs();
+	}
+
+	@Test
+	public void testSeedAppearsSane() {
+		Set<Bytes> seeds = new HashSet<Bytes>();
+		LinuxSeedProvider p = new LinuxSeedProvider();
+		for(int i = 0; i < 1000; i++) {
+			byte[] seed = p.getSeed();
+			assertEquals(SEED_BYTES, seed.length);
+			assertTrue(seeds.add(new Bytes(seed)));
+		}
+	}
+
+	@Test
+	public void testEntropyIsWrittenToPool() throws Exception {
+		// Redirect the provider's entropy to a file
+		File urandom = new File(testDir, "urandom");
+		urandom.delete();
+		assertTrue(urandom.createNewFile());
+		assertEquals(0, urandom.length());
+		String path = urandom.getAbsolutePath();
+		LinuxSeedProvider p = new LinuxSeedProvider(path, "/dev/urandom");
+		p.getSeed();
+		// There should be 16 bytes from the clock, plus network interfaces
+		assertTrue(urandom.length() > 20);
+	}
+
+	@Test
+	public void testSeedIsReadFromPool() throws Exception {
+		// Generate a seed
+		byte[] seed = new byte[SEED_BYTES];
+		new Random().nextBytes(seed);
+		// Write the seed to a file
+		File urandom = new File(testDir, "urandom");
+		urandom.delete();
+		FileOutputStream out = new FileOutputStream(urandom);
+		out.write(seed);
+		out.flush();
+		out.close();
+		assertTrue(urandom.exists());
+		assertEquals(SEED_BYTES, urandom.length());
+		// Check that the provider reads the seed from the file
+		String path = urandom.getAbsolutePath();
+		LinuxSeedProvider p = new LinuxSeedProvider("/dev/urandom", path);
+		assertArrayEquals(seed, p.getSeed());
+	}
+
+	@After
+	public void tearDown() {
+		TestUtils.deleteTestDirectory(testDir);
+	}
+}
diff --git a/briar-tests/src/org/briarproject/transport/IncomingEncryptionLayerTest.java b/briar-tests/src/org/briarproject/transport/IncomingEncryptionLayerTest.java
index 631c33facabed83111f58b34b9e92fae79542996..cc1a38e1c0d1f778bd424650412e1b601277296f 100644
--- a/briar-tests/src/org/briarproject/transport/IncomingEncryptionLayerTest.java
+++ b/briar-tests/src/org/briarproject/transport/IncomingEncryptionLayerTest.java
@@ -10,12 +10,12 @@ import java.io.ByteArrayInputStream;
 
 import org.briarproject.BriarTestCase;
 import org.briarproject.TestLifecycleModule;
+import org.briarproject.TestSystemModule;
 import org.briarproject.api.FormatException;
 import org.briarproject.api.crypto.AuthenticatedCipher;
 import org.briarproject.api.crypto.CryptoComponent;
 import org.briarproject.api.crypto.SecretKey;
 import org.briarproject.crypto.CryptoModule;
-
 import org.junit.Test;
 
 import com.google.inject.Guice;
@@ -35,7 +35,7 @@ public class IncomingEncryptionLayerTest extends BriarTestCase {
 
 	public IncomingEncryptionLayerTest() {
 		Injector i = Guice.createInjector(new CryptoModule(),
-				new TestLifecycleModule());
+				new TestLifecycleModule(), new TestSystemModule());
 		crypto = i.getInstance(CryptoComponent.class);
 		frameCipher = crypto.getFrameCipher();
 		frameKey = crypto.generateSecretKey();
diff --git a/briar-tests/src/org/briarproject/transport/OutgoingEncryptionLayerTest.java b/briar-tests/src/org/briarproject/transport/OutgoingEncryptionLayerTest.java
index bf9a12c1b3a1d571313a24287a88e9207c562f6d..8a35ce732c6246555c6c055bd8703b733f2847e5 100644
--- a/briar-tests/src/org/briarproject/transport/OutgoingEncryptionLayerTest.java
+++ b/briar-tests/src/org/briarproject/transport/OutgoingEncryptionLayerTest.java
@@ -11,11 +11,11 @@ import java.io.ByteArrayOutputStream;
 
 import org.briarproject.BriarTestCase;
 import org.briarproject.TestLifecycleModule;
+import org.briarproject.TestSystemModule;
 import org.briarproject.api.crypto.AuthenticatedCipher;
 import org.briarproject.api.crypto.CryptoComponent;
 import org.briarproject.api.crypto.SecretKey;
 import org.briarproject.crypto.CryptoModule;
-
 import org.junit.Test;
 
 import com.google.inject.Guice;
@@ -35,7 +35,7 @@ public class OutgoingEncryptionLayerTest extends BriarTestCase {
 
 	public OutgoingEncryptionLayerTest() {
 		Injector i = Guice.createInjector(new CryptoModule(),
-				new TestLifecycleModule());
+				new TestLifecycleModule(), new TestSystemModule());
 		crypto = i.getInstance(CryptoComponent.class);
 		frameCipher = crypto.getFrameCipher();
 		tag = new byte[TAG_LENGTH];
diff --git a/briar-tests/src/org/briarproject/transport/TransportIntegrationTest.java b/briar-tests/src/org/briarproject/transport/TransportIntegrationTest.java
index 99f4ff4529390b2f53ac04b82e8f1b4d352844b0..857bfdb6ed4d1cfb6492eff76fc2571e22e25ce5 100644
--- a/briar-tests/src/org/briarproject/transport/TransportIntegrationTest.java
+++ b/briar-tests/src/org/briarproject/transport/TransportIntegrationTest.java
@@ -13,6 +13,7 @@ import java.util.Random;
 
 import org.briarproject.BriarTestCase;
 import org.briarproject.TestLifecycleModule;
+import org.briarproject.TestSystemModule;
 import org.briarproject.TestUtils;
 import org.briarproject.api.ContactId;
 import org.briarproject.api.TransportId;
@@ -23,7 +24,6 @@ import org.briarproject.api.transport.ConnectionContext;
 import org.briarproject.api.transport.ConnectionWriter;
 import org.briarproject.api.transport.ConnectionWriterFactory;
 import org.briarproject.crypto.CryptoModule;
-
 import org.junit.Test;
 
 import com.google.inject.AbstractModule;
@@ -52,7 +52,7 @@ public class TransportIntegrationTest extends BriarTestCase {
 			}
 		};
 		Injector i = Guice.createInjector(testModule, new CryptoModule(),
-				new TestLifecycleModule());
+				new TestLifecycleModule(), new TestSystemModule());
 		crypto = i.getInstance(CryptoComponent.class);
 		connectionWriterFactory = i.getInstance(ConnectionWriterFactory.class);
 		contactId = new ContactId(234);