/*
 * Copyright (C) 2022, Google Inc. and others
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Distribution License v. 1.0 which is available at
 * https://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

package org.eclipse.jgit.patch;

import static org.eclipse.jgit.lib.Constants.OBJ_BLOB;
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.assertNull;
import static org.junit.Assert.assertTrue;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;

import org.eclipse.jgit.annotations.Nullable;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.attributes.FilterCommand;
import org.eclipse.jgit.attributes.FilterCommandFactory;
import org.eclipse.jgit.attributes.FilterCommandRegistry;
import org.eclipse.jgit.junit.RepositoryTestCase;
import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.ConfigConstants;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectInserter;
import org.eclipse.jgit.patch.PatchApplier.Result;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevTree;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.treewalk.TreeWalk;
import org.eclipse.jgit.util.FS;
import org.eclipse.jgit.util.IO;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;

@RunWith(Suite.class)
@Suite.SuiteClasses({
 		PatchApplierTest.WithWorktree. class, //
		PatchApplierTest.InCore.class, //
})
public class PatchApplierTest {

	public abstract static class Base extends RepositoryTestCase {

		protected String name;

		/** data before patching. */
		protected byte[] preImage;
		/** expected data after patching. */
		protected byte[] postImage;

		protected String expectedText;
		protected RevTree baseTip;
		public boolean inCore;

		Base(boolean inCore) {
			this.inCore = inCore;
		}

		void init(final String aName) throws Exception {
			init(aName, true, true);
		}

		protected void init(String aName, boolean preExists, boolean postExists)
				throws Exception {
			// Patch and pre/postimage are read from data
			// org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/
			this.name = aName;
			if (postExists) {
				expectedText = initPostImage(aName);
			}

			if (preExists) {
				initPreImage(aName);
			}
			try (Git git = new Git(db)) {
				RevCommit base = git.commit().setMessage("PreImage").call();
				baseTip = base.getTree();
			}
		}

		protected void initPreImage(String aName) throws Exception {
			preImage = IO
					.readWholeStream(getTestResource(aName + "_PreImage"), 0)
					.array();
			addFile(aName, preImage);
		}

		protected void addFile(String aName, byte[] b) throws Exception {
			File f = new File(db.getWorkTree(), aName);
			Files.write(f.toPath(), b);
			try (Git git = new Git(db)) {
				git.add().addFilepattern(aName).call();
			}
		}

		protected String initPostImage(String aName) throws Exception {
			postImage = IO
					.readWholeStream(getTestResource(aName + "_PostImage"), 0)
					.array();
			return new String(postImage, StandardCharsets.UTF_8);
		}

		protected Result applyPatch() throws IOException {
			try (InputStream patchStream = getTestResource(name + ".patch")) {
				Patch patch = new Patch();
				patch.parse(patchStream);
				if (inCore) {
					try (ObjectInserter oi = db.newObjectInserter()) {
						return new PatchApplier(db, baseTip, oi).applyPatch(patch);
					}
				}
				return new PatchApplier(db).applyPatch(patch);
			}
		}

		protected static InputStream getTestResource(String patchFile) {
			return PatchApplierTest.class.getClassLoader()
					.getResourceAsStream("org/eclipse/jgit/diff/" + patchFile);
		}

		void verifyChange(Result result, String aName) throws Exception {
			verifyChange(result, aName, true);
		}

		protected void verifyContent(Result result, String path, boolean exists)
				throws Exception {
			verifyContent(result, path, exists ? expectedText : null);
		}

		protected void verifyContent(Result result, String path,
				@Nullable String expectedContent) throws Exception {
			if (inCore) {
				byte[] output = readBlob(result.getTreeId(), path);
				if (expectedContent == null)
					assertNull(output);
				else {
					assertNotNull(output);
					assertEquals(expectedContent,
							new String(output, StandardCharsets.UTF_8));
				}
			} else {
				File f = new File(db.getWorkTree(), path);
				if (expectedContent == null)
					assertFalse(f.exists());
				else
					checkFile(f, expectedContent);
			}
		}

		void verifyChange(Result result, String aName, boolean exists)
				throws Exception {
			assertEquals(0, result.getErrors().size());
			assertEquals(1, result.getPaths().size());
			verifyContent(result, aName, exists);
		}

		protected byte[] readBlob(ObjectId treeish, String path)
				throws Exception {
			try (TestRepository<?> tr = new TestRepository<>(db);
					RevWalk rw = tr.getRevWalk()) {
				db.incrementOpen();
				RevTree tree = rw.parseTree(treeish);
				try (TreeWalk tw = TreeWalk.forPath(db, path, tree)) {
					if (tw == null) {
						return null;
					}
					return tw.getObjectReader()
							.open(tw.getObjectId(0), OBJ_BLOB).getBytes();
				}
			}
		}

		protected void checkBinary(Result result, int numberOfFiles)
				throws Exception {
			assertEquals(0, result.getErrors().size());
			assertEquals(numberOfFiles, result.getPaths().size());
			if (inCore) {
				assertArrayEquals(postImage,
						readBlob(result.getTreeId(), result.getPaths().get(0)));
			} else {
				File f = new File(db.getWorkTree(), name);
				assertArrayEquals(postImage, Files.readAllBytes(f.toPath()));
			}
		}

		/* tests */

		@Test
		public void testBinaryDelta() throws Exception {
			init("delta");
			checkBinary(applyPatch(), 1);
		}

		@Test
		public void testBinaryLiteral() throws Exception {
			init("literal");
			checkBinary(applyPatch(), 1);
		}

		@Test
		public void testBinaryLiteralAdd() throws Exception {
			init("literal_add", false, true);
			checkBinary(applyPatch(), 1);
		}

		@Test
		public void testModifyM2() throws Exception {
			init("M2", true, true);

			Result result = applyPatch();

			if (!inCore && FS.DETECTED.supportsExecute()) {
				assertEquals(1, result.getPaths().size());
				File f = new File(db.getWorkTree(), result.getPaths().get(0));
				assertTrue(FS.DETECTED.canExecute(f));
			}

			verifyChange(result, "M2");
		}

		@Test
		public void testModifyM3() throws Exception {
			init("M3", true, true);

			Result result = applyPatch();

			verifyChange(result, "M3");
			if (!inCore && FS.DETECTED.supportsExecute()) {
				File f = new File(db.getWorkTree(), result.getPaths().get(0));
				assertFalse(FS.DETECTED.canExecute(f));
			}
		}

		@Test
		public void testModifyX() throws Exception {
			init("X");

			Result result = applyPatch();
			verifyChange(result, "X");
		}

		@Test
		public void testModifyY() throws Exception {
			init("Y");

			Result result = applyPatch();

			verifyChange(result, "Y");
		}

		@Test
		public void testModifyZ() throws Exception {
			init("Z");

			Result result = applyPatch();
			verifyChange(result, "Z");
		}

		@Test
		public void testNonASCII() throws Exception {
			init("NonASCII");

			Result result = applyPatch();
			verifyChange(result, "NonASCII");
		}

		@Test
		public void testNonASCII2() throws Exception {
			init("NonASCII2");

			Result result = applyPatch();
			verifyChange(result, "NonASCII2");
		}

		@Test
		public void testNonASCIIAdd() throws Exception {
			init("NonASCIIAdd");

			Result result = applyPatch();
			verifyChange(result, "NonASCIIAdd");
		}

		@Test
		public void testNonASCIIAdd2() throws Exception {
			init("NonASCIIAdd2", false, true);

			Result result = applyPatch();
			verifyChange(result, "NonASCIIAdd2");
		}

		@Test
		public void testNonASCIIDel() throws Exception {
			init("NonASCIIDel", true, false);

			Result result = applyPatch();
			verifyChange(result, "NonASCIIDel", false);
			assertEquals("NonASCIIDel", result.getPaths().get(0));
		}

		@Test
		public void testRenameNoHunks() throws Exception {
			init("RenameNoHunks", true, true);

			Result result = applyPatch();

			assertEquals(2, result.getPaths().size());
			assertTrue(result.getPaths().contains("RenameNoHunks"));
			assertTrue(result.getPaths().contains("nested/subdir/Renamed"));

			verifyContent(result, "nested/subdir/Renamed", true);
		}

		@Test
		public void testRenameWithHunks() throws Exception {
			init("RenameWithHunks", true, true);

			Result result = applyPatch();
			assertEquals(2, result.getPaths().size());
			assertTrue(result.getPaths().contains("RenameWithHunks"));
			assertTrue(result.getPaths().contains("nested/subdir/Renamed"));

			verifyContent(result, "nested/subdir/Renamed", true);
		}

		@Test
		public void testCopyWithHunks() throws Exception {
			init("CopyWithHunks", true, true);

			Result result = applyPatch();
			verifyChange(result, "CopyResult", true);
		}

		@Test
		public void testShiftUp() throws Exception {
			init("ShiftUp");

			Result result = applyPatch();
			verifyChange(result, "ShiftUp");
		}

		@Test
		public void testShiftUp2() throws Exception {
			init("ShiftUp2");

			Result result = applyPatch();
			verifyChange(result, "ShiftUp2");
		}

		@Test
		public void testShiftDown() throws Exception {
			init("ShiftDown");

			Result result = applyPatch();
			verifyChange(result, "ShiftDown");
		}

		@Test
		public void testShiftDown2() throws Exception {
			init("ShiftDown2");

			Result result = applyPatch();
			verifyChange(result, "ShiftDown2");
		}

		@Test
		public void testAddAlreadyExistingFile() throws Exception {
			addFile("M1", "existing content".getBytes(StandardCharsets.UTF_8));
			init("M1", false, false);

			Result result = applyPatch();

			assertEquals(1, result.getErrors().size());
			assertEquals(0, result.getPaths().size());
		}

		@Test
		public void testDeleteNonexistentFile() throws Exception {
			init("NonASCIIDel", false, false);

			Result result = applyPatch();

			assertEquals(1, result.getErrors().size());
			assertEquals(0, result.getPaths().size());
		}

		@Test
		public void testModifyNonexistentFile() throws Exception {
			init("ShiftDown", false, true);

			Result result = applyPatch();

			assertEquals(1, result.getErrors().size());
			assertEquals(0, result.getPaths().size());
		}

		@Test
		public void testRenameNonexistentFile() throws Exception {
			init("RenameNoHunks", false, true);

			Result result = applyPatch();

			assertEquals(1, result.getErrors().size());
			assertEquals(0, result.getPaths().size());
		}

		@Test
		public void testCopyNonexistentFile() throws Exception {
			init("CopyWithHunks", false, true);

			Result result = applyPatch();

			assertEquals(1, result.getErrors().size());
			assertEquals(0, result.getPaths().size());
		}

		@Test
		public void testCopyOnTopAlreadyExistingFile() throws Exception {
			addFile("CopyResult", "existing content".getBytes(StandardCharsets.UTF_8));
			init("CopyWithHunks", true, false);

			Result result = applyPatch();

			assertEquals(1, result.getErrors().size());
			assertEquals(0, result.getPaths().size());
		}

		@Test
		public void testDoesNotAffectUnrelatedFiles() throws Exception {
			initPreImage("Unaffected");
			String expectedUnaffectedText = initPostImage("Unaffected");
			init("X");

			Result result = applyPatch();
			verifyChange(result, "X");
			verifyContent(result, "Unaffected", expectedUnaffectedText);
		}

		@Test
		public void testConflictFails() throws Exception {
			init("conflict");

			Result result = applyPatch();
			assertEquals(1, result.getErrors().size());
		}
	}

	public static class InCore extends Base {

		public InCore() {
			super(true);
		}

		@Test
		public void testNoNewlineAtEnd() throws Exception {
			init("x_d");

			Result result = applyPatch();
			verifyChange(result, "x_d");
		}

		@Test
		public void testNoNewlineAtEndInHunk() throws Exception {
			init("x_e");

			Result result = applyPatch();
			verifyChange(result, "x_e");
		}

		@Test
		public void testAddNewlineAtEnd() throws Exception {
			init("x_add_nl");

			Result result = applyPatch();
			verifyChange(result, "x_add_nl");
		}

		@Test
		public void testRemoveNewlineAtEnd() throws Exception {
			init("x_last_rm_nl");

			Result result = applyPatch();
			verifyChange(result, "x_last_rm_nl");
		}

		@Test
		public void testVeryLongFile() throws Exception {
			init("very_long_file");

			Result result = applyPatch();
			verifyChange(result, "very_long_file");
		}
	}

	public static class WithWorktree extends Base {
		public WithWorktree() {
			super(false);
		}

		@Test
		public void testModifyNL1() throws Exception {
			init("NL1");

			Result result = applyPatch();
			verifyChange(result, "NL1");
		}

		@Test
		public void testCrLf() throws Exception {
			try {
				db.getConfig().setBoolean(ConfigConstants.CONFIG_CORE_SECTION,
						null, ConfigConstants.CONFIG_KEY_AUTOCRLF, true);
				init("crlf", true, true);

				Result result = applyPatch();

				verifyChange(result, "crlf");
			} finally {
				db.getConfig().unset(ConfigConstants.CONFIG_CORE_SECTION, null,
						ConfigConstants.CONFIG_KEY_AUTOCRLF);
			}
		}

		@Test
		public void testCrLfOff() throws Exception {
			try {
				db.getConfig().setBoolean(ConfigConstants.CONFIG_CORE_SECTION,
						null, ConfigConstants.CONFIG_KEY_AUTOCRLF, false);
				init("crlf", true, true);

				Result result = applyPatch();

				verifyChange(result, "crlf");
			} finally {
				db.getConfig().unset(ConfigConstants.CONFIG_CORE_SECTION, null,
						ConfigConstants.CONFIG_KEY_AUTOCRLF);
			}
		}

		@Test
		public void testCrLfEmptyCommitted() throws Exception {
			try {
				db.getConfig().setBoolean(ConfigConstants.CONFIG_CORE_SECTION,
						null, ConfigConstants.CONFIG_KEY_AUTOCRLF, true);
				init("crlf3", true, true);

				Result result = applyPatch();

				verifyChange(result, "crlf3");
			} finally {
				db.getConfig().unset(ConfigConstants.CONFIG_CORE_SECTION, null,
						ConfigConstants.CONFIG_KEY_AUTOCRLF);
			}
		}

		@Test
		public void testCrLfNewFile() throws Exception {
			try {
				db.getConfig().setBoolean(ConfigConstants.CONFIG_CORE_SECTION,
						null, ConfigConstants.CONFIG_KEY_AUTOCRLF, true);
				init("crlf4", false, true);

				Result result = applyPatch();

				verifyChange(result, "crlf4");
			} finally {
				db.getConfig().unset(ConfigConstants.CONFIG_CORE_SECTION, null,
						ConfigConstants.CONFIG_KEY_AUTOCRLF);
			}
		}

		@Test
		public void testPatchWithCrLf() throws Exception {
			try {
				db.getConfig().setBoolean(ConfigConstants.CONFIG_CORE_SECTION,
						null, ConfigConstants.CONFIG_KEY_AUTOCRLF, false);
				init("crlf2", true, true);

				Result result = applyPatch();

				verifyChange(result, "crlf2");
			} finally {
				db.getConfig().unset(ConfigConstants.CONFIG_CORE_SECTION, null,
						ConfigConstants.CONFIG_KEY_AUTOCRLF);
			}
		}

		@Test
		public void testPatchWithCrLf2() throws Exception {
			String aName = "crlf2";
			try (Git git = new Git(db)) {
				db.getConfig().setBoolean(ConfigConstants.CONFIG_CORE_SECTION,
						null, ConfigConstants.CONFIG_KEY_AUTOCRLF, false);
				init(aName, true, true);
				db.getConfig().setBoolean(ConfigConstants.CONFIG_CORE_SECTION,
						null, ConfigConstants.CONFIG_KEY_AUTOCRLF, true);

				Result result = applyPatch();

				verifyChange(result, aName);
			} finally {
				db.getConfig().unset(ConfigConstants.CONFIG_CORE_SECTION, null,
						ConfigConstants.CONFIG_KEY_AUTOCRLF);
			}
		}

		@Test
		public void testNoNewlineAtEndAutoCRLF_true() throws Exception {
			try {
				db.getConfig().setBoolean(ConfigConstants.CONFIG_CORE_SECTION,
						null, ConfigConstants.CONFIG_KEY_AUTOCRLF, true);

				init("x_d_crlf", true, true);

				Result result = applyPatch();
				verifyChange(result, "x_d_crlf");
			} finally {
				db.getConfig().unset(ConfigConstants.CONFIG_CORE_SECTION, null,
						ConfigConstants.CONFIG_KEY_AUTOCRLF);
			}
		}

		@Test
		public void testNoNewlineAtEndAutoCRLF_false() throws Exception {
			try {
				db.getConfig().setBoolean(ConfigConstants.CONFIG_CORE_SECTION,
						null, ConfigConstants.CONFIG_KEY_AUTOCRLF, false);

				init("x_d", true, true);

				Result result = applyPatch();
				verifyChange(result, "x_d");
			} finally {
				db.getConfig().unset(ConfigConstants.CONFIG_CORE_SECTION, null,
						ConfigConstants.CONFIG_KEY_AUTOCRLF);
			}
		}

		@Test
		public void testNoNewlineAtEndAutoCRLF_input() throws Exception {
			try {
				db.getConfig().setString(ConfigConstants.CONFIG_CORE_SECTION,
						null, ConfigConstants.CONFIG_KEY_AUTOCRLF, "input");

				init("x_d", true, true);

				Result result = applyPatch();
				verifyChange(result, "x_d");
			} finally {
				db.getConfig().unset(ConfigConstants.CONFIG_CORE_SECTION, null,
						ConfigConstants.CONFIG_KEY_AUTOCRLF);
			}
		}

		@Test
		public void testNoNewlineAtEndInHunkAutoCRLF_true() throws Exception {
			try {
				db.getConfig().setBoolean(ConfigConstants.CONFIG_CORE_SECTION,
						null, ConfigConstants.CONFIG_KEY_AUTOCRLF, true);

				init("x_e_crlf", true, true);

				Result result = applyPatch();
				verifyChange(result, "x_e_crlf");
			} finally {
				db.getConfig().unset(ConfigConstants.CONFIG_CORE_SECTION, null,
						ConfigConstants.CONFIG_KEY_AUTOCRLF);
			}
		}

		@Test
		public void testNoNewlineAtEndInHunkAutoCRLF_false() throws Exception {
			try {
				db.getConfig().setBoolean(ConfigConstants.CONFIG_CORE_SECTION,
						null, ConfigConstants.CONFIG_KEY_AUTOCRLF, false);

				init("x_e", true, true);

				Result result = applyPatch();
				verifyChange(result, "x_e");
			} finally {
				db.getConfig().unset(ConfigConstants.CONFIG_CORE_SECTION, null,
						ConfigConstants.CONFIG_KEY_AUTOCRLF);
			}
		}

		@Test
		public void testNoNewlineAtEndInHunkAutoCRLF_input() throws Exception {
			try {
				db.getConfig().setString(ConfigConstants.CONFIG_CORE_SECTION,
						null, ConfigConstants.CONFIG_KEY_AUTOCRLF, "input");

				init("x_e", true, true);

				Result result = applyPatch();
				verifyChange(result, "x_e");
			} finally {
				db.getConfig().unset(ConfigConstants.CONFIG_CORE_SECTION, null,
						ConfigConstants.CONFIG_KEY_AUTOCRLF);
			}
		}

		@Test
		public void testAddNewlineAtEndAutoCRLF_true() throws Exception {
			try {
				db.getConfig().setBoolean(ConfigConstants.CONFIG_CORE_SECTION,
						null, ConfigConstants.CONFIG_KEY_AUTOCRLF, true);

				init("x_add_nl_crlf", true, true);

				Result result = applyPatch();
				verifyChange(result, "x_add_nl_crlf");
			} finally {
				db.getConfig().unset(ConfigConstants.CONFIG_CORE_SECTION, null,
						ConfigConstants.CONFIG_KEY_AUTOCRLF);
			}
		}

		@Test
		public void testAddNewlineAtEndAutoCRLF_false() throws Exception {
			try {
				db.getConfig().setBoolean(ConfigConstants.CONFIG_CORE_SECTION,
						null, ConfigConstants.CONFIG_KEY_AUTOCRLF, false);

				init("x_add_nl", true, true);

				Result result = applyPatch();
				verifyChange(result, "x_add_nl");
			} finally {
				db.getConfig().unset(ConfigConstants.CONFIG_CORE_SECTION, null,
						ConfigConstants.CONFIG_KEY_AUTOCRLF);
			}
		}

		@Test
		public void testAddNewlineAtEndAutoCRLF_input() throws Exception {
			try {
				db.getConfig().setString(ConfigConstants.CONFIG_CORE_SECTION,
						null, ConfigConstants.CONFIG_KEY_AUTOCRLF, "input");

				init("x_add_nl", true, true);

				Result result = applyPatch();
				verifyChange(result, "x_add_nl");
			} finally {
				db.getConfig().unset(ConfigConstants.CONFIG_CORE_SECTION, null,
						ConfigConstants.CONFIG_KEY_AUTOCRLF);
			}
		}

		@Test
		public void testRemoveNewlineAtEndAutoCRLF_true() throws Exception {
			try {
				db.getConfig().setBoolean(ConfigConstants.CONFIG_CORE_SECTION,
						null, ConfigConstants.CONFIG_KEY_AUTOCRLF, true);

				init("x_last_rm_nl_crlf", true, true);

				Result result = applyPatch();
				verifyChange(result, "x_last_rm_nl_crlf");
			} finally {
				db.getConfig().unset(ConfigConstants.CONFIG_CORE_SECTION, null,
						ConfigConstants.CONFIG_KEY_AUTOCRLF);
			}
		}

		@Test
		public void testRemoveNewlineAtEndAutoCRLF_false() throws Exception {
			try {
				db.getConfig().setBoolean(ConfigConstants.CONFIG_CORE_SECTION,
						null, ConfigConstants.CONFIG_KEY_AUTOCRLF, false);

				init("x_last_rm_nl", true, true);

				Result result = applyPatch();
				verifyChange(result, "x_last_rm_nl");
			} finally {
				db.getConfig().unset(ConfigConstants.CONFIG_CORE_SECTION, null,
						ConfigConstants.CONFIG_KEY_AUTOCRLF);
			}
		}

		@Test
		public void testRemoveNewlineAtEndAutoCRLF_input() throws Exception {
			try {
				db.getConfig().setString(ConfigConstants.CONFIG_CORE_SECTION,
						null, ConfigConstants.CONFIG_KEY_AUTOCRLF, "input");

				init("x_last_rm_nl", true, true);

				Result result = applyPatch();
				verifyChange(result, "x_last_rm_nl");
			} finally {
				db.getConfig().unset(ConfigConstants.CONFIG_CORE_SECTION, null,
						ConfigConstants.CONFIG_KEY_AUTOCRLF);
			}
		}

		@Test
		public void testEditNoNewline() throws Exception {
			init("z_e_no_nl", true, true);

			Result result = applyPatch();
			verifyChange(result, "z_e_no_nl");
		}

		@Test
		public void testEditAddNewline() throws Exception {
			init("z_e_add_nl", true, true);

			Result result = applyPatch();
			verifyChange(result, "z_e_add_nl");
		}

		@Test
		public void testEditRemoveNewline() throws Exception {
			init("z_e_rm_nl", true, true);

			Result result = applyPatch();
			verifyChange(result, "z_e_rm_nl");
		}

		// Clean/smudge filter for testFiltering. The smudgetest test resources
		// were created with C git using a clean filter sed -e "s/A/E/g" and the
		// smudge filter sed -e "s/E/A/g". To keep the test independent of the
		// presence of sed, implement this with a built-in filter.
		private static class ReplaceFilter extends FilterCommand {

			private final char toReplace;

			private final char replacement;

			ReplaceFilter(InputStream in, OutputStream out, char toReplace,
					char replacement) {
				super(in, out);
				this.toReplace = toReplace;
				this.replacement = replacement;
			}

			@Override
			public int run() throws IOException {
				int b = in.read();
				if (b < 0) {
					in.close();
					out.close();
					return -1;
				}
				if ((b & 0xFF) == toReplace) {
					b = replacement;
				}
				out.write(b);
				return 1;
			}
		}

		@Test
		public void testFiltering() throws Exception {
			// Set up filter
			FilterCommandFactory clean =
					(repo, in, out) -> new ReplaceFilter(in, out, 'A', 'E');
			FilterCommandFactory smudge =
					(repo, in, out) -> new ReplaceFilter(in, out, 'E', 'A');
			FilterCommandRegistry.register("jgit://builtin/a2e/clean", clean);
			FilterCommandRegistry.register("jgit://builtin/a2e/smudge", smudge);
			Config config = db.getConfig();
			try (Git git = new Git(db)) {
				config.setString(ConfigConstants.CONFIG_FILTER_SECTION, "a2e",
						"clean", "jgit://builtin/a2e/clean");
				config.setString(ConfigConstants.CONFIG_FILTER_SECTION, "a2e",
						"smudge", "jgit://builtin/a2e/smudge");
				write(new File(db.getWorkTree(), ".gitattributes"),
						"smudgetest filter=a2e");
				git.add().addFilepattern(".gitattributes").call();
				git.commit().setMessage("Attributes").call();
				init("smudgetest", true, true);

				Result result = applyPatch();

				verifyChange(result, name);
			} finally {
				config.unset(ConfigConstants.CONFIG_FILTER_SECTION, "a2e",
						"clean");
				config.unset(ConfigConstants.CONFIG_FILTER_SECTION, "a2e",
						"smudge");
				// Tear down filter
				FilterCommandRegistry.unregister("jgit://builtin/a2e/clean");
				FilterCommandRegistry.unregister("jgit://builtin/a2e/smudge");
			}
		}

		private void dotGitTest(String fileName) throws Exception {
			init(fileName, false, false);
			Result result = null;
			IOException ex = null;
			try {
				result = applyPatch();
			} catch (IOException e) {
				ex = e;
			}
			assertTrue(ex != null
					|| (result != null && !result.getErrors().isEmpty()));
			File b = new File(new File(trash, ".git"), "b");
			assertFalse(".git/b should not exist", b.exists());
		}

		@Test
		public void testDotGit() throws Exception {
			dotGitTest("dotgit");
		}

		@Test
		public void testDotGit2() throws Exception {
			dotGitTest("dotgit2");
		}
	}
}
