diff --git a/.classpath b/.classpath
index 18ed19663b13363fe6a570274e0eb82de015367a..2ed9bb6ee03d54c507ff19daa62b1c761d8cb246 100644
--- a/.classpath
+++ b/.classpath
@@ -1,15 +1,19 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <classpath>
-	<classpathentry kind="src" path="ui"/>
+	<classpathentry excluding=".gitignore|build.xml" kind="src" path="api"/>
+	<classpathentry excluding=".gitignore|build.xml" kind="src" path="components"/>
 	<classpathentry kind="src" path="i18n"/>
-	<classpathentry kind="src" path="test"/>
-	<classpathentry kind="src" path="api"/>
-	<classpathentry kind="src" path="components"/>
-	<classpathentry kind="src" path="util"/>
 	<classpathentry kind="src" path="installer"/>
+	<classpathentry kind="src" path="test"/>
+	<classpathentry excluding=".gitignore|build.xml" kind="src" path="ui"/>
+	<classpathentry excluding=".gitignore|build.xml" kind="src" path="util"/>
 	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
 	<classpathentry kind="lib" path="lib/h2small-1.3.154.jar"/>
 	<classpathentry kind="lib" path="lib/guice-3.0-no_aop.jar"/>
 	<classpathentry kind="lib" path="lib/javax.inject-1.jar"/>
+	<classpathentry kind="lib" path="lib/test/junit-4.9b2.jar"/>
+	<classpathentry kind="lib" path="lib/test/hamcrest-core-1.1.jar"/>
+	<classpathentry kind="lib" path="lib/test/hamcrest-library-1.1.jar"/>
+	<classpathentry kind="lib" path="lib/test/jmock-2.5.1.jar"/>
 	<classpathentry kind="output" path="bin"/>
 </classpath>
diff --git a/build-common.xml b/build-common.xml
index dd1a59c5a4f7212213cc5ec89b10cabc87c7f5f5..6d9487f8e7d643231c0ac0ecfcb0e1d6395f7056 100644
--- a/build-common.xml
+++ b/build-common.xml
@@ -1,8 +1,10 @@
 <project name='build-common' default='compile'>
 	<import file='dependencies.xml'/>
-	<property name='build' location='build'/>
 	<dirname property='build-common.root' file='${ant.file.build-common}'/>
-	<fileset id='third-party-jars' dir='${build-common.root}/lib'>
+	<fileset id='bundled-jars' dir='${build-common.root}/lib'>
+		<include name='*.jar'/>
+	</fileset>
+	<fileset id='test-jars' dir='${build-common.root}/lib/test'>
 		<include name='*.jar'/>
 	</fileset>
 	<path id='api-classes'>
@@ -11,18 +13,22 @@
 	<path id='component-classes'>
 		<pathelement location='${build-common.root}/components/build'/>
 	</path>
+	<path id='test-classes'>
+		<pathelement location='${build-common.root}/test/build'/>
+	</path>
 	<path id='util-classes'>
 		<pathelement location='${build-common.root}/util/build'/>
 	</path>
 	<target name='clean'>
-		<delete dir='${build}'/>
+		<delete dir='build'/>
 	</target>
 	<target name='compile'>
-		<mkdir dir='${build}'/>
-		<javac srcdir='net/sf/briar' destdir='${build}'
+		<mkdir dir='build'/>
+		<javac srcdir='net/sf/briar' destdir='build'
 			includeantruntime='false'>
 			<classpath>
-				<fileset refid='third-party-jars'/>
+				<fileset refid='bundled-jars'/>
+				<fileset refid='test-jars'/>
 				<path refid='api-classes'/>
 				<path refid='component-classes'/>
 				<path refid='util-classes'/>
diff --git a/build.xml b/build.xml
index e1daec61bac2b11cc417c76fa216266388fa7d48..e20d86a82685e51591228d4b7982a739c8550230 100644
--- a/build.xml
+++ b/build.xml
@@ -1,3 +1,3 @@
-<project name='all' default='compile'>
+<project name='all' default='depend'>
 	<import file='build-common.xml'/>
 </project>
diff --git a/dependencies.xml b/dependencies.xml
index f6b2af37894f97c9ee953f1cc9ed4a0578c54f15..1755a17fe7ad9b21fc7e3855bc3984263520b1f2 100644
--- a/dependencies.xml
+++ b/dependencies.xml
@@ -1,25 +1,23 @@
-<project name='dependencies' default='depend.all'>
-
+<project name='dependencies'>
 	<dirname property='depend.root' file='${ant.file.dependencies}'/>
-
-	<target name='depend.all' depends='depend.components, depend.ui'>
-	</target>
+	<target name='depend.all' depends='depend.components, depend.ui'/>
 	<target name='depend.api'>
 		<ant dir='${depend.root}/api' inheritAll='false'/>
 	</target>
 	<target name='depend.components' depends='depend.api, depend.util'>
 		<ant dir='${depend.root}/components' inheritAll='false'/>
 	</target>
+	<target name='depend.test' depends='depend.components'>
+		<ant dir='${depend.root}/test' inheritAll='false'/>
+	</target>
 	<target name='depend.ui' depends='depend.api, depend.util'>
 		<ant dir='${depend.root}/ui' inheritAll='false'/>
 	</target>
 	<target name='depend.util'>
 		<ant dir='${depend.root}/util' inheritAll='false'/>
 	</target>
-
 	<target name='depend-clean.all'
-		depends='depend-clean.components, depend-clean.ui'>
-	</target>
+		depends='depend-clean.components, depend-clean.ui'/>
 	<target name='depend-clean.api'>
 		<ant dir='${depend.root}/api' target='clean'
 			inheritAll='false'/>
@@ -29,6 +27,11 @@
 		<ant dir='${depend.root}/components' target='clean'
 			inheritAll='false'/>
 	</target>
+	<target name='depend-clean.test'
+		depends='depend-clean.components'>
+		<ant dir='${depend.root}/test' target='clean'
+			inheritAll='false'/>
+	</target>
 	<target name='depend-clean.ui'
 		depends='depend-clean.api, depend-clean.util'>
 		<ant dir='${depend.root}/ui' target='clean'
@@ -38,5 +41,4 @@
 		<ant dir='${depend.root}/util' target='clean'
 			inheritAll='false'/>
 	</target>
-
 </project>
diff --git a/lib/test/hamcrest-core-1.1.jar b/lib/test/hamcrest-core-1.1.jar
new file mode 100644
index 0000000000000000000000000000000000000000..5f1d5ce0c3d60472692cda24885c92042a693ac0
Binary files /dev/null and b/lib/test/hamcrest-core-1.1.jar differ
diff --git a/lib/test/hamcrest-library-1.1.jar b/lib/test/hamcrest-library-1.1.jar
new file mode 100644
index 0000000000000000000000000000000000000000..40610c9b4a2343cc8891a055dcd301e8d142d937
Binary files /dev/null and b/lib/test/hamcrest-library-1.1.jar differ
diff --git a/lib/test/jmock-2.5.1.jar b/lib/test/jmock-2.5.1.jar
new file mode 100644
index 0000000000000000000000000000000000000000..4415dfbc94f8515bef4495976bcdb0fa5e6b5981
Binary files /dev/null and b/lib/test/jmock-2.5.1.jar differ
diff --git a/lib/test/junit-4.9b2.jar b/lib/test/junit-4.9b2.jar
new file mode 100644
index 0000000000000000000000000000000000000000..aec30a07fb322901d74d262e4e21dba191851c37
Binary files /dev/null and b/lib/test/junit-4.9b2.jar differ
diff --git a/test/build.xml b/test/build.xml
new file mode 100644
index 0000000000000000000000000000000000000000..5869dbdfc96cb4d8327fe136ea394245ebaab759
--- /dev/null
+++ b/test/build.xml
@@ -0,0 +1,16 @@
+<project name='test' default='compile'>
+	<import file='../build-common.xml'/>
+	<target name='test' depends='depend'>
+		<junit haltonfailure='true' printsummary='on' showoutput='true'>
+			<classpath>
+				<fileset refid='bundled-jars'/>
+				<fileset refid='test-jars'/>
+				<path refid='api-classes'/>
+				<path refid='component-classes'/>
+				<path refid='test-classes'/>
+				<path refid='util-classes'/>
+			</classpath>
+			<test name='net.sf.briar.util.FileUtilsTest'/>
+		</junit>
+	</target>
+</project>
diff --git a/test/net/sf/briar/util/FileUtilsTest.java b/test/net/sf/briar/util/FileUtilsTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..c30ac0a6578229e1be850504880072ade3f568b5
--- /dev/null
+++ b/test/net/sf/briar/util/FileUtilsTest.java
@@ -0,0 +1,59 @@
+package net.sf.briar.util;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.util.Scanner;
+
+import junit.framework.TestCase;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class FileUtilsTest extends TestCase {
+
+	private final File testDir = new File("test.tmp");
+
+	@Before
+	public void setUp() {
+		testDir.mkdirs();
+	}
+
+	@Test
+	public void testCopy() throws IOException {
+		File src = new File(testDir, "src");
+		File dest = new File(testDir, "dest");
+
+		PrintStream out = new PrintStream(new FileOutputStream(src));
+		out.print("Foo bar\r\nBar foo\r\n");
+		out.flush();
+		out.close();
+		long length = src.length();
+
+		FileUtils.copy(src, dest);
+
+		assertEquals(length, dest.length());
+		Scanner in = new Scanner(dest);
+		assertTrue(in.hasNextLine());
+		assertEquals("Foo bar", in.nextLine());
+		assertTrue(in.hasNextLine());
+		assertEquals("Bar foo", in.nextLine());
+		assertFalse(in.hasNext());
+		in.close();
+
+		src.delete();
+		dest.delete();
+	}
+
+	@After
+	public void tearDown() throws IOException {
+		delete(testDir);
+	}
+
+	private static void delete(File f) throws IOException {
+		if(f.isDirectory()) for(File child : f.listFiles()) delete(child);
+		f.delete();
+	}
+}