diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ReadTreeTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ReadTreeTest.java
index 481691a448513316903d6655c7d0a6788ba5aee1..feef66f9ad3d40bde7b342051271e0da26e23563 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ReadTreeTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ReadTreeTest.java
@@ -2,6 +2,7 @@
  * Copyright (C) 2007, Dave Watson <dwatson@mimvista.com>
  * Copyright (C) 2008-2009, Robin Rosenberg <robin.rosenberg@dewire.com>
  * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
+ * Copyright (C) 2010, Christian Halstrick <christian.halstrick@sap.com>
  * and other copyright owners as documented in the project's IP log.
  *
  * This program and the accompanying materials are made available
@@ -49,6 +50,7 @@
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
+import java.util.ArrayList;
 import java.util.HashMap;
 
 import org.eclipse.jgit.errors.CheckoutConflictException;
@@ -58,7 +60,7 @@ public class ReadTreeTest extends RepositoryTestCase {
 	private Tree theHead;
 	private Tree theMerge;
 	private GitIndex theIndex;
-	private WorkDirCheckout theReadTree;
+	private Checkout theReadTree;
 	// Each of these rules are from the read-tree manpage
 	// go there to see what they mean.
 	// Rule 0 is left out for obvious reasons :)
@@ -71,23 +73,23 @@ public void testRules1thru3_NoIndexEntry() throws IOException {
 		headFile.setId(objectId);
 		Tree merge = new Tree(db);
 
-		WorkDirCheckout readTree = new WorkDirCheckout(db, trash, head, index, merge);
+		Checkout readTree = getCheckoutImpl(head, index, merge);
 		readTree.prescanTwoTrees();
 
-		assertTrue(readTree.removed.contains("foo"));
+		assertTrue(readTree.removed().contains("foo"));
 
-		readTree = new WorkDirCheckout(db, trash, merge, index, head);
+		readTree = getCheckoutImpl(merge, index, head);
 		readTree.prescanTwoTrees();
 
-		assertEquals(objectId, readTree.updated.get("foo"));
+		assertEquals(objectId, readTree.updated().get("foo"));
 
 		ObjectId anotherId = ObjectId.fromString("ba78e065e2c261d4f7b8f42107588051e87e18ee");
 		merge.addFile("foo").setId(anotherId);
 
-		readTree = new WorkDirCheckout(db, trash, head, index, merge);
+		readTree = getCheckoutImpl(head, index, merge);
 		readTree.prescanTwoTrees();
 
-		assertEquals(anotherId, readTree.updated.get("foo"));
+		assertEquals(anotherId, readTree.updated().get("foo"));
 	}
 
 	void setupCase(HashMap<String, String> headEntries,
@@ -134,8 +136,8 @@ ObjectId genSha1(String data) {
 		return null;
 	}
 
-	private WorkDirCheckout go() throws IOException {
-		theReadTree = new WorkDirCheckout(db, trash, theHead, theIndex, theMerge);
+	private Checkout go() throws IOException {
+		theReadTree = getCheckoutImpl(theHead, theIndex, theMerge);
 		theReadTree.prescanTwoTrees();
 		return theReadTree;
 	}
@@ -152,9 +154,9 @@ public void testRules4thru13_IndexEntryNotInHead() throws IOException {
 		setupCase(null, null, idxMap);
 		theReadTree = go();
 
-		assertTrue(theReadTree.updated.isEmpty());
-		assertTrue(theReadTree.removed.isEmpty());
-		assertTrue(theReadTree.conflicts.isEmpty());
+		assertTrue(theReadTree.updated().isEmpty());
+		assertTrue(theReadTree.removed().isEmpty());
+		assertTrue(theReadTree.conflicts().isEmpty());
 
 		// rules 6 and 7
 		idxMap = new HashMap<String, String>();
@@ -172,9 +174,9 @@ public void testRules4thru13_IndexEntryNotInHead() throws IOException {
 		setupCase(null, mergeMap, idxMap);
 		go();
 
-		assertTrue(theReadTree.updated.isEmpty());
-		assertTrue(theReadTree.removed.isEmpty());
-		assertTrue(theReadTree.conflicts.contains("foo"));
+		assertTrue(theReadTree.updated().isEmpty());
+		assertTrue(theReadTree.removed().isEmpty());
+		assertTrue(theReadTree.conflicts().contains("foo"));
 
 		// rule 10
 
@@ -183,9 +185,9 @@ public void testRules4thru13_IndexEntryNotInHead() throws IOException {
 		setupCase(headMap, null, idxMap);
 		go();
 
-		assertTrue(theReadTree.removed.contains("foo"));
-		assertTrue(theReadTree.updated.isEmpty());
-		assertTrue(theReadTree.conflicts.isEmpty());
+		assertTrue(theReadTree.removed().contains("foo"));
+		assertTrue(theReadTree.updated().isEmpty());
+		assertTrue(theReadTree.conflicts().isEmpty());
 
 		// rule 11
 		setupCase(headMap, null, idxMap);
@@ -194,18 +196,18 @@ public void testRules4thru13_IndexEntryNotInHead() throws IOException {
 		theIndex.getMembers()[0].forceRecheck();
 		go();
 
-		assertTrue(theReadTree.removed.isEmpty());
-		assertTrue(theReadTree.updated.isEmpty());
-		assertTrue(theReadTree.conflicts.contains("foo"));
+		assertTrue(theReadTree.removed().isEmpty());
+		assertTrue(theReadTree.updated().isEmpty());
+		assertTrue(theReadTree.conflicts().contains("foo"));
 
 		// rule 12 & 13
 		headMap.put("foo", "head");
 		setupCase(headMap, null, idxMap);
 		go();
 
-		assertTrue(theReadTree.removed.isEmpty());
-		assertTrue(theReadTree.updated.isEmpty());
-		assertTrue(theReadTree.conflicts.contains("foo"));
+		assertTrue(theReadTree.removed().isEmpty());
+		assertTrue(theReadTree.updated().isEmpty());
+		assertTrue(theReadTree.conflicts().contains("foo"));
 
 		// rules 14 & 15
 		setupCase(headMap, headMap, idxMap);
@@ -215,7 +217,7 @@ public void testRules4thru13_IndexEntryNotInHead() throws IOException {
 
 		// rules 16 & 17
 		setupCase(headMap, mergeMap, idxMap); go();
-		assertTrue(theReadTree.conflicts.contains("foo"));
+		assertTrue(theReadTree.conflicts().contains("foo"));
 
 		// rules 18 & 19
 		setupCase(headMap, idxMap, idxMap); go();
@@ -223,7 +225,7 @@ public void testRules4thru13_IndexEntryNotInHead() throws IOException {
 
 		// rule 20
 		setupCase(idxMap, mergeMap, idxMap); go();
-		assertTrue(theReadTree.updated.containsKey("foo"));
+		assertTrue(theReadTree.updated().containsKey("foo"));
 
 		// rules 21
 		setupCase(idxMap, mergeMap, idxMap);
@@ -231,13 +233,13 @@ public void testRules4thru13_IndexEntryNotInHead() throws IOException {
 		writeTrashFile("foo", "bar");
 		theIndex.getMembers()[0].forceRecheck();
 		go();
-		assertTrue(theReadTree.conflicts.contains("foo"));
+		assertTrue(theReadTree.conflicts().contains("foo"));
 	}
 
 	private void assertAllEmpty() {
-		assertTrue(theReadTree.removed.isEmpty());
-		assertTrue(theReadTree.updated.isEmpty());
-		assertTrue(theReadTree.conflicts.isEmpty());
+		assertTrue(theReadTree.removed().isEmpty());
+		assertTrue(theReadTree.updated().isEmpty());
+		assertTrue(theReadTree.conflicts().isEmpty());
 	}
 
 	public void testDirectoryFileSimple() throws IOException {
@@ -254,20 +256,20 @@ public void testDirectoryFileSimple() throws IOException {
 		recursiveDelete(new File(trash, "DF"));
 
 		theIndex.add(trash, writeTrashFile("DF", "DF"));
-		theReadTree = new WorkDirCheckout(db, trash, treeDF, theIndex, treeDFDF);
+		theReadTree = getCheckoutImpl(treeDF, theIndex, treeDFDF);
 		theReadTree.prescanTwoTrees();
 
-		assertTrue(theReadTree.removed.contains("DF"));
-		assertTrue(theReadTree.updated.containsKey("DF/DF"));
+		assertTrue(theReadTree.removed().contains("DF"));
+		assertTrue(theReadTree.updated().containsKey("DF/DF"));
 
 		recursiveDelete(new File(trash, "DF"));
 		theIndex = new GitIndex(db);
 		theIndex.add(trash, writeTrashFile("DF/DF", "DF/DF"));
 
-		theReadTree = new WorkDirCheckout(db, trash, treeDFDF, theIndex, treeDF);
+		theReadTree = getCheckoutImpl(treeDFDF, theIndex, treeDF);
 		theReadTree.prescanTwoTrees();
-		assertTrue(theReadTree.removed.contains("DF/DF"));
-		assertTrue(theReadTree.updated.containsKey("DF"));
+		assertTrue(theReadTree.removed().contains("DF/DF"));
+		assertTrue(theReadTree.updated().containsKey("DF"));
 	}
 
 	/*
@@ -473,19 +475,19 @@ private void cleanUpDF() throws Exception {
 	}
 
 	private void assertConflict(String s) {
-		assertTrue(theReadTree.conflicts.contains(s));
+		assertTrue(theReadTree.conflicts().contains(s));
 	}
 
 	private void assertUpdated(String s) {
-		assertTrue(theReadTree.updated.containsKey(s));
+		assertTrue(theReadTree.updated().containsKey(s));
 	}
 
 	private void assertRemoved(String s) {
-		assertTrue(theReadTree.removed.contains(s));
+		assertTrue(theReadTree.removed().contains(s));
 	}
 
 	private void assertNoConflicts() {
-		assertTrue(theReadTree.conflicts.isEmpty());
+		assertTrue(theReadTree.conflicts().isEmpty());
 	}
 
 	private void doit(HashMap<String, String> h, HashMap<String, String>m,
@@ -551,7 +553,7 @@ public void testCloseNameConflicts1() throws IOException {
 	}
 
 	private void checkout() throws IOException {
-		theReadTree = new WorkDirCheckout(db, trash, theHead, theIndex, theMerge);
+		theReadTree = getCheckoutImpl(theHead, theIndex, theMerge);
 		theReadTree.checkout();
 	}
 
@@ -578,4 +580,57 @@ public void testCheckoutOutChanges() throws IOException {
 			// should have thrown
 		}
 	}
+
+	/**
+	 * The interface these tests need from a class implementing a checkout
+	 */
+	interface Checkout {
+		HashMap<String, ObjectId> updated();
+		ArrayList<String> conflicts();
+		ArrayList<String> removed();
+		void prescanTwoTrees() throws IOException;
+		void checkout() throws IOException;
+	}
+
+	/**
+	 * Return the current implementation of the {@link Checkout} interface.
+	 * <p>
+	 * May be overridden by subclasses which would inherit all tests but can
+	 * specify their own implementation of a Checkout
+	 *
+	 * @param head
+	 * @param index
+	 * @param merge
+	 * @return the current implementation of {@link Checkout}
+	 */
+	protected Checkout getCheckoutImpl(Tree head, GitIndex index,
+			Tree merge) {
+		return new WorkdirCheckoutImpl(head, index, merge);
+	}
+
+	/**
+	 * An implementation of the {@link Checkout} interface which uses {@link WorkDirCheckout}
+	 */
+	class WorkdirCheckoutImpl extends WorkDirCheckout implements Checkout {
+		public WorkdirCheckoutImpl(Tree head, GitIndex index,
+				Tree merge) {
+			super(db, trash, head, index, merge);
+		}
+
+		public HashMap<String, ObjectId> updated() {
+			return updated;
+		}
+
+		public ArrayList<String> conflicts() {
+			return conflicts;
+		}
+
+		public ArrayList<String> removed() {
+			return removed;
+		}
+
+		public void prescanTwoTrees() throws IOException {
+			super.prescanTwoTrees();
+		}
+	}
 }