/*
 * Copyright (C) 2007, Dave Watson <dwatson@mimvista.com>
 * Copyright (C) 2008-2011, Shawn O. Pearce <spearce@spearce.org>
 * Copyright (C) 2008-2011, Robin Rosenberg <robin.rosenberg@dewire.com>
 * Copyright (C) 2010-2011, 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 under the
 * terms of the Eclipse Distribution License v1.0 which accompanies this
 * distribution, is reproduced below, and is available at
 * http://www.eclipse.org/org/documents/edl-v10.php
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * - Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * - Neither the name of the Eclipse Foundation, Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from this
 * software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */
package org.eclipse.jgit.lib;

import static java.nio.charset.StandardCharsets.UTF_8;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.jgit.api.CheckoutCommand;
import org.eclipse.jgit.api.CheckoutResult;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.MergeResult.MergeStatus;
import org.eclipse.jgit.api.ResetCommand.ResetType;
import org.eclipse.jgit.api.Status;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.api.errors.NoFilepatternException;
import org.eclipse.jgit.dircache.DirCache;
import org.eclipse.jgit.dircache.DirCacheCheckout;
import org.eclipse.jgit.dircache.DirCacheCheckout.CheckoutMetadata;
import org.eclipse.jgit.dircache.DirCacheEditor;
import org.eclipse.jgit.dircache.DirCacheEditor.PathEdit;
import org.eclipse.jgit.dircache.DirCacheEntry;
import org.eclipse.jgit.errors.CheckoutConflictException;
import org.eclipse.jgit.errors.CorruptObjectException;
import org.eclipse.jgit.errors.NoWorkTreeException;
import org.eclipse.jgit.events.ChangeRecorder;
import org.eclipse.jgit.events.ListenerHandle;
import org.eclipse.jgit.junit.RepositoryTestCase;
import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.junit.TestRepository.BranchBuilder;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.treewalk.AbstractTreeIterator;
import org.eclipse.jgit.treewalk.FileTreeIterator;
import org.eclipse.jgit.treewalk.TreeWalk;
import org.eclipse.jgit.treewalk.WorkingTreeIterator;
import org.eclipse.jgit.util.FS;
import org.eclipse.jgit.util.FileUtils;
import org.junit.Assume;
import org.junit.Test;

public class DirCacheCheckoutTest extends RepositoryTestCase {
	private DirCacheCheckout dco;
	protected ObjectId theHead;
	protected ObjectId theMerge;
	private DirCache dirCache;

	private void prescanTwoTrees(ObjectId head, ObjectId merge)
			throws IllegalStateException, IOException {
		DirCache dc = db.lockDirCache();
		try {
			dco = new DirCacheCheckout(db, head, dc, merge);
			dco.preScanTwoTrees();
		} finally {
			dc.unlock();
		}
	}

	private void checkout() throws IOException {
		DirCache dc = db.lockDirCache();
		try {
			dco = new DirCacheCheckout(db, theHead, dc, theMerge);
			dco.checkout();
		} finally {
			dc.unlock();
		}
	}

	private List<String> getRemoved() {
		return dco.getRemoved();
	}

	private Map<String, CheckoutMetadata> getUpdated() {
		return dco.getUpdated();
	}

	private List<String> getConflicts() {
		return dco.getConflicts();
	}

	private static HashMap<String, String> mk(String a) {
		return mkmap(a, a);
	}

	private static HashMap<String, String> mkmap(String... args) {
		if ((args.length % 2) > 0)
			throw new IllegalArgumentException("needs to be pairs");

		HashMap<String, String> map = new HashMap<>();
		for (int i = 0; i < args.length; i += 2) {
			map.put(args[i], args[i + 1]);
		}

		return map;
	}

	@Test
	public void testResetHard() throws IOException, NoFilepatternException,
			GitAPIException {
		ChangeRecorder recorder = new ChangeRecorder();
		ListenerHandle handle = null;
		try (Git git = new Git(db)) {
			handle = db.getListenerList()
					.addWorkingTreeModifiedListener(recorder);
			writeTrashFile("f", "f()");
			writeTrashFile("D/g", "g()");
			git.add().addFilepattern(".").call();
			git.commit().setMessage("inital").call();
			assertIndex(mkmap("f", "f()", "D/g", "g()"));
			recorder.assertNoEvent();
			git.branchCreate().setName("topic").call();
			recorder.assertNoEvent();

			writeTrashFile("f", "f()\nmaster");
			writeTrashFile("D/g", "g()\ng2()");
			writeTrashFile("E/h", "h()");
			git.add().addFilepattern(".").call();
			RevCommit master = git.commit().setMessage("master-1").call();
			assertIndex(mkmap("f", "f()\nmaster", "D/g", "g()\ng2()", "E/h", "h()"));
			recorder.assertNoEvent();

			checkoutBranch("refs/heads/topic");
			assertIndex(mkmap("f", "f()", "D/g", "g()"));
			recorder.assertEvent(new String[] { "f", "D/g" },
					new String[] { "E/h" });

			writeTrashFile("f", "f()\nside");
			assertTrue(new File(db.getWorkTree(), "D/g").delete());
			writeTrashFile("G/i", "i()");
			git.add().addFilepattern(".").call();
			git.add().addFilepattern(".").setUpdate(true).call();
			RevCommit topic = git.commit().setMessage("topic-1").call();
			assertIndex(mkmap("f", "f()\nside", "G/i", "i()"));
			recorder.assertNoEvent();

			writeTrashFile("untracked", "untracked");

			resetHard(master);
			assertIndex(mkmap("f", "f()\nmaster", "D/g", "g()\ng2()", "E/h", "h()"));
			recorder.assertEvent(new String[] { "f", "D/g", "E/h" },
					new String[] { "G", "G/i" });

			resetHard(topic);
			assertIndex(mkmap("f", "f()\nside", "G/i", "i()"));
			assertWorkDir(mkmap("f", "f()\nside", "G/i", "i()", "untracked",
					"untracked"));
			recorder.assertEvent(new String[] { "f", "G/i" },
					new String[] { "D", "D/g", "E", "E/h" });

			assertEquals(MergeStatus.CONFLICTING, git.merge().include(master)
					.call().getMergeStatus());
			assertEquals(
					"[D/g, mode:100644, stage:1][D/g, mode:100644, stage:3][E/h, mode:100644][G/i, mode:100644][f, mode:100644, stage:1][f, mode:100644, stage:2][f, mode:100644, stage:3]",
					indexState(0));
			recorder.assertEvent(new String[] { "f", "D/g", "E/h" },
					ChangeRecorder.EMPTY);

			resetHard(master);
			assertIndex(mkmap("f", "f()\nmaster", "D/g", "g()\ng2()", "E/h", "h()"));
			assertWorkDir(mkmap("f", "f()\nmaster", "D/g", "g()\ng2()", "E/h",
					"h()", "untracked", "untracked"));
			recorder.assertEvent(new String[] { "f", "D/g" },
					new String[] { "G", "G/i" });

		} finally {
			if (handle != null) {
				handle.remove();
			}
		}
	}

	/**
	 * Reset hard from unclean condition.
	 * <p>
	 * WorkDir: Empty <br>
	 * Index: f/g <br>
	 * Merge: x
	 *
	 * @throws Exception
	 */
	@Test
	public void testResetHardFromIndexEntryWithoutFileToTreeWithoutFile()
			throws Exception {
		ChangeRecorder recorder = new ChangeRecorder();
		ListenerHandle handle = null;
		try (Git git = new Git(db)) {
			handle = db.getListenerList()
					.addWorkingTreeModifiedListener(recorder);
			writeTrashFile("x", "x");
			git.add().addFilepattern("x").call();
			RevCommit id1 = git.commit().setMessage("c1").call();

			writeTrashFile("f/g", "f/g");
			git.rm().addFilepattern("x").call();
			recorder.assertEvent(ChangeRecorder.EMPTY, new String[] { "x" });
			git.add().addFilepattern("f/g").call();
			git.commit().setMessage("c2").call();
			deleteTrashFile("f/g");
			deleteTrashFile("f");

			// The actual test
			git.reset().setMode(ResetType.HARD).setRef(id1.getName()).call();
			assertIndex(mkmap("x", "x"));
			recorder.assertEvent(new String[] { "x" }, ChangeRecorder.EMPTY);
		} finally {
			if (handle != null) {
				handle.remove();
			}
		}
	}

	/**
	 * Test first checkout in a repo
	 *
	 * @throws Exception
	 */
	@Test
	public void testInitialCheckout() throws Exception {
		ChangeRecorder recorder = new ChangeRecorder();
		ListenerHandle handle = null;
		try (Git git = new Git(db);
				TestRepository<Repository> db_t = new TestRepository<>(db)) {
			handle = db.getListenerList()
					.addWorkingTreeModifiedListener(recorder);
			BranchBuilder master = db_t.branch("master");
			master.commit().add("f", "1").message("m0").create();
			assertFalse(new File(db.getWorkTree(), "f").exists());
			git.checkout().setName("master").call();
			assertTrue(new File(db.getWorkTree(), "f").exists());
			recorder.assertEvent(new String[] { "f" }, ChangeRecorder.EMPTY);
		} finally {
			if (handle != null) {
				handle.remove();
			}
		}
	}

	private DirCacheCheckout resetHard(RevCommit commit)
			throws NoWorkTreeException,
			CorruptObjectException, IOException {
		DirCacheCheckout dc;
		dc = new DirCacheCheckout(db, null, db.lockDirCache(),
				commit.getTree());
		dc.setFailOnConflict(true);
		assertTrue(dc.checkout());
		return dc;
	}

	private void assertIndex(HashMap<String, String> i)
			throws CorruptObjectException, IOException {
		String expectedValue;
		String path;
		DirCache read = DirCache.read(db.getIndexFile(), db.getFS());

		assertEquals("Index has not the right size.", i.size(),
				read.getEntryCount());
		for (int j = 0; j < read.getEntryCount(); j++) {
			path = read.getEntry(j).getPathString();
			expectedValue = i.get(path);
			assertNotNull("found unexpected entry for path " + path
					+ " in index", expectedValue);
			assertTrue("unexpected content for path " + path
					+ " in index. Expected: <" + expectedValue + ">",
					Arrays.equals(db.open(read.getEntry(j).getObjectId())
							.getCachedBytes(), i.get(path).getBytes(UTF_8)));
		}
	}

	@Test
	public void testRules1thru3_NoIndexEntry() throws IOException {
		ObjectId head = buildTree(mk("foo"));
		ObjectId merge = db.newObjectInserter().insert(Constants.OBJ_TREE,
				new byte[0]);

		prescanTwoTrees(head, merge);

		assertTrue(getRemoved().contains("foo"));

		prescanTwoTrees(merge, head);

		assertTrue(getUpdated().containsKey("foo"));

		merge = buildTree(mkmap("foo", "a"));

		prescanTwoTrees(head, merge);

		assertConflict("foo");
	}

	void setupCase(HashMap<String, String> headEntries, HashMap<String, String> mergeEntries, HashMap<String, String> indexEntries) throws IOException {
		theHead = buildTree(headEntries);
		theMerge = buildTree(mergeEntries);
		buildIndex(indexEntries);
	}

	private void buildIndex(HashMap<String, String> indexEntries) throws IOException {
		dirCache = new DirCache(db.getIndexFile(), db.getFS());
		if (indexEntries != null) {
			assertTrue(dirCache.lock());
			DirCacheEditor editor = dirCache.editor();
			for (java.util.Map.Entry<String,String> e : indexEntries.entrySet()) {
				writeTrashFile(e.getKey(), e.getValue());
				ObjectId id;
				try (ObjectInserter inserter = db.newObjectInserter()) {
					id = inserter.insert(Constants.OBJ_BLOB,
						Constants.encode(e.getValue()));
				}
				editor.add(new DirCacheEditor.DeletePath(e.getKey()));
				editor.add(new DirCacheEditor.PathEdit(e.getKey()) {
					@Override
					public void apply(DirCacheEntry ent) {
						ent.setFileMode(FileMode.REGULAR_FILE);
						ent.setObjectId(id);
						ent.setUpdateNeeded(false);
					}
				});
			}
			assertTrue(editor.commit());
		}

	}

	static final class AddEdit extends PathEdit {

		private final ObjectId data;

		private final long length;

		public AddEdit(String entryPath, ObjectId data, long length) {
			super(entryPath);
			this.data = data;
			this.length = length;
		}

		@Override
		public void apply(DirCacheEntry ent) {
			ent.setFileMode(FileMode.REGULAR_FILE);
			ent.setLength(length);
			ent.setObjectId(data);
		}

	}

	private ObjectId buildTree(HashMap<String, String> headEntries)
			throws IOException {
		DirCache lockDirCache = DirCache.newInCore();
		// assertTrue(lockDirCache.lock());
		DirCacheEditor editor = lockDirCache.editor();
		if (headEntries != null) {
			for (java.util.Map.Entry<String, String> e : headEntries.entrySet()) {
				AddEdit addEdit = new AddEdit(e.getKey(),
						genSha1(e.getValue()), e.getValue().length());
				editor.add(addEdit);
			}
		}
		editor.finish();
		return lockDirCache.writeTree(db.newObjectInserter());
	}

	ObjectId genSha1(String data) {
		try (ObjectInserter w = db.newObjectInserter()) {
			ObjectId id = w.insert(Constants.OBJ_BLOB, data.getBytes(UTF_8));
			w.flush();
			return id;
		} catch (IOException e) {
			fail(e.toString());
		}
		return null;
	}

	protected void go() throws IllegalStateException, IOException {
		prescanTwoTrees(theHead, theMerge);
	}

	@Test
	public void testRules4thru13_IndexEntryNotInHead() throws IOException {
		// rules 4 and 5
		HashMap<String, String> idxMap;

		idxMap = new HashMap<>();
		idxMap.put("foo", "foo");
		setupCase(null, null, idxMap);
		go();

		assertTrue(getUpdated().isEmpty());
		assertTrue(getRemoved().isEmpty());
		assertTrue(getConflicts().isEmpty());

		// rules 6 and 7
		idxMap = new HashMap<>();
		idxMap.put("foo", "foo");
		setupCase(null, idxMap, idxMap);
		go();

		assertAllEmpty();

		// rules 8 and 9
		HashMap<String, String> mergeMap;
		mergeMap = new HashMap<>();

		mergeMap.put("foo", "merge");
		setupCase(null, mergeMap, idxMap);
		go();

		assertTrue(getUpdated().isEmpty());
		assertTrue(getRemoved().isEmpty());
		assertTrue(getConflicts().contains("foo"));

		// rule 10

		HashMap<String, String> headMap = new HashMap<>();
		headMap.put("foo", "foo");
		setupCase(headMap, null, idxMap);
		go();

		assertTrue(getRemoved().contains("foo"));
		assertTrue(getUpdated().isEmpty());
		assertTrue(getConflicts().isEmpty());

		// rule 11
		setupCase(headMap, null, idxMap);
		assertTrue(new File(trash, "foo").delete());
		writeTrashFile("foo", "bar");
		db.readDirCache().getEntry(0).setUpdateNeeded(true);
		go();

		assertTrue(getRemoved().isEmpty());
		assertTrue(getUpdated().isEmpty());
		assertTrue(getConflicts().contains("foo"));

		// rule 12 & 13
		headMap.put("foo", "head");
		setupCase(headMap, null, idxMap);
		go();

		assertTrue(getRemoved().isEmpty());
		assertTrue(getUpdated().isEmpty());
		assertTrue(getConflicts().contains("foo"));

		// rules 14 & 15
		setupCase(headMap, headMap, idxMap);
		go();

		assertAllEmpty();

		// rules 16 & 17
		setupCase(headMap, mergeMap, idxMap); go();
		assertTrue(getConflicts().contains("foo"));

		// rules 18 & 19
		setupCase(headMap, idxMap, idxMap); go();
		assertAllEmpty();

		// rule 20
		setupCase(idxMap, mergeMap, idxMap); go();
		assertTrue(getUpdated().containsKey("foo"));

		// rules 21
		setupCase(idxMap, mergeMap, idxMap);
		assertTrue(new File(trash, "foo").delete());
		writeTrashFile("foo", "bar");
		db.readDirCache().getEntry(0).setUpdateNeeded(true);
		go();
		assertTrue(getConflicts().contains("foo"));
	}

	private void assertAllEmpty() {
		assertTrue(getRemoved().isEmpty());
		assertTrue(getUpdated().isEmpty());
		assertTrue(getConflicts().isEmpty());
	}

	/*-
	 * Directory/File Conflict cases:
	 * It's entirely possible that in practice a number of these may be equivalent
	 * to the cases described in git-read-tree.txt. As long as it does the right thing,
	 * that's all I care about. These are basically reverse-engineered from
	 * what git currently does. If there are tests for these in git, it's kind of
	 * hard to track them all down...
	 *
	 *     H        I       M     Clean     H==M     H==I    I==M         Result
	 *     ------------------------------------------------------------------
	 *1    D        D       F       Y         N       Y       N           Update
	 *2    D        D       F       N         N       Y       N           Conflict
	 *3    D        F       D                 Y       N       N           Keep
	 *4    D        F       D                 N       N       N           Conflict
	 *5    D        F       F       Y         N       N       Y           Keep
	 *5b   D        F       F       Y         N       N       N           Conflict
	 *6    D        F       F       N         N       N       Y           Keep
	 *6b   D        F       F       N         N       N       N           Conflict
	 *7    F        D       F       Y         Y       N       N           Update
	 *8    F        D       F       N         Y       N       N           Conflict
	 *9    F        D       F       Y         N       N       N           Update
	 *10   F        D       D                 N       N       Y           Keep
	 *11   F        D       D                 N       N       N           Conflict
	 *12   F        F       D       Y         N       Y       N           Update
	 *13   F        F       D       N         N       Y       N           Conflict
	 *14   F        F       D                 N       N       N           Conflict
	 *15   0        F       D                 N       N       N           Conflict
	 *16   0        D       F       Y         N       N       N           Update
	 *17   0        D       F                 N       N       N           Conflict
	 *18   F        0       D                                             Update
	 *19   D        0       F                                             Update
	 */
	@Test
	public void testDirectoryFileSimple() throws IOException {
		ObjectId treeDF = buildTree(mkmap("DF", "DF"));
		ObjectId treeDFDF = buildTree(mkmap("DF/DF", "DF/DF"));
		buildIndex(mkmap("DF", "DF"));

		prescanTwoTrees(treeDF, treeDFDF);

		assertTrue(getRemoved().contains("DF"));
		assertTrue(getUpdated().containsKey("DF/DF"));

		recursiveDelete(new File(trash, "DF"));
		buildIndex(mkmap("DF/DF", "DF/DF"));

		prescanTwoTrees(treeDFDF, treeDF);
		assertTrue(getRemoved().contains("DF/DF"));
		assertTrue(getUpdated().containsKey("DF"));
	}

	@Test
	public void testDirectoryFileConflicts_1() throws Exception {
		// 1
		doit(mk("DF/DF"), mk("DF"), mk("DF/DF"));
		assertNoConflicts();
		assertUpdated("DF");
		assertRemoved("DF/DF");
	}

	@Test
	public void testDirectoryFileConflicts_2() throws Exception {
		// 2
		setupCase(mk("DF/DF"), mk("DF"), mk("DF/DF"));
		writeTrashFile("DF/DF", "different");
		go();
		assertConflict("DF/DF");

	}

	@Test
	public void testDirectoryFileConflicts_3() throws Exception {
		// 3
		doit(mk("DF/DF"), mk("DF/DF"), mk("DF"));
		assertNoConflicts();
	}

	@Test
	public void testDirectoryFileConflicts_4() throws Exception {
		// 4 (basically same as 3, just with H and M different)
		doit(mk("DF/DF"), mkmap("DF/DF", "foo"), mk("DF"));
		assertConflict("DF/DF");

	}

	@Test
	public void testDirectoryFileConflicts_5() throws Exception {
		// 5
		doit(mk("DF/DF"), mk("DF"), mk("DF"));
		assertRemoved("DF/DF");
		assertEquals(0, dco.getConflicts().size());
		assertEquals(0, dco.getUpdated().size());
	}

	@Test
	public void testDirectoryFileConflicts_5b() throws Exception {
		// 5
		doit(mk("DF/DF"), mkmap("DF", "different"), mk("DF"));
		assertRemoved("DF/DF");
		assertConflict("DF");
		assertEquals(0, dco.getUpdated().size());
	}

	@Test
	public void testDirectoryFileConflicts_6() throws Exception {
		// 6
		setupCase(mk("DF/DF"), mk("DF"), mk("DF"));
		writeTrashFile("DF", "different");
		go();
		assertRemoved("DF/DF");
		assertEquals(0, dco.getConflicts().size());
		assertEquals(0, dco.getUpdated().size());
	}

	@Test
	public void testDirectoryFileConflicts_6b() throws Exception {
		// 6
		setupCase(mk("DF/DF"), mk("DF"), mkmap("DF", "different"));
		writeTrashFile("DF", "again different");
		go();
		assertRemoved("DF/DF");
		assertConflict("DF");
		assertEquals(0, dco.getUpdated().size());
	}

	@Test
	public void testDirectoryFileConflicts_7() throws Exception {
		// 7
		doit(mk("DF"), mk("DF"), mk("DF/DF"));
		assertUpdated("DF");
		assertRemoved("DF/DF");

		cleanUpDF();
		setupCase(mk("DF/DF"), mk("DF/DF"), mk("DF/DF/DF/DF/DF"));
		go();
		assertRemoved("DF/DF/DF/DF/DF");
		assertUpdated("DF/DF");

		cleanUpDF();
		setupCase(mk("DF/DF"), mk("DF/DF"), mk("DF/DF/DF/DF/DF"));
		writeTrashFile("DF/DF/DF/DF/DF", "diff");
		go();
		assertConflict("DF/DF/DF/DF/DF");

		// assertUpdated("DF/DF");
		// Why do we expect an update on DF/DF. H==M,
		// H&M are files and index contains a dir, index
		// is dirty: that case is not in the table but
		// we cannot update DF/DF to a file, this would
		// require that we delete DF/DF/DF/DF/DF in workdir
		// throwing away unsaved contents.
		// This test would fail in DirCacheCheckoutTests.
	}

	@Test
	public void testDirectoryFileConflicts_8() throws Exception {
		// 8
		setupCase(mk("DF"), mk("DF"), mk("DF/DF"));
		recursiveDelete(new File(db.getWorkTree(), "DF"));
		writeTrashFile("DF", "xy");
		go();
		assertConflict("DF/DF");
	}

	@Test
	public void testDirectoryFileConflicts_9() throws Exception {
		// 9
		doit(mkmap("DF", "QP"), mkmap("DF", "QP"), mkmap("DF/DF", "DF/DF"));
		assertRemoved("DF/DF");
		assertUpdated("DF");
	}

	@Test
	public void testDirectoryFileConflicts_10() throws Exception {
		// 10
		cleanUpDF();
		doit(mk("DF"), mk("DF/DF"), mk("DF/DF"));
		assertNoConflicts();
	}

	@Test
	public void testDirectoryFileConflicts_11() throws Exception {
		// 11
		doit(mk("DF"), mk("DF/DF"), mkmap("DF/DF", "asdf"));
		assertConflict("DF/DF");
	}

	@Test
	public void testDirectoryFileConflicts_12() throws Exception {
		// 12
		cleanUpDF();
		doit(mk("DF"), mk("DF/DF"), mk("DF"));
		assertRemoved("DF");
		assertUpdated("DF/DF");
	}

	@Test
	public void testDirectoryFileConflicts_13() throws Exception {
		// 13
		cleanUpDF();
		setupCase(mk("DF"), mk("DF/DF"), mk("DF"));
		writeTrashFile("DF", "asdfsdf");
		go();
		assertConflict("DF");
		assertUpdated("DF/DF");
	}

	@Test
	public void testDirectoryFileConflicts_14() throws Exception {
		// 14
		cleanUpDF();
		doit(mk("DF"), mk("DF/DF"), mkmap("DF", "Foo"));
		assertConflict("DF");
		assertUpdated("DF/DF");
	}

	@Test
	public void testDirectoryFileConflicts_15() throws Exception {
		// 15
		doit(mkmap(), mk("DF/DF"), mk("DF"));

		// This test would fail in DirCacheCheckoutTests. I think this test is wrong,
		// it should check for conflicts according to rule 15
		// assertRemoved("DF");

		assertUpdated("DF/DF");
	}

	@Test
	public void testDirectoryFileConflicts_15b() throws Exception {
		// 15, take 2, just to check multi-leveled
		doit(mkmap(), mk("DF/DF/DF/DF"), mk("DF"));

		// I think this test is wrong, it should
		// check for conflicts according to rule 15
		// This test would fail in DirCacheCheckouts
		// assertRemoved("DF");

		assertUpdated("DF/DF/DF/DF");
	}

	@Test
	public void testDirectoryFileConflicts_16() throws Exception {
		// 16
		cleanUpDF();
		doit(mkmap(), mk("DF"), mk("DF/DF/DF"));
		assertRemoved("DF/DF/DF");
		assertUpdated("DF");
	}

	@Test
	public void testDirectoryFileConflicts_17() throws Exception {
		// 17
		cleanUpDF();
		setupCase(mkmap(), mk("DF"), mk("DF/DF/DF"));
		writeTrashFile("DF/DF/DF", "asdf");
		go();
		assertConflict("DF/DF/DF");

		// Why do we expect an update on DF. If we really update
		// DF and update also the working tree we would have to
		// overwrite a dirty file in the work-tree DF/DF/DF
		// This test would fail in DirCacheCheckout
		// assertUpdated("DF");
	}

	@Test
	public void testDirectoryFileConflicts_18() throws Exception {
		// 18
		cleanUpDF();
		doit(mk("DF/DF"), mk("DF/DF/DF/DF"), null);
		assertRemoved("DF/DF");
		assertUpdated("DF/DF/DF/DF");
	}

	@Test
	public void testDirectoryFileConflicts_19() throws Exception {
		// 19
		cleanUpDF();
		doit(mk("DF/DF/DF/DF"), mk("DF/DF/DF"), null);
		assertRemoved("DF/DF/DF/DF");
		assertUpdated("DF/DF/DF");
	}

	protected void cleanUpDF() throws Exception {
		tearDown();
		setUp();
		recursiveDelete(new File(trash, "DF"));
	}

	protected void assertConflict(String s) {
		assertTrue(getConflicts().contains(s));
	}

	protected void assertUpdated(String s) {
		assertTrue(getUpdated().containsKey(s));
	}

	protected void assertRemoved(String s) {
		assertTrue(getRemoved().contains(s));
	}

	protected void assertNoConflicts() {
		assertTrue(getConflicts().isEmpty());
	}

	protected void doit(HashMap<String, String> h, HashMap<String, String> m, HashMap<String, String> i)
			throws IOException {
				setupCase(h, m, i);
				go();
			}

	@Test
	public void testUntrackedConflicts() throws IOException {
		setupCase(null, mk("foo"), null);
		writeTrashFile("foo", "foo");
		go();

		// test that we don't overwrite untracked files when there is a HEAD
		recursiveDelete(new File(trash, "foo"));
		setupCase(mk("other"), mkmap("other", "other", "foo", "foo"),
				mk("other"));
		writeTrashFile("foo", "bar");
		try {
			checkout();
			fail("didn't get the expected exception");
		} catch (CheckoutConflictException e) {
			assertConflict("foo");
			assertEquals("foo", e.getConflictingFiles()[0]);
			assertWorkDir(mkmap("foo", "bar", "other", "other"));
			assertIndex(mk("other"));
		}

		// test that we don't overwrite untracked files when there is no HEAD
		recursiveDelete(new File(trash, "other"));
		recursiveDelete(new File(trash, "foo"));
		setupCase(null, mk("foo"), null);
		writeTrashFile("foo", "bar");
		try {
			checkout();
			fail("didn't get the expected exception");
		} catch (CheckoutConflictException e) {
			assertConflict("foo");
			assertWorkDir(mkmap("foo", "bar"));
			assertIndex(mkmap("other", "other"));
		}

		// TODO: Why should we expect conflicts here?
		// H and M are empty and according to rule #5 of
		// the carry-over rules a dirty index is no reason
		// for a conflict. (I also feel it should be a
		// conflict because we are going to overwrite
		// unsaved content in the working tree
		// This test would fail in DirCacheCheckoutTest
		// assertConflict("foo");

		recursiveDelete(new File(trash, "foo"));
		recursiveDelete(new File(trash, "other"));
		setupCase(null, mk("foo"), null);
		writeTrashFile("foo/bar/baz", "");
		writeTrashFile("foo/blahblah", "");
		go();

		assertConflict("foo");
		assertConflict("foo/bar/baz");
		assertConflict("foo/blahblah");

		recursiveDelete(new File(trash, "foo"));

		setupCase(mkmap("foo/bar", "", "foo/baz", ""),
				mk("foo"), mkmap("foo/bar", "", "foo/baz", ""));
		assertTrue(new File(trash, "foo/bar").exists());
		go();

		assertNoConflicts();
	}

	@Test
	public void testCloseNameConflictsX0() throws IOException {
		setupCase(mkmap("a/a", "a/a-c"), mkmap("a/a","a/a", "b.b/b.b","b.b/b.bs"), mkmap("a/a", "a/a-c") );
		checkout();
		assertIndex(mkmap("a/a", "a/a", "b.b/b.b", "b.b/b.bs"));
		assertWorkDir(mkmap("a/a", "a/a", "b.b/b.b", "b.b/b.bs"));
		go();
		assertIndex(mkmap("a/a", "a/a", "b.b/b.b", "b.b/b.bs"));
		assertWorkDir(mkmap("a/a", "a/a", "b.b/b.b", "b.b/b.bs"));
		assertNoConflicts();
	}

	@Test
	public void testCloseNameConflicts1() throws IOException {
		setupCase(mkmap("a/a", "a/a-c"), mkmap("a/a","a/a", "a.a/a.a","a.a/a.a"), mkmap("a/a", "a/a-c") );
		checkout();
		assertIndex(mkmap("a/a", "a/a", "a.a/a.a", "a.a/a.a"));
		assertWorkDir(mkmap("a/a", "a/a", "a.a/a.a", "a.a/a.a"));
		go();
		assertIndex(mkmap("a/a", "a/a", "a.a/a.a", "a.a/a.a"));
		assertWorkDir(mkmap("a/a", "a/a", "a.a/a.a", "a.a/a.a"));
		assertNoConflicts();
	}

	@Test
	public void testCheckoutHierarchy() throws IOException {
		setupCase(
				mkmap("a", "a", "b/c", "b/c", "d", "d", "e/f", "e/f", "e/g",
						"e/g"),
				mkmap("a", "a2", "b/c", "b/c", "d", "d", "e/f", "e/f", "e/g",
						"e/g2"),
				mkmap("a", "a", "b/c", "b/c", "d", "d", "e/f", "e/f", "e/g",
						"e/g3"));
		try {
			checkout();
			fail("did not throw CheckoutConflictException");
		} catch (CheckoutConflictException e) {
			assertWorkDir(mkmap("a", "a", "b/c", "b/c", "d", "d", "e/f",
					"e/f", "e/g", "e/g3"));
			assertConflict("e/g");
			assertEquals("e/g", e.getConflictingFiles()[0]);
		}
	}

	@Test
	public void testCheckoutOutChanges() throws IOException {
		setupCase(mk("foo"), mk("foo/bar"), mk("foo"));
		checkout();
		assertIndex(mk("foo/bar"));
		assertWorkDir(mk("foo/bar"));

		assertFalse(new File(trash, "foo").isFile());
		assertTrue(new File(trash, "foo/bar").isFile());
		recursiveDelete(new File(trash, "foo"));

		assertWorkDir(mkmap());

		setupCase(mk("foo/bar"), mk("foo"), mk("foo/bar"));
		checkout();

		assertIndex(mk("foo"));
		assertWorkDir(mk("foo"));

		assertFalse(new File(trash, "foo/bar").isFile());
		assertTrue(new File(trash, "foo").isFile());

		setupCase(mk("foo"), mkmap("foo", "qux"), mkmap("foo", "bar"));

		assertIndex(mkmap("foo", "bar"));
		assertWorkDir(mkmap("foo", "bar"));

		try {
			checkout();
			fail("did not throw exception");
		} catch (CheckoutConflictException e) {
			assertIndex(mkmap("foo", "bar"));
			assertWorkDir(mkmap("foo", "bar"));
		}
	}

	@Test
	public void testCheckoutChangeLinkToEmptyDir() throws Exception {
		Assume.assumeTrue(FS.DETECTED.supportsSymlinks());
		String fname = "was_file";
		ChangeRecorder recorder = new ChangeRecorder();
		ListenerHandle handle = null;
		try (Git git = new Git(db)) {
			handle = db.getListenerList()
					.addWorkingTreeModifiedListener(recorder);
			// Add a file
			writeTrashFile(fname, "a");
			git.add().addFilepattern(fname).call();

			// Add a link to file
			String linkName = "link";
			File link = writeLink(linkName, fname).toFile();
			git.add().addFilepattern(linkName).call();
			git.commit().setMessage("Added file and link").call();

			assertWorkDir(mkmap(linkName, "a", fname, "a"));

			// replace link with empty directory
			FileUtils.delete(link);
			FileUtils.mkdir(link);
			assertTrue("Link must be a directory now", link.isDirectory());

			// modify file
			writeTrashFile(fname, "b");
			assertWorkDir(mkmap(fname, "b", linkName, "/"));
			recorder.assertNoEvent();

			// revert both paths to HEAD state
			git.checkout().setStartPoint(Constants.HEAD).addPath(fname)
					.addPath(linkName).call();

			assertWorkDir(mkmap(fname, "a", linkName, "a"));
			recorder.assertEvent(new String[] { fname, linkName },
					ChangeRecorder.EMPTY);

			Status st = git.status().call();
			assertTrue(st.isClean());
		} finally {
			if (handle != null) {
				handle.remove();
			}
		}
	}

	@Test
	public void testCheckoutChangeLinkToEmptyDirs() throws Exception {
		Assume.assumeTrue(FS.DETECTED.supportsSymlinks());
		String fname = "was_file";
		ChangeRecorder recorder = new ChangeRecorder();
		ListenerHandle handle = null;
		try (Git git = new Git(db)) {
			handle = db.getListenerList()
					.addWorkingTreeModifiedListener(recorder);
			// Add a file
			writeTrashFile(fname, "a");
			git.add().addFilepattern(fname).call();

			// Add a link to file
			String linkName = "link";
			File link = writeLink(linkName, fname).toFile();
			git.add().addFilepattern(linkName).call();
			git.commit().setMessage("Added file and link").call();

			assertWorkDir(mkmap(linkName, "a", fname, "a"));

			// replace link with directory containing only directories, no files
			FileUtils.delete(link);
			FileUtils.mkdirs(new File(link, "dummyDir"));
			assertTrue("Link must be a directory now", link.isDirectory());

			assertFalse("Must not delete non empty directory", link.delete());

			// modify file
			writeTrashFile(fname, "b");
			assertWorkDir(mkmap(fname, "b", linkName + "/dummyDir", "/"));
			recorder.assertNoEvent();

			// revert both paths to HEAD state
			git.checkout().setStartPoint(Constants.HEAD).addPath(fname)
					.addPath(linkName).call();

			assertWorkDir(mkmap(fname, "a", linkName, "a"));
			recorder.assertEvent(new String[] { fname, linkName },
					ChangeRecorder.EMPTY);

			Status st = git.status().call();
			assertTrue(st.isClean());
		} finally {
			if (handle != null) {
				handle.remove();
			}
		}
	}

	@Test
	public void testCheckoutChangeLinkToNonEmptyDirs() throws Exception {
		Assume.assumeTrue(FS.DETECTED.supportsSymlinks());
		String fname = "file";
		ChangeRecorder recorder = new ChangeRecorder();
		ListenerHandle handle = null;
		try (Git git = new Git(db)) {
			handle = db.getListenerList()
					.addWorkingTreeModifiedListener(recorder);
			// Add a file
			writeTrashFile(fname, "a");
			git.add().addFilepattern(fname).call();

			// Add a link to file
			String linkName = "link";
			File link = writeLink(linkName, fname).toFile();
			git.add().addFilepattern(linkName).call();
			git.commit().setMessage("Added file and link").call();

			assertWorkDir(mkmap(linkName, "a", fname, "a"));

			// replace link with directory containing only directories, no files
			FileUtils.delete(link);

			// create but do not add a file in the new directory to the index
			writeTrashFile(linkName + "/dir1", "file1", "c");

			// create but do not add a file in the new directory to the index
			writeTrashFile(linkName + "/dir2", "file2", "d");

			assertTrue("File must be a directory now", link.isDirectory());
			assertFalse("Must not delete non empty directory", link.delete());

			// 2 extra files are created
			assertWorkDir(mkmap(fname, "a", linkName + "/dir1/file1", "c",
					linkName + "/dir2/file2", "d"));
			recorder.assertNoEvent();

			// revert path to HEAD state
			git.checkout().setStartPoint(Constants.HEAD).addPath(linkName)
					.call();

			// expect only the one added to the index
			assertWorkDir(mkmap(linkName, "a", fname, "a"));
			recorder.assertEvent(new String[] { linkName },
					ChangeRecorder.EMPTY);

			Status st = git.status().call();
			assertTrue(st.isClean());
		} finally {
			if (handle != null) {
				handle.remove();
			}
		}
	}

	@Test
	public void testCheckoutChangeLinkToNonEmptyDirsAndNewIndexEntry()
			throws Exception {
		Assume.assumeTrue(FS.DETECTED.supportsSymlinks());
		String fname = "file";
		ChangeRecorder recorder = new ChangeRecorder();
		ListenerHandle handle = null;
		try (Git git = new Git(db)) {
			handle = db.getListenerList()
					.addWorkingTreeModifiedListener(recorder);
			// Add a file
			writeTrashFile(fname, "a");
			git.add().addFilepattern(fname).call();

			// Add a link to file
			String linkName = "link";
			File link = writeLink(linkName, fname).toFile();
			git.add().addFilepattern(linkName).call();
			git.commit().setMessage("Added file and link").call();

			assertWorkDir(mkmap(linkName, "a", fname, "a"));

			// replace link with directory containing only directories, no files
			FileUtils.delete(link);

			// create and add a file in the new directory to the index
			writeTrashFile(linkName + "/dir1", "file1", "c");
			git.add().addFilepattern(linkName + "/dir1/file1").call();

			// create but do not add a file in the new directory to the index
			writeTrashFile(linkName + "/dir2", "file2", "d");

			assertTrue("File must be a directory now", link.isDirectory());
			assertFalse("Must not delete non empty directory", link.delete());

			// 2 extra files are created
			assertWorkDir(mkmap(fname, "a", linkName + "/dir1/file1", "c",
					linkName + "/dir2/file2", "d"));
			recorder.assertNoEvent();

			// revert path to HEAD state
			git.checkout().setStartPoint(Constants.HEAD).addPath(linkName)
					.call();

			// original file and link
			assertWorkDir(mkmap(linkName, "a", fname, "a"));
			recorder.assertEvent(new String[] { linkName },
					ChangeRecorder.EMPTY);

			Status st = git.status().call();
			assertTrue(st.isClean());
		} finally {
			if (handle != null) {
				handle.remove();
			}
		}
	}

	@Test
	public void testCheckoutChangeFileToEmptyDir() throws Exception {
		String fname = "was_file";
		ChangeRecorder recorder = new ChangeRecorder();
		ListenerHandle handle = null;
		try (Git git = new Git(db)) {
			handle = db.getListenerList()
					.addWorkingTreeModifiedListener(recorder);
			// Add a file
			File file = writeTrashFile(fname, "a");
			git.add().addFilepattern(fname).call();
			git.commit().setMessage("Added file").call();

			// replace file with empty directory
			FileUtils.delete(file);
			FileUtils.mkdir(file);
			assertTrue("File must be a directory now", file.isDirectory());
			assertWorkDir(mkmap(fname, "/"));
			recorder.assertNoEvent();

			// revert path to HEAD state
			git.checkout().setStartPoint(Constants.HEAD).addPath(fname).call();
			assertWorkDir(mkmap(fname, "a"));
			recorder.assertEvent(new String[] { fname }, ChangeRecorder.EMPTY);

			Status st = git.status().call();
			assertTrue(st.isClean());
		} finally {
			if (handle != null) {
				handle.remove();
			}
		}
	}

	@Test
	public void testCheckoutChangeFileToEmptyDirs() throws Exception {
		String fname = "was_file";
		ChangeRecorder recorder = new ChangeRecorder();
		ListenerHandle handle = null;
		try (Git git = new Git(db)) {
			handle = db.getListenerList()
					.addWorkingTreeModifiedListener(recorder);
			// Add a file
			File file = writeTrashFile(fname, "a");
			git.add().addFilepattern(fname).call();
			git.commit().setMessage("Added file").call();

			// replace file with directory containing only directories, no files
			FileUtils.delete(file);
			FileUtils.mkdirs(new File(file, "dummyDir"));
			assertTrue("File must be a directory now", file.isDirectory());
			assertFalse("Must not delete non empty directory", file.delete());

			assertWorkDir(mkmap(fname + "/dummyDir", "/"));
			recorder.assertNoEvent();

			// revert path to HEAD state
			git.checkout().setStartPoint(Constants.HEAD).addPath(fname).call();
			assertWorkDir(mkmap(fname, "a"));
			recorder.assertEvent(new String[] { fname }, ChangeRecorder.EMPTY);

			Status st = git.status().call();
			assertTrue(st.isClean());
		} finally {
			if (handle != null) {
				handle.remove();
			}
		}
	}

	@Test
	public void testCheckoutChangeFileToNonEmptyDirs() throws Exception {
		String fname = "was_file";
		ChangeRecorder recorder = new ChangeRecorder();
		ListenerHandle handle = null;
		try (Git git = new Git(db)) {
			handle = db.getListenerList()
					.addWorkingTreeModifiedListener(recorder);
			// Add a file
			File file = writeTrashFile(fname, "a");
			git.add().addFilepattern(fname).call();
			git.commit().setMessage("Added file").call();

			assertWorkDir(mkmap(fname, "a"));

			// replace file with directory containing only directories, no files
			FileUtils.delete(file);

			// create but do not add a file in the new directory to the index
			writeTrashFile(fname + "/dir1", "file1", "c");

			// create but do not add a file in the new directory to the index
			writeTrashFile(fname + "/dir2", "file2", "d");

			assertTrue("File must be a directory now", file.isDirectory());
			assertFalse("Must not delete non empty directory", file.delete());

			// 2 extra files are created
			assertWorkDir(mkmap(fname + "/dir1/file1", "c",
					fname + "/dir2/file2", "d"));
			recorder.assertNoEvent();

			// revert path to HEAD state
			git.checkout().setStartPoint(Constants.HEAD).addPath(fname).call();

			// expect only the one added to the index
			assertWorkDir(mkmap(fname, "a"));
			recorder.assertEvent(new String[] { fname }, ChangeRecorder.EMPTY);

			Status st = git.status().call();
			assertTrue(st.isClean());
		} finally {
			if (handle != null) {
				handle.remove();
			}
		}
	}

	@Test
	public void testCheckoutChangeFileToNonEmptyDirsAndNewIndexEntry()
			throws Exception {
		String fname = "was_file";
		ChangeRecorder recorder = new ChangeRecorder();
		ListenerHandle handle = null;
		try (Git git = new Git(db)) {
			handle = db.getListenerList()
					.addWorkingTreeModifiedListener(recorder);
			// Add a file
			File file = writeTrashFile(fname, "a");
			git.add().addFilepattern(fname).call();
			git.commit().setMessage("Added file").call();

			assertWorkDir(mkmap(fname, "a"));

			// replace file with directory containing only directories, no files
			FileUtils.delete(file);

			// create and add a file in the new directory to the index
			writeTrashFile(fname + "/dir", "file1", "c");
			git.add().addFilepattern(fname + "/dir/file1").call();

			// create but do not add a file in the new directory to the index
			writeTrashFile(fname + "/dir", "file2", "d");

			assertTrue("File must be a directory now", file.isDirectory());
			assertFalse("Must not delete non empty directory", file.delete());

			// 2 extra files are created
			assertWorkDir(mkmap(fname + "/dir/file1", "c", fname + "/dir/file2",
					"d"));
			recorder.assertNoEvent();

			// revert path to HEAD state
			git.checkout().setStartPoint(Constants.HEAD).addPath(fname).call();
			assertWorkDir(mkmap(fname, "a"));
			recorder.assertEvent(new String[] { fname }, ChangeRecorder.EMPTY);
			Status st = git.status().call();
			assertTrue(st.isClean());
		} finally {
			if (handle != null) {
				handle.remove();
			}
		}
	}

	@Test
	public void testCheckoutOutChangesAutoCRLFfalse() throws IOException {
		setupCase(mk("foo"), mkmap("foo/bar", "foo\nbar"), mk("foo"));
		checkout();
		assertIndex(mkmap("foo/bar", "foo\nbar"));
		assertWorkDir(mkmap("foo/bar", "foo\nbar"));
	}

	@Test
	public void testCheckoutOutChangesAutoCRLFInput() throws IOException {
		setupCase(mk("foo"), mkmap("foo/bar", "foo\nbar"), mk("foo"));
		db.getConfig().setString("core", null, "autocrlf", "input");
		checkout();
		assertIndex(mkmap("foo/bar", "foo\nbar"));
		assertWorkDir(mkmap("foo/bar", "foo\nbar"));
	}

	@Test
	public void testCheckoutOutChangesAutoCRLFtrue() throws IOException {
		setupCase(mk("foo"), mkmap("foo/bar", "foo\nbar"), mk("foo"));
		db.getConfig().setString("core", null, "autocrlf", "true");
		checkout();
		assertIndex(mkmap("foo/bar", "foo\nbar"));
		assertWorkDir(mkmap("foo/bar", "foo\r\nbar"));
	}

	@Test
	public void testCheckoutOutChangesAutoCRLFtrueBinary() throws IOException {
		setupCase(mk("foo"), mkmap("foo/bar", "foo\nb\u0000ar"), mk("foo"));
		db.getConfig().setString("core", null, "autocrlf", "true");
		checkout();
		assertIndex(mkmap("foo/bar", "foo\nb\u0000ar"));
		assertWorkDir(mkmap("foo/bar", "foo\nb\u0000ar"));
	}

	@Test
	public void testCheckoutUncachedChanges() throws IOException {
		setupCase(mk("foo"), mk("foo"), mk("foo"));
		writeTrashFile("foo", "otherData");
		checkout();
		assertIndex(mk("foo"));
		assertWorkDir(mkmap("foo", "otherData"));
		assertTrue(new File(trash, "foo").isFile());
	}

	@Test
	public void testDontOverwriteDirtyFile() throws IOException {
		setupCase(mk("foo"), mk("other"), mk("foo"));
		writeTrashFile("foo", "different");
		try {
			checkout();
			fail("Didn't got the expected conflict");
		} catch (CheckoutConflictException e) {
			assertIndex(mk("foo"));
			assertWorkDir(mkmap("foo", "different"));
			assertEquals(Arrays.asList("foo"), getConflicts());
			assertTrue(new File(trash, "foo").isFile());
		}
	}

	@Test
	public void testDontOverwriteEmptyFolder() throws IOException {
		setupCase(mk("foo"), mk("foo"), mk("foo"));
		FileUtils.mkdir(new File(db.getWorkTree(), "d"));
		checkout();
		assertWorkDir(mkmap("foo", "foo", "d", "/"));
	}

	@Test
	public void testOverwriteUntrackedIgnoredFile() throws IOException,
			GitAPIException {
		String fname="file.txt";
		ChangeRecorder recorder = new ChangeRecorder();
		ListenerHandle handle = null;
		try (Git git = new Git(db)) {
			handle = db.getListenerList()
					.addWorkingTreeModifiedListener(recorder);
			// Add a file
			writeTrashFile(fname, "a");
			git.add().addFilepattern(fname).call();
			git.commit().setMessage("create file").call();

			// Create branch
			git.branchCreate().setName("side").call();

			// Modify file
			writeTrashFile(fname, "b");
			git.add().addFilepattern(fname).call();
			git.commit().setMessage("modify file").call();
			recorder.assertNoEvent();

			// Switch branches
			git.checkout().setName("side").call();
			recorder.assertEvent(new String[] { fname }, ChangeRecorder.EMPTY);
			git.rm().addFilepattern(fname).call();
			recorder.assertEvent(ChangeRecorder.EMPTY, new String[] { fname });
			writeTrashFile(".gitignore", fname);
			git.add().addFilepattern(".gitignore").call();
			git.commit().setMessage("delete and ignore file").call();

			writeTrashFile(fname, "Something different");
			recorder.assertNoEvent();
			git.checkout().setName("master").call();
			assertWorkDir(mkmap(fname, "b"));
			recorder.assertEvent(new String[] { fname },
					new String[] { ".gitignore" });
			assertTrue(git.status().call().isClean());
		} finally {
			if (handle != null) {
				handle.remove();
			}
		}
	}

	@Test
	public void testOverwriteUntrackedFileModeChange()
			throws IOException, GitAPIException {
		String fname = "file.txt";
		ChangeRecorder recorder = new ChangeRecorder();
		ListenerHandle handle = null;
		try (Git git = new Git(db)) {
			handle = db.getListenerList()
					.addWorkingTreeModifiedListener(recorder);
			// Add a file
			File file = writeTrashFile(fname, "a");
			git.add().addFilepattern(fname).call();
			git.commit().setMessage("create file").call();
			assertWorkDir(mkmap(fname, "a"));

			// Create branch
			git.branchCreate().setName("side").call();

			// Switch branches
			git.checkout().setName("side").call();
			recorder.assertNoEvent();

			// replace file with directory containing files
			FileUtils.delete(file);

			// create and add a file in the new directory to the index
			writeTrashFile(fname + "/dir1", "file1", "c");
			git.add().addFilepattern(fname + "/dir1/file1").call();

			// create but do not add a file in the new directory to the index
			writeTrashFile(fname + "/dir2", "file2", "d");

			assertTrue("File must be a directory now", file.isDirectory());
			assertFalse("Must not delete non empty directory", file.delete());

			// 2 extra files are created
			assertWorkDir(mkmap(fname + "/dir1/file1", "c",
					fname + "/dir2/file2", "d"));

			try {
				git.checkout().setName("master").call();
				fail("did not throw exception");
			} catch (Exception e) {
				// 2 extra files are still there
				assertWorkDir(mkmap(fname + "/dir1/file1", "c",
						fname + "/dir2/file2", "d"));
			}
			recorder.assertNoEvent();
		} finally {
			if (handle != null) {
				handle.remove();
			}
		}
	}

	@Test
	public void testOverwriteUntrackedLinkModeChange()
			throws Exception {
		Assume.assumeTrue(FS.DETECTED.supportsSymlinks());
		String fname = "file.txt";
		ChangeRecorder recorder = new ChangeRecorder();
		ListenerHandle handle = null;
		try (Git git = new Git(db)) {
			handle = db.getListenerList()
					.addWorkingTreeModifiedListener(recorder);
			// Add a file
			writeTrashFile(fname, "a");
			git.add().addFilepattern(fname).call();

			// Add a link to file
			String linkName = "link";
			File link = writeLink(linkName, fname).toFile();
			git.add().addFilepattern(linkName).call();
			git.commit().setMessage("Added file and link").call();

			assertWorkDir(mkmap(linkName, "a", fname, "a"));

			// Create branch
			git.branchCreate().setName("side").call();

			// Switch branches
			git.checkout().setName("side").call();
			recorder.assertNoEvent();

			// replace link with directory containing files
			FileUtils.delete(link);

			// create and add a file in the new directory to the index
			writeTrashFile(linkName + "/dir1", "file1", "c");
			git.add().addFilepattern(linkName + "/dir1/file1").call();

			// create but do not add a file in the new directory to the index
			writeTrashFile(linkName + "/dir2", "file2", "d");

			assertTrue("Link must be a directory now", link.isDirectory());
			assertFalse("Must not delete non empty directory", link.delete());

			// 2 extra files are created
			assertWorkDir(mkmap(fname, "a", linkName + "/dir1/file1", "c",
					linkName + "/dir2/file2", "d"));

			try {
				git.checkout().setName("master").call();
				fail("did not throw exception");
			} catch (Exception e) {
				// 2 extra files are still there
				assertWorkDir(mkmap(fname, "a", linkName + "/dir1/file1", "c",
						linkName + "/dir2/file2", "d"));
			}
			recorder.assertNoEvent();
		} finally {
			if (handle != null) {
				handle.remove();
			}
		}
	}

	@Test
	public void testFileModeChangeWithNoContentChangeUpdate() throws Exception {
		if (!FS.DETECTED.supportsExecute())
			return;

		ChangeRecorder recorder = new ChangeRecorder();
		ListenerHandle handle = null;
		try (Git git = new Git(db)) {
			handle = db.getListenerList()
					.addWorkingTreeModifiedListener(recorder);
			// Add non-executable file
			File file = writeTrashFile("file.txt", "a");
			git.add().addFilepattern("file.txt").call();
			git.commit().setMessage("commit1").call();
			assertFalse(db.getFS().canExecute(file));

			// Create branch
			git.branchCreate().setName("b1").call();

			// Make file executable
			db.getFS().setExecute(file, true);
			git.add().addFilepattern("file.txt").call();
			git.commit().setMessage("commit2").call();
			recorder.assertNoEvent();

			// Verify executable and working directory is clean
			Status status = git.status().call();
			assertTrue(status.getModified().isEmpty());
			assertTrue(status.getChanged().isEmpty());
			assertTrue(db.getFS().canExecute(file));

			// Switch branches
			git.checkout().setName("b1").call();

			// Verify not executable and working directory is clean
			status = git.status().call();
			assertTrue(status.getModified().isEmpty());
			assertTrue(status.getChanged().isEmpty());
			assertFalse(db.getFS().canExecute(file));
			recorder.assertEvent(new String[] { "file.txt" },
					ChangeRecorder.EMPTY);
		} finally {
			if (handle != null) {
				handle.remove();
			}
		}
	}

	@Test
	public void testFileModeChangeAndContentChangeConflict() throws Exception {
		if (!FS.DETECTED.supportsExecute())
			return;

		ChangeRecorder recorder = new ChangeRecorder();
		ListenerHandle handle = null;
		try (Git git = new Git(db)) {
			handle = db.getListenerList()
					.addWorkingTreeModifiedListener(recorder);
			// Add non-executable file
			File file = writeTrashFile("file.txt", "a");
			git.add().addFilepattern("file.txt").call();
			git.commit().setMessage("commit1").call();
			assertFalse(db.getFS().canExecute(file));

			// Create branch
			git.branchCreate().setName("b1").call();

			// Make file executable
			db.getFS().setExecute(file, true);
			git.add().addFilepattern("file.txt").call();
			git.commit().setMessage("commit2").call();

			// Verify executable and working directory is clean
			Status status = git.status().call();
			assertTrue(status.getModified().isEmpty());
			assertTrue(status.getChanged().isEmpty());
			assertTrue(db.getFS().canExecute(file));

			writeTrashFile("file.txt", "b");

			// Switch branches
			CheckoutCommand checkout = git.checkout().setName("b1");
			try {
				checkout.call();
				fail("Checkout exception not thrown");
			} catch (org.eclipse.jgit.api.errors.CheckoutConflictException e) {
				CheckoutResult result = checkout.getResult();
				assertNotNull(result);
				assertNotNull(result.getConflictList());
				assertEquals(1, result.getConflictList().size());
				assertTrue(result.getConflictList().contains("file.txt"));
			}
			recorder.assertNoEvent();
		} finally {
			if (handle != null) {
				handle.remove();
			}
		}
	}

	@Test
	public void testDirtyFileModeEqualHeadMerge()
			throws Exception {
		if (!FS.DETECTED.supportsExecute())
			return;

		ChangeRecorder recorder = new ChangeRecorder();
		ListenerHandle handle = null;
		try (Git git = new Git(db)) {
			handle = db.getListenerList()
					.addWorkingTreeModifiedListener(recorder);
			// Add non-executable file
			File file = writeTrashFile("file.txt", "a");
			git.add().addFilepattern("file.txt").call();
			git.commit().setMessage("commit1").call();
			assertFalse(db.getFS().canExecute(file));

			// Create branch
			git.branchCreate().setName("b1").call();

			// Create second commit and don't touch file
			writeTrashFile("file2.txt", "");
			git.add().addFilepattern("file2.txt").call();
			git.commit().setMessage("commit2").call();

			// stage a mode change
			writeTrashFile("file.txt", "a");
			db.getFS().setExecute(file, true);
			git.add().addFilepattern("file.txt").call();

			// dirty the file
			writeTrashFile("file.txt", "b");

			assertEquals(
					"[file.txt, mode:100755, content:a][file2.txt, mode:100644, content:]",
					indexState(CONTENT));
			assertWorkDir(mkmap("file.txt", "b", "file2.txt", ""));
			recorder.assertNoEvent();

			// Switch branches and check that the dirty file survived in
			// worktree and index
			git.checkout().setName("b1").call();
			assertEquals("[file.txt, mode:100755, content:a]",
					indexState(CONTENT));
			assertWorkDir(mkmap("file.txt", "b"));
			recorder.assertEvent(ChangeRecorder.EMPTY,
					new String[] { "file2.txt" });
		} finally {
			if (handle != null) {
				handle.remove();
			}
		}
	}

	@Test
	public void testDirtyFileModeEqualIndexMerge()
			throws Exception {
		if (!FS.DETECTED.supportsExecute())
			return;

		ChangeRecorder recorder = new ChangeRecorder();
		ListenerHandle handle = null;
		try (Git git = new Git(db)) {
			handle = db.getListenerList()
					.addWorkingTreeModifiedListener(recorder);
			// Add non-executable file
			File file = writeTrashFile("file.txt", "a");
			git.add().addFilepattern("file.txt").call();
			git.commit().setMessage("commit1").call();
			assertFalse(db.getFS().canExecute(file));

			// Create branch
			git.branchCreate().setName("b1").call();

			// Create second commit with executable file
			file = writeTrashFile("file.txt", "b");
			db.getFS().setExecute(file, true);
			git.add().addFilepattern("file.txt").call();
			git.commit().setMessage("commit2").call();

			// stage the same content as in the branch we want to switch to
			writeTrashFile("file.txt", "a");
			db.getFS().setExecute(file, false);
			git.add().addFilepattern("file.txt").call();

			// dirty the file
			writeTrashFile("file.txt", "c");
			db.getFS().setExecute(file, true);

			assertEquals("[file.txt, mode:100644, content:a]",
					indexState(CONTENT));
			assertWorkDir(mkmap("file.txt", "c"));
			recorder.assertNoEvent();

			// Switch branches and check that the dirty file survived in
			// worktree
			// and index
			git.checkout().setName("b1").call();
			assertEquals("[file.txt, mode:100644, content:a]",
					indexState(CONTENT));
			assertWorkDir(mkmap("file.txt", "c"));
			recorder.assertNoEvent();
		} finally {
			if (handle != null) {
				handle.remove();
			}
		}
	}

	@Test
	public void testFileModeChangeAndContentChangeNoConflict() throws Exception {
		if (!FS.DETECTED.supportsExecute())
			return;

		ChangeRecorder recorder = new ChangeRecorder();
		ListenerHandle handle = null;
		try (Git git = new Git(db)) {
			handle = db.getListenerList()
					.addWorkingTreeModifiedListener(recorder);
			// Add first file
			File file1 = writeTrashFile("file1.txt", "a");
			git.add().addFilepattern("file1.txt").call();
			git.commit().setMessage("commit1").call();
			assertFalse(db.getFS().canExecute(file1));

			// Add second file
			File file2 = writeTrashFile("file2.txt", "b");
			git.add().addFilepattern("file2.txt").call();
			git.commit().setMessage("commit2").call();
			assertFalse(db.getFS().canExecute(file2));
			recorder.assertNoEvent();

			// Create branch from first commit
			assertNotNull(git.checkout().setCreateBranch(true).setName("b1")
					.setStartPoint(Constants.HEAD + "~1").call());
			recorder.assertEvent(ChangeRecorder.EMPTY,
					new String[] { "file2.txt" });

			// Change content and file mode in working directory and index
			file1 = writeTrashFile("file1.txt", "c");
			db.getFS().setExecute(file1, true);
			git.add().addFilepattern("file1.txt").call();

			// Switch back to 'master'
			assertNotNull(git.checkout().setName(Constants.MASTER).call());
			recorder.assertEvent(new String[] { "file2.txt" },
					ChangeRecorder.EMPTY);
		} finally {
			if (handle != null) {
				handle.remove();
			}
		}
	}

	@Test(expected = CheckoutConflictException.class)
	public void testFolderFileConflict() throws Exception {
		RevCommit headCommit = commitFile("f/a", "initial content", "master");
		RevCommit checkoutCommit = commitFile("f/a", "side content", "side");
		FileUtils.delete(new File(db.getWorkTree(), "f"), FileUtils.RECURSIVE);
		writeTrashFile("f", "file instead of folder");
		new DirCacheCheckout(db, headCommit.getTree(), db.lockDirCache(),
				checkoutCommit.getTree()).checkout();
	}

	@Test
	public void testMultipleContentConflicts() throws Exception {
		commitFile("a", "initial content", "master");
		RevCommit headCommit = commitFile("b", "initial content", "master");
		commitFile("a", "side content", "side");
		RevCommit checkoutCommit = commitFile("b", "side content", "side");
		writeTrashFile("a", "changed content");
		writeTrashFile("b", "changed content");

		try {
			new DirCacheCheckout(db, headCommit.getTree(), db.lockDirCache(),
					checkoutCommit.getTree()).checkout();
			fail();
		} catch (CheckoutConflictException expected) {
			assertEquals(2, expected.getConflictingFiles().length);
			assertTrue(Arrays.asList(expected.getConflictingFiles())
					.contains("a"));
			assertTrue(Arrays.asList(expected.getConflictingFiles())
					.contains("b"));
			assertEquals("changed content", read("a"));
			assertEquals("changed content", read("b"));
		}
	}

	@Test
	public void testFolderFileAndContentConflicts() throws Exception {
		RevCommit headCommit = commitFile("f/a", "initial content", "master");
		commitFile("b", "side content", "side");
		RevCommit checkoutCommit = commitFile("f/a", "side content", "side");
		FileUtils.delete(new File(db.getWorkTree(), "f"), FileUtils.RECURSIVE);
		writeTrashFile("f", "file instead of a folder");
		writeTrashFile("b", "changed content");

		try {
			new DirCacheCheckout(db, headCommit.getTree(), db.lockDirCache(),
					checkoutCommit.getTree()).checkout();
			fail();
		} catch (CheckoutConflictException expected) {
			assertEquals(2, expected.getConflictingFiles().length);
			assertTrue(Arrays.asList(expected.getConflictingFiles())
					.contains("b"));
			assertTrue(Arrays.asList(expected.getConflictingFiles())
					.contains("f"));
			assertEquals("file instead of a folder", read("f"));
			assertEquals("changed content", read("b"));
		}
	}

	@Test
	public void testLongFilename() throws Exception {
		char[] bytes = new char[253];
		Arrays.fill(bytes, 'f');
		String longFileName = new String(bytes);
		// 1
		doit(mkmap(longFileName, "a"), mkmap(longFileName, "b"),
				mkmap(longFileName, "a"));
		writeTrashFile(longFileName, "a");
		checkout();
		assertNoConflicts();
		assertUpdated(longFileName);
	}

	@Test
	public void testIgnoredDirectory() throws Exception {
		writeTrashFile(".gitignore", "src/ignored");
		writeTrashFile("src/ignored/sub/foo.txt", "1");
		try (Git git = new Git(db)) {
			git.add().addFilepattern(".").call();
			RevCommit commit = git.commit().setMessage("adding .gitignore")
					.call();
			writeTrashFile("foo.txt", "2");
			writeTrashFile("zzz.txt", "3");
			git.add().addFilepattern("foo.txt").call();
			git.commit().setMessage("add file").call();
			assertEquals("Should not have entered ignored directory", 1,
					resetHardAndCount(commit));
		}
	}

	@Test
	public void testIgnoredDirectoryWithTrackedContent() throws Exception {
		writeTrashFile("src/ignored/sub/foo.txt", "1");
		try (Git git = new Git(db)) {
			git.add().addFilepattern(".").call();
			git.commit().setMessage("adding foo.txt").call();
			writeTrashFile(".gitignore", "src/ignored");
			writeTrashFile("src/ignored/sub/foo.txt", "2");
			writeTrashFile("src/ignored/other/bar.txt", "3");
			git.add().addFilepattern(".").call();
			RevCommit commit = git.commit().setMessage("adding .gitignore")
					.call();
			writeTrashFile("foo.txt", "2");
			writeTrashFile("zzz.txt", "3");
			git.add().addFilepattern("foo.txt").call();
			git.commit().setMessage("add file").call();
			File file = writeTrashFile("src/ignored/sub/foo.txt", "3");
			assertEquals("Should have entered ignored directory", 3,
					resetHardAndCount(commit));
			checkFile(file, "2");
		}
	}

	@Test
	public void testResetWithChangeInGitignore() throws Exception {
		writeTrashFile(".gitignore", "src/ignored");
		writeTrashFile("src/ignored/sub/foo.txt", "1");
		try (Git git = new Git(db)) {
			git.add().addFilepattern(".").call();
			RevCommit initial = git.commit().setMessage("initial").call();
			writeTrashFile("src/newignored/foo.txt", "2");
			writeTrashFile("src/.gitignore", "newignored");
			git.add().addFilepattern(".").call();
			RevCommit commit = git.commit().setMessage("newignored").call();
			assertEquals("Should not have entered src/newignored directory", 1,
					resetHardAndCount(initial));
			assertEquals("Should have entered src/newignored directory", 2,
					resetHardAndCount(commit));
			deleteTrashFile("src/.gitignore");
			git.rm().addFilepattern("src/.gitignore").call();
			RevCommit top = git.commit().setMessage("Unignore newignore")
					.call();
			assertEquals("Should have entered src/newignored directory", 2,
					resetHardAndCount(initial));
			assertEquals("Should have entered src/newignored directory", 2,
					resetHardAndCount(commit));
			assertEquals("Should not have entered src/newignored directory", 1,
					resetHardAndCount(top));

		}
	}

	@Test
	public void testCheckoutWithEmptyIndexDoesntOverwrite() throws Exception {
		try (Git git = new Git(db);
				TestRepository<Repository> db_t = new TestRepository<>(db)) {
			// prepare the commits
			BranchBuilder master = db_t.branch("master");
			RevCommit mergeCommit = master.commit()
					.add("p/x", "headContent")
					.message("m0").create();
			master.commit().add("p/x", "headContent").message("m1").create();
			git.checkout().setName("master").call();

			// empty index and write unsaved data in 'p'
			git.rm().addFilepattern("p").call();
			writeTrashFile("p", "important data");

			git.checkout().setName(mergeCommit.getName()).call();

			assertEquals("", indexState(CONTENT));
			assertEquals("important data", read("p"));
		}
	}

	private static class TestFileTreeIterator extends FileTreeIterator {

		// For assertions only
		private final int[] count;

		public TestFileTreeIterator(Repository repo, int[] count) {
			super(repo);
			this.count = count;
		}

		protected TestFileTreeIterator(final WorkingTreeIterator p,
				final File root, FS fs, FileModeStrategy fileModeStrategy,
				int[] count) {
			super(p, root, fs, fileModeStrategy);
			this.count = count;
		}

		@Override
		protected AbstractTreeIterator enterSubtree() {
			count[0] += 1;
			return new TestFileTreeIterator(this,
					((FileEntry) current()).getFile(), fs, fileModeStrategy,
					count);
		}
	}

	private int resetHardAndCount(RevCommit commit) throws Exception {
		int[] callCount = { 0 };
		DirCache cache = db.lockDirCache();
		FileTreeIterator workingTreeIterator = new TestFileTreeIterator(db,
				callCount);
		try {
			DirCacheCheckout checkout = new DirCacheCheckout(db, null, cache,
					commit.getTree().getId(), workingTreeIterator);
			checkout.setFailOnConflict(false);
			checkout.checkout();
		} finally {
			cache.unlock();
		}
		return callCount[0];
	}

	public void assertWorkDir(Map<String, String> i)
			throws CorruptObjectException,
			IOException {
		try (TreeWalk walk = new TreeWalk(db)) {
			walk.setRecursive(false);
			walk.addTree(new FileTreeIterator(db));
			String expectedValue;
			String path;
			int nrFiles = 0;
			FileTreeIterator ft;
			while (walk.next()) {
				ft = walk.getTree(0, FileTreeIterator.class);
				path = ft.getEntryPathString();
				expectedValue = i.get(path);
				File file = new File(db.getWorkTree(), path);
				assertTrue(file.exists());
				if (file.isFile()) {
					assertNotNull("found unexpected file for path " + path
							+ " in workdir", expectedValue);
					try (FileInputStream is = new FileInputStream(file)) {
						byte[] buffer = new byte[(int) file.length()];
						int offset = 0;
						int numRead = 0;
						while (offset < buffer.length
								&& (numRead = is.read(buffer, offset,
										buffer.length - offset)) >= 0) {
							offset += numRead;
						}
						assertArrayEquals(
								"unexpected content for path " + path
										+ " in workDir. ",
								buffer, i.get(path).getBytes(UTF_8));
					}
					nrFiles++;
				} else if (file.isDirectory()) {
					String[] files = file.list();
					if (files != null && files.length == 0) {
						assertEquals("found unexpected empty folder for path "
								+ path + " in workDir. ", "/", i.get(path));
						nrFiles++;
					}
				}
				if (walk.isSubtree()) {
					walk.enterSubtree();
				}
			}
			assertEquals("WorkDir has not the right size.", i.size(), nrFiles);
		}
	}
}
